1 //
2 // ipv2_data.cc
3 //
4 // Copyright (C) 1996 Limit Point Systems, Inc.
5 //
6 // Author: Curtis Janssen <cljanss@limitpt.com>
7 // Maintainer: LPS
8 //
9 // This file is part of the SC Toolkit.
10 //
11 // The SC Toolkit is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU Library General Public License as published by
13 // the Free Software Foundation; either version 2, or (at your option)
14 // any later version.
15 //
16 // The SC Toolkit is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 // GNU Library General Public License for more details.
20 //
21 // You should have received a copy of the GNU Library General Public License
22 // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
23 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 //
25 // The U.S. Government is granted a limited license as per AL 91-7.
26 //
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <stdarg.h>
31 #include <string.h>
32 #include <util/keyval/ipv2.h>
33 
34 using namespace std;
35 using namespace sc;
36 
37 IPV2::Status
boolean(const char * keyword,int * boolean,int n,...)38 IPV2::boolean(const char *keyword,int *boolean,int n,...)
39 {
40   va_list args;
41   int i;
42   int *v;
43   Status r;
44 
45   if (n==0) {
46     return boolean_v(keyword,boolean,n,NULL);
47     }
48   else {
49     v = (int *) malloc(sizeof(int)*n);
50     if (!v) return Malloc;
51     va_start(args, n);
52     for (i=0; i<n; i++) {
53       v[i] = va_arg(args,int);
54       }
55     va_end(args);
56     r = boolean_v(keyword,boolean,n,v);
57     free(v);
58     return r;
59     }
60   }
61 
62 IPV2::Status
boolean_v(const char * keyword,int * boolean,int n,int * v)63 IPV2::boolean_v(const char* keyword,int* boolean,int n,int* v)
64 {
65   const char *val;
66   Status errcod;
67   char copy[10],*s;
68 
69   if ((errcod = value_v(keyword,&val,n,v)) !=0) return errcod;
70 
71   strncpy(copy,val,10);
72   copy[9] = '\0';
73 
74   /* Convert the string to uppercase. */
75   for (s=copy; *s!='\0'; s++) {
76     if (*s>='a' && *s <='z') *s = *s + 'A' - 'a';
77     }
78 
79   if (!strcmp(copy,"YES")) *boolean = 1;
80   else if (!strcmp(copy,"NO")) *boolean = 0;
81   else if (!strcmp(copy,"1")) *boolean = 1;
82   else if (!strcmp(copy,"0")) *boolean = 0;
83   else if (!strcmp(copy,"TRUE")) *boolean = 1;
84   else if (!strcmp(copy,"FALSE")) *boolean = 0;
85   else if (!strcmp(copy,"ON")) *boolean = 1;
86   else if (!strcmp(copy,"OFF")) *boolean = 0;
87   else return Type;
88 
89   return OK;
90   }
91 
92 /* n should always be zero in this version of libip. */
93 int
exist(const char * keyword,int n,...)94 IPV2::exist(const char *keyword,int n,...)
95 {
96   va_list args;
97   int i;
98   int *v;
99   int r;
100 
101   if (n==0) {
102     return exist_v(keyword,n,NULL);
103     }
104   else {
105     v = (int *) malloc(sizeof(int)*n);
106     if (!v) {
107       warn("IPV2::exist: problem malloc");
108       return 0;
109       }
110     va_start(args, n);
111     for (i=0; i<n; i++) {
112       v[i] = va_arg(args,int);
113       }
114     va_end(args);
115     r = exist_v(keyword,n,v);
116     free(v);
117     return r;
118     }
119   }
120 
121 /* n should always be zero in this version of libip. */
122 int
exist_v(const char * keyword,int n,int * v)123 IPV2::exist_v(const char* keyword,int n,int* v)
124 {
125   if (n!=0) {
126     *ip_out << "IPV2::exist_v: n must be zero n = " << n << endl;
127     abort();
128     }
129   if (ip_cwk_descend_tree(keyword)) return 1;
130 
131   return 0;
132   }
133 
134 IPV2::Status
data(const char * keyword,const char * conv,void * value,int n,...)135 IPV2::data(const char *keyword,const char *conv,void *value,int n,...)
136 {
137   va_list args;
138   int i;
139   int *v;
140   Status r;
141 
142   if (n==0) {
143     return data_v(keyword,conv,value,n,NULL);
144     }
145   else {
146     v = (int *) malloc(sizeof(int)*n);
147     if (!v) return Malloc;
148     va_start(args, n);
149     for (i=0; i<n; i++) {
150       v[i] = va_arg(args,int);
151       }
152     va_end(args);
153     r = data_v(keyword,conv,value,n,v);
154     free(v);
155     return r;
156     }
157   }
158 
159 IPV2::Status
data_v(const char * keyword,const char * conv,void * value,int n,int * v)160 IPV2::data_v(const char* keyword,const char* conv,void* value,int n,int*v)
161 {
162   const char *val;
163   Status errcod;
164 
165   if ((errcod = value_v(keyword,&val,n,v))!=0) return errcod;
166 
167   if (sscanf(val,conv,value) != 1) return Type;
168 
169   return OK;
170   }
171 
172 IPV2::Status
classname(const char * keyword,const char ** name,int n,...)173 IPV2::classname(const char *keyword,const char **name,int n,...)
174 {
175   va_list args;
176   int i;
177   int *v;
178   Status r;
179 
180   if (n==0) {
181     return classname_v(keyword,name,n,NULL);
182     }
183   else {
184     v = (int *) malloc(sizeof(int)*n);
185     if (!v) return Malloc;
186     va_start(args, n);
187     for (i=0; i<n; i++) {
188       v[i] = va_arg(args,int);
189       }
190     va_end(args);
191     r = classname_v(keyword,name,n,v);
192     free(v);
193     return r;
194     }
195   }
196 
197 IPV2::Status
classname_v(const char * keyword,const char ** name,int n,int * v)198 IPV2::classname_v(const char* keyword,const char** name,int n,int *v)
199 {
200   ip_keyword_tree_t *kt;
201   static char newkey[KEYWORD_LENGTH];
202   Status errcod;
203 
204   if ((errcod = construct_key_v(keyword,newkey,n,v))!=OK) return errcod;
205 
206   kt = ip_cwk_descend_tree(newkey);
207   if (!kt) {
208     ip_lastkeyword(keyword);
209     *name = 0;
210     return KeyNotFound;
211     }
212 
213   ip_lastkeywordtree(kt);
214   *name = kt->classname;
215 
216   return OK;
217   }
218 
219 IPV2::Status
truekeyword(const char * keyword,const char ** name,int n,...)220 IPV2::truekeyword(const char *keyword,const char **name,int n,...)
221 {
222   va_list args;
223   int i;
224   int *v;
225   Status r;
226 
227   if (n==0) {
228     return truekeyword_v(keyword,name,n,NULL);
229     }
230   else {
231     v = (int *) malloc(sizeof(int)*n);
232     if (!v) return Malloc;
233     va_start(args, n);
234     for (i=0; i<n; i++) {
235       v[i] = va_arg(args,int);
236       }
237     va_end(args);
238     r = truekeyword_v(keyword,name,n,v);
239     free(v);
240     return r;
241     }
242   }
243 
244 static char*
get_name(ip_keyword_tree_t * kt,char * currentname)245 get_name(ip_keyword_tree_t*kt,char*currentname)
246 {
247   if (!kt) return currentname;
248   char*newname;
249   if (currentname) {
250       newname = (char*)malloc(strlen(currentname)+strlen(kt->keyword)+2);
251       sprintf(newname,"%s:%s",kt->keyword,currentname);
252       free(currentname);
253     }
254   else newname = strcpy((char*)malloc(strlen(kt->keyword)+1),kt->keyword);
255   return get_name(kt->up,newname);
256 }
257 
258 char*
get_truename(ip_keyword_tree_t * kt)259 IPV2::get_truename(ip_keyword_tree_t*kt)
260 {
261   return get_name(kt,0);
262 }
263 
264 IPV2::Status
truekeyword_v(const char * keyword,const char ** name,int n,int * v)265 IPV2::truekeyword_v(const char* keyword,const char** name,int n,int *v)
266 {
267   ip_keyword_tree_t *kt;
268   static char newkey[KEYWORD_LENGTH];
269   Status errcod;
270 
271   if ((errcod = construct_key_v(keyword,newkey,n,v))!=OK) return errcod;
272 
273   kt = ip_cwk_descend_tree(newkey);
274   if (!kt) {
275     ip_lastkeyword(keyword);
276     *name = 0;
277     return KeyNotFound;
278     }
279 
280   ip_lastkeywordtree(kt);
281 
282   if (!kt->truename) {
283       kt->truename = get_truename(kt);
284     }
285   *name = kt->truename;
286 
287   return OK;
288   }
289 
290 IPV2::Status
string(const char * keyword,char ** value,int n,...)291 IPV2::string(const char *keyword,char **value,int n,...)
292 {
293   va_list args;
294   int i;
295   int *v;
296   Status r;
297 
298   if (n==0) {
299     return string_v(keyword,value,n,NULL);
300     }
301   else {
302     v = (int *) malloc(sizeof(int)*n);
303     if (!v) return Malloc;
304     va_start(args, n);
305     for (i=0; i<n; i++) {
306       v[i] = va_arg(args,int);
307       }
308     va_end(args);
309     r = string_v(keyword,value,n,v);
310     free(v);
311     return r;
312     }
313   }
314 
315 // if an error is encountered, *value is not modified
316 IPV2::Status
string_v(const char * keyword,char ** value,int n,int * v)317 IPV2::string_v(const char* keyword,char** value,int n,int *v)
318 {
319   const char *val;
320   Status errcod;
321 
322   if ((errcod = value_v(keyword,&val,n,v))!=0) return errcod;
323 
324   char *tmp = new char[strlen(val)+1];
325   if (! tmp) return Malloc;
326   strcpy(tmp,val);
327   *value = tmp;
328   return OK;
329   }
330 
331 IPV2::Status
value(const char * keyword,const char ** value,int n,...)332 IPV2::value(const char *keyword,const char **value,int n,...)
333 {
334   va_list args;
335   int i;
336   int *v;
337   Status r;
338 
339   if (n==0) {
340     return value_v(keyword,value,n,NULL);
341     }
342   else {
343     v = (int *) malloc(sizeof(int)*n);
344     if (!v) return Malloc;
345     va_start(args, n);
346     for (i=0; i<n; i++) {
347       v[i] = va_arg(args,int);
348       }
349     va_end(args);
350     r = value_v(keyword,value,n,v);
351     free(v);
352     return r;
353     }
354   }
355 
356 IPV2::Status
value_v(const char * keyword,const char ** value,int n,int * v)357 IPV2::value_v(const char* keyword,const char**value,int n,int*v)
358 {
359   Status errcod;
360   ip_keyword_tree_t *kt;
361   static char newkey[KEYWORD_LENGTH];
362 
363   if ((errcod = construct_key_v(keyword,newkey,n,v))!=OK) return errcod;
364 
365   /* Get the kt corresponding to the keyword using the cwk. */
366   kt = ip_cwk_descend_tree(newkey);
367 
368   if (!kt) {
369     ip_lastkeyword(keyword);
370     return KeyNotFound;
371     }
372 
373   ip_lastkeywordtree(kt);
374 
375   *value = kt->value;
376   if (*value == NULL) return HasNoValue;
377 
378   return OK;
379   }
380 
381 
382 IPV2::Status
construct_key_v(const char * keyword,char * newkey,int n,int * v)383 IPV2::construct_key_v(const char* keyword,char *newkey,int n,int*v)
384 {
385   int i;
386   char index[11];
387   int count;
388   Status errcod;
389 
390   /* Construct the new keyword. */
391   strcpy(newkey,keyword);
392   for (i=0; i<n; i++) {
393     if ((errcod = count_v(newkey,&count,0,NULL)) != OK) return errcod;
394     if (v[i]<0 || v[i]>=count) return OutOfBounds;
395     sprintf(index,":%d",v[i]);
396     strcat(newkey,index);
397     }
398 
399   return OK;
400   }
401