2 * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the University of California, Berkeley nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include <netinet/in.h>
33 #include <sys/queue.h>
35 #include <cmdline_parse_ipaddr.h>
36 #include <cmdline_parse.h>
38 #include "expression.h"
39 #include "conf_parser.h"
41 #include "conf_htable.h"
42 #include "parse_confnode.h"
44 struct cmdline_token_ops token_conf_node_ops = {
45 .parse = parse_conf_node,
46 .complete_get_nb = complete_get_nb_conf_node,
47 .complete_get_elt = complete_get_elt_conf_node,
48 .get_help = get_help_conf_node,
51 /* return 0 if string matches pattern (string must not contain '*')*/
52 static int strcmp_joker(const char *s, const char *pattern)
57 while (*s == *pattern && *pattern != '*') {
65 if (*(pattern + 1) == '\0')
68 if (strcmp_joker(s, pattern + 1) == 0)
76 find_in_children(struct confnode_list *l, struct confnode *n,
77 const char *pattern, int flags, int mask, int recurs)
81 TAILQ_FOREACH(c, &n->children, next) {
82 /* if it's a "if" node, parse children */
83 if (c->flags & CONFNODE_F_INVISIBLE)
84 find_in_children(l, c, pattern, flags, mask, recurs);
87 if ((c->flags & mask) == flags &&
88 !strcmp_joker(c->name, pattern))
89 TAILQ_INSERT_TAIL(l, c, user_next);
92 find_in_children(l, c, pattern, flags, mask, recurs);
98 count_children(struct confnode *n, int flags, int mask)
103 TAILQ_FOREACH(c, &n->children, next) {
104 /* if it's a "if" node, parse children */
105 if (c->flags & CONFNODE_F_INVISIBLE)
106 i += count_children(c, flags, mask);
107 else if ((c->flags & mask) == flags)
113 static struct confnode *
114 get_from_idx(struct confnode *n, unsigned int *cur, unsigned int idx,
117 struct confnode *c, *tmp;
119 TAILQ_FOREACH(c, &n->children, next) {
120 /* if it's a "if" node, parse children */
121 if (c->flags & CONFNODE_F_INVISIBLE) {
122 tmp = get_from_idx(c, cur, idx, flags, mask);
127 if ((c->flags & mask) != flags)
138 parse_conf_node(cmdline_parse_token_hdr_t *tk, const char *buf, void *res)
140 struct token_conf_node *tk2 = (struct token_conf_node *)tk;
141 struct token_conf_node_data *tkd = &tk2->conf_node_data;
143 struct confnode_list l;
144 unsigned int token_len = 0;
150 while(!cmdline_isendoftoken(buf[token_len]))
153 if (token_len > sizeof(token) - 1)
156 memcpy(token, buf, token_len);
157 token[token_len] = '\0';
162 if (token[0] == '/' && token[1] == '/') {
163 /* if contains joker */
164 if (strchr(token + 2, '*'))
165 find_in_children(&l, *tkd->root, token+2, tkd->flags,
168 n = conf_htable_lookup(token + 2);
169 if ((n->flags & tkd->mask) != tkd->flags)
171 TAILQ_INSERT_TAIL(&l, n, user_next);
176 find_in_children(&l, *tkd->cur, token, tkd->flags, tkd->mask, 0);
180 /* store the address of object in structure */
182 *(struct confnode **)res = TAILQ_FIRST(&l);
187 int complete_get_nb_conf_node(cmdline_parse_token_hdr_t *tk)
189 struct token_conf_node *tk2 = (struct token_conf_node *)tk;
190 struct token_conf_node_data *tkd = &tk2->conf_node_data;
192 return count_children(*tkd->cur, tkd->flags, tkd->mask);
195 int complete_get_elt_conf_node(cmdline_parse_token_hdr_t *tk, int idx,
196 char *dstbuf, unsigned int size)
198 struct token_conf_node *tk2 = (struct token_conf_node *)tk;
199 struct token_conf_node_data *tkd = &tk2->conf_node_data;
201 unsigned int i = 0, len;
203 n = get_from_idx(*tkd->cur, &i, idx, tkd->flags, tkd->mask);
207 len = strlen(n->name) + 1;
211 strcpy(dstbuf, n->name);
216 int get_help_conf_node(cmdline_parse_token_hdr_t *tk, char *dstbuf, unsigned int size)
218 snprintf(dstbuf, size, "conf-node");