Replace tabs in files with editor modeline "expandtab"
[metze/wireshark/wip.git] / extcap_parser.c
1 /* extcap_parser.c
2  *
3  * Routines for extcap external capture
4  * Copyright 2013, Mike Ryan <mikeryan@lacklustre.net>
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24
25 #include <config.h>
26
27 #include <stdio.h>
28 #include <glib.h>
29 #include <string.h>
30
31 #include "extcap_parser.h"
32
33 void extcap_printf_complex(extcap_complex *comp) {
34     gchar *ret = extcap_get_complex_as_string(comp);
35     printf("%s", ret);
36     g_free(ret);
37 }
38
39 gchar *extcap_get_complex_as_string(extcap_complex *comp) {
40     /* Pick an arbitrary size that should be big enough */
41     gchar *ret = g_new(gchar, 32);
42
43     if (comp == NULL) {
44         g_snprintf(ret, 32, "(null)");
45         return ret;
46     }
47
48     switch (comp->complex_type) {
49     case EXTCAP_ARG_INTEGER:
50         g_snprintf(ret, 32, "%d", comp->complex_value.int_value);
51         break;
52     case EXTCAP_ARG_UNSIGNED:
53         g_snprintf(ret, 32, "%u", comp->complex_value.uint_value);
54         break;
55     case EXTCAP_ARG_LONG:
56         g_snprintf(ret, 32, "%ld", comp->complex_value.long_value);
57         break;
58     case EXTCAP_ARG_DOUBLE:
59         g_snprintf(ret, 32, "%f", comp->complex_value.double_value);
60         break;
61     case EXTCAP_ARG_BOOLEAN:
62         g_snprintf(ret, 32, "%s",
63                 comp->complex_value.bool_value ? "true" : "false");
64         break;
65     case EXTCAP_ARG_STRING:
66     case EXTCAP_ARG_FILESELECT:
67         g_free(ret);
68         ret = g_strdup(comp->complex_value.string_value);
69         break;
70     default:
71         /* Nulling out the return string */
72         g_snprintf(ret, 32, " ");
73         break;
74     }
75
76     return ret;
77 }
78
79 extcap_complex *extcap_parse_complex(extcap_arg_type complex_type,
80         const gchar *data) {
81     extcap_complex *rc = g_new(extcap_complex, 1);
82     gboolean success = FALSE;
83     long double exp_f;
84
85     switch (complex_type) {
86     case EXTCAP_ARG_INTEGER:
87         if (sscanf(data, "%Lf", &exp_f) == 1) {
88             rc->complex_value.int_value = (int) exp_f;
89             success = TRUE;
90             break;
91         }
92         break;
93     case EXTCAP_ARG_UNSIGNED:
94         if (sscanf(data, "%Lf", &exp_f) == 1) {
95             rc->complex_value.uint_value = (unsigned int) exp_f;
96             success = TRUE;
97             break;
98         }
99         break;
100     case EXTCAP_ARG_LONG:
101         if (sscanf(data, "%Lf", &exp_f) == 1) {
102             rc->complex_value.long_value = (long) exp_f;
103             success = TRUE;
104             break;
105         }
106         break;
107     case EXTCAP_ARG_DOUBLE:
108         if (sscanf(data, "%Lf", &exp_f) == 1) {
109             rc->complex_value.double_value = (double) exp_f;
110             success = TRUE;
111             break;
112         }
113         break;
114     case EXTCAP_ARG_BOOLEAN:
115     case EXTCAP_ARG_BOOLFLAG:
116         if (data[0] == 't' || data[0] == 'T' || data[0] == '1') {
117             rc->complex_value.bool_value = 1;
118         } else {
119             rc->complex_value.bool_value = 0;
120         }
121         success = TRUE;
122         break;
123     case EXTCAP_ARG_STRING:
124     case EXTCAP_ARG_FILESELECT:
125         rc->complex_value.string_value = g_strdup(data);
126         success = TRUE;
127         break;
128     default:
129         break;
130     }
131
132     if (!success) {
133         g_free(rc);
134         return NULL ;
135     }
136
137     rc->complex_type = complex_type;
138     rc->value_filled = TRUE;
139
140     return rc;
141 }
142
143 gboolean extcap_compare_is_default(extcap_arg *element, extcap_complex *test) {
144     gboolean result = FALSE;
145
146     if (element->default_complex == NULL)
147         return result;
148
149     switch (element->arg_type) {
150     case EXTCAP_ARG_INTEGER:
151         if (extcap_complex_get_int(test)
152                 == extcap_complex_get_int(element->default_complex))
153             result = TRUE;
154         break;
155     case EXTCAP_ARG_UNSIGNED:
156         if (extcap_complex_get_uint(test)
157                 == extcap_complex_get_uint(element->default_complex))
158             result = TRUE;
159         break;
160     case EXTCAP_ARG_LONG:
161         if (extcap_complex_get_long(test)
162                 == extcap_complex_get_long(element->default_complex))
163             result = TRUE;
164         break;
165     case EXTCAP_ARG_DOUBLE:
166         if (extcap_complex_get_double(test)
167                 == extcap_complex_get_double(element->default_complex))
168             result = TRUE;
169         break;
170     case EXTCAP_ARG_BOOLEAN:
171     case EXTCAP_ARG_BOOLFLAG:
172         if (extcap_complex_get_bool(test)
173                 == extcap_complex_get_bool(element->default_complex))
174             result = TRUE;
175         break;
176     case EXTCAP_ARG_STRING:
177         if (strcmp(extcap_complex_get_string(test),
178                 extcap_complex_get_string(element->default_complex)) == 0)
179             result = TRUE;
180         break;
181
182     default:
183         break;
184     }
185
186     return result;
187 }
188
189 void extcap_free_complex(extcap_complex *comp) {
190     if (comp->complex_type == EXTCAP_ARG_STRING
191             || comp->complex_type == EXTCAP_ARG_FILESELECT)
192         g_free(comp->complex_value.string_value);
193
194     g_free(comp);
195 }
196
197 int extcap_complex_get_int(extcap_complex *comp) {
198     if ( comp == NULL )
199         return (int)0;
200     return comp->complex_value.int_value;
201 }
202
203 unsigned int extcap_complex_get_uint(extcap_complex *comp) {
204     if ( comp == NULL )
205         return (unsigned int)0;
206     return comp->complex_value.uint_value;
207 }
208
209 long extcap_complex_get_long(extcap_complex *comp) {
210     if ( comp == NULL )
211         return (long)0;
212     return comp->complex_value.long_value;
213 }
214
215 double extcap_complex_get_double(extcap_complex *comp) {
216     if ( comp == NULL )
217         return (double)0;
218     return comp->complex_value.double_value;
219 }
220
221 gboolean extcap_complex_get_bool(extcap_complex *comp) {
222     if ( comp == NULL )
223         return FALSE;
224     return comp->complex_value.bool_value;
225 }
226
227 gchar *extcap_complex_get_string(extcap_complex *comp) {
228     return comp->complex_value.string_value;
229 }
230
231 void extcap_free_tokenized_param(extcap_token_param *v) {
232     if (v == NULL)
233         return;
234
235     if (v->arg != NULL)
236         g_free(v->arg);
237
238     if (v->value != NULL)
239         g_free(v->value);
240
241     g_free(v);
242 }
243
244 void extcap_free_tokenized_sentence(extcap_token_sentence *s) {
245     extcap_token_param *tv;
246
247     if (s == NULL)
248         return;
249
250     if (s->sentence != NULL)
251         g_free(s->sentence);
252
253     while (s->param_list != NULL ) {
254         tv = s->param_list;
255         s->param_list = tv->next_token;
256
257         extcap_free_tokenized_param(tv);
258     }
259 }
260
261 void extcap_free_tokenized_sentence_list(extcap_token_sentence *f) {
262     extcap_token_sentence *t;
263
264     while (f != NULL ) {
265         t = f->next_sentence;
266         extcap_free_tokenized_sentence(f);
267         f = t;
268     }
269 }
270
271 extcap_token_sentence *extcap_tokenize_sentence(const gchar *s) {
272     gchar *b, *e, *eq;
273
274     extcap_token_param *tv = NULL;
275
276     extcap_token_sentence *rs = g_new(extcap_token_sentence, 1);
277
278     rs->sentence = NULL;
279     rs->next_sentence = NULL;
280     rs->param_list = NULL;
281
282     if ((b = g_strstr_len(s, -1, " ")) == NULL) {
283         extcap_free_tokenized_sentence(rs);
284         return NULL ;
285     }
286
287     rs->sentence = g_strndup(s, b - s);
288
289     if ((b = g_strstr_len(s, -1, "{")) == NULL) {
290         /* printf("debug - tokenizer - sentence with no values\n"); */
291         extcap_free_tokenized_sentence(rs);
292         return NULL ;
293     }
294
295     while (b != NULL ) {
296         if ((e = g_strstr_len(b, -1, "}")) == NULL) {
297             /* printf("debug - tokenizer - invalid, missing }\n"); */
298             extcap_free_tokenized_sentence(rs);
299             return NULL ;
300         }
301
302         if ((eq = g_strstr_len(b, -1, "=")) == NULL) {
303             /* printf("debug - tokenizer - invalid, missing =\n"); */
304             extcap_free_tokenized_sentence(rs);
305             return NULL ;
306         }
307
308         b++;
309         e--;
310
311         if (b >= eq || e <= eq) {
312             /* printf("debug - tokenizer - invalid, missing arg or value in {}\n"); */
313             extcap_free_tokenized_sentence(rs);
314             return NULL ;
315         }
316
317         tv = g_new(extcap_token_param, 1);
318         tv->arg = g_strndup(b, eq - b);
319         tv->value = g_strndup(eq + 1, e - eq);
320
321         if (g_ascii_strcasecmp(tv->arg, "number") == 0) {
322             tv->param_type = EXTCAP_PARAM_ARGNUM;
323         } else if (g_ascii_strcasecmp(tv->arg, "call") == 0) {
324             tv->param_type = EXTCAP_PARAM_CALL;
325         } else if (g_ascii_strcasecmp(tv->arg, "display") == 0) {
326             tv->param_type = EXTCAP_PARAM_DISPLAY;
327         } else if (g_ascii_strcasecmp(tv->arg, "type") == 0) {
328             tv->param_type = EXTCAP_PARAM_TYPE;
329         } else if (g_ascii_strcasecmp(tv->arg, "arg") == 0) {
330             tv->param_type = EXTCAP_PARAM_ARG;
331         } else if (g_ascii_strcasecmp(tv->arg, "default") == 0) {
332             tv->param_type = EXTCAP_PARAM_DEFAULT;
333         } else if (g_ascii_strcasecmp(tv->arg, "value") == 0) {
334             tv->param_type = EXTCAP_PARAM_VALUE;
335         } else if (g_ascii_strcasecmp(tv->arg, "range") == 0) {
336             tv->param_type = EXTCAP_PARAM_RANGE;
337         } else if (g_ascii_strcasecmp(tv->arg, "tooltip") == 0) {
338             tv->param_type = EXTCAP_PARAM_TOOLTIP;
339         } else if (g_ascii_strcasecmp(tv->arg, "mustexist") == 0) {
340             tv->param_type = EXTCAP_PARAM_FILE_MUSTEXIST;
341         } else if (g_ascii_strcasecmp(tv->arg, "name") == 0) {
342             tv->param_type = EXTCAP_PARAM_NAME;
343         } else if (g_ascii_strcasecmp(tv->arg, "enabled") == 0) {
344             tv->param_type = EXTCAP_PARAM_ENABLED;
345         } else if (g_ascii_strcasecmp(tv->arg, "parent") == 0) {
346             tv->param_type = EXTCAP_PARAM_PARENT;
347         } else {
348             tv->param_type = EXTCAP_PARAM_UNKNOWN;
349         }
350
351         tv->next_token = rs->param_list;
352         rs->param_list = tv;
353
354         /* printf("debug - tokenizer - got '%s' = '%s'\n", tv->arg, tv->value); */
355
356         b = e + 1;
357         if ((size_t) (b - s) > strlen(s))
358             break;
359
360         b = g_strstr_len(b, -1, "{");
361     }
362
363     return rs;
364 }
365
366 extcap_token_sentence *extcap_tokenize_sentences(const gchar *s) {
367     extcap_token_sentence *first = NULL, *cur = NULL, *last = NULL;
368
369     gchar **list, **list_iter;
370
371     list_iter = list = g_strsplit(s, "\n", 0);
372
373     while (*list_iter != NULL ) {
374         cur = extcap_tokenize_sentence(*list_iter);
375
376         if (cur != NULL) {
377             if (first == NULL) {
378                 first = cur;
379                 last = cur;
380             } else {
381                 last->next_sentence = cur;
382                 last = cur;
383             }
384         }
385
386         list_iter++;
387     }
388
389     g_strfreev(list);
390
391     return first;
392 }
393
394 extcap_token_param *extcap_find_param_by_type(extcap_token_param *first,
395         extcap_param_type t) {
396     while (first != NULL ) {
397         if (first->param_type == t) {
398             return first;
399         }
400
401         first = first->next_token;
402     }
403
404     return NULL ;
405 }
406
407 void extcap_free_value(extcap_value *v) {
408     if (v == NULL)
409         return;
410
411     if (v->call != NULL)
412         g_free(v->call);
413
414     if (v->display != NULL)
415         g_free(v->display);
416
417     g_free(v);
418 }
419
420 extcap_interface *extcap_new_interface(void) {
421     extcap_interface *r = g_new(extcap_interface, 1);
422
423     r->call = r->display = NULL;
424     r->next_interface = NULL;
425
426     return r;
427 }
428
429 void extcap_free_interface(extcap_interface *i) {
430     if (i == NULL)
431         return;
432
433     if (i->call != NULL)
434         g_free(i->call);
435
436     if (i->display != NULL)
437         g_free(i->display);
438 }
439
440 extcap_dlt *extcap_new_dlt(void) {
441     extcap_dlt *r = g_new(extcap_dlt, 1);
442
443     r->number = -1;
444     r->name = r->display = NULL;
445     r->next_dlt = NULL;
446
447     return r;
448 }
449
450 void extcap_free_dlt(extcap_dlt *d) {
451     if (d == NULL)
452         return;
453
454     if (d->name != NULL)
455         g_free(d->name);
456
457     if (d->display != NULL)
458         g_free(d->display);
459 }
460
461 extcap_arg *extcap_new_arg(void) {
462     extcap_arg *r = g_new(extcap_arg, 1);
463
464     r->call = NULL;
465     r->display = NULL;
466     r->tooltip = NULL;
467     r->arg_type = EXTCAP_ARG_UNKNOWN;
468     r->range_start = NULL;
469     r->range_end = NULL;
470     r->default_complex = NULL;
471     r->fileexists = FALSE;
472
473     r->values = NULL;
474     /*r->next_arg = NULL; */
475
476     return r;
477 }
478
479 static void extcap_free_valuelist(gpointer data, gpointer user_data _U_) {
480     extcap_free_value((extcap_value *) data);
481 }
482
483 void extcap_free_arg(extcap_arg *a) {
484
485     if (a == NULL)
486         return;
487
488     if (a->call != NULL)
489         g_free(a->call);
490
491     if (a->display != NULL)
492         g_free(a->display);
493
494     if (a->tooltip != NULL)
495         g_free(a->tooltip);
496
497     if (a->range_start != NULL)
498         extcap_free_complex(a->range_start);
499
500     if (a->range_end != NULL)
501         extcap_free_complex(a->range_end);
502
503     if (a->default_complex != NULL)
504         extcap_free_complex(a->default_complex);
505
506     g_list_foreach(a->values, (GFunc) extcap_free_valuelist, NULL);
507 }
508
509 static void extcap_free_arg_list_cb(gpointer listentry, gpointer data _U_) {
510     if (listentry != NULL)
511         extcap_free_arg((extcap_arg *) listentry);
512 }
513
514 void extcap_free_arg_list(GList *a) {
515     g_list_foreach(a, extcap_free_arg_list_cb, NULL);
516     g_list_free(a);
517 }
518
519 static gint glist_find_numbered_arg(gconstpointer listelem, gconstpointer needle) {
520     if (((const extcap_arg *) listelem)->arg_num == *((const int*) needle))
521         return 0;
522     return 1;
523 }
524
525 extcap_arg *extcap_parse_arg_sentence(GList * args, extcap_token_sentence *s) {
526     extcap_token_param *v = NULL;
527     extcap_arg *target_arg = NULL;
528     extcap_value *value = NULL;
529     GList * entry = NULL;
530     int tint;
531     extcap_sentence_type sent = EXTCAP_SENTENCE_UNKNOWN;
532
533     if (s == NULL)
534         return target_arg;
535
536     if (g_ascii_strcasecmp(s->sentence, "arg") == 0) {
537         sent = EXTCAP_SENTENCE_ARG;
538         /* printf("ARG sentence\n"); */
539     } else if (g_ascii_strcasecmp(s->sentence, "value") == 0) {
540         sent = EXTCAP_SENTENCE_VALUE;
541         /* printf("VALUE sentence\n"); */
542     }
543
544     if (sent == EXTCAP_SENTENCE_ARG) {
545         target_arg = extcap_new_arg();
546
547         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_ARGNUM))
548                 == NULL) {
549             extcap_free_arg(target_arg);
550             return NULL ;
551         }
552
553         if (sscanf(v->value, "%d", &(target_arg->arg_num)) != 1) {
554             extcap_free_arg(target_arg);
555             return NULL ;
556         }
557
558         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_CALL))
559                 == NULL) {
560             extcap_free_arg(target_arg);
561             return NULL ;
562         }
563         target_arg->call = g_strdup(v->value);
564
565         /* No value only parameters allowed */
566         if (strlen(target_arg->call) == 0) {
567             extcap_free_arg(target_arg);
568             return NULL ;
569         }
570
571         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_DISPLAY))
572                 == NULL) {
573             extcap_free_arg(target_arg);
574             return NULL ;
575         }
576         target_arg->display = g_strdup(v->value);
577
578         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_TOOLTIP))
579                 != NULL) {
580             target_arg->tooltip = g_strdup(v->value);
581         }
582
583         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_FILE_MUSTEXIST))
584                 != NULL) {
585             target_arg->fileexists = (v->value[0] == 't' || v->value[0] == 'T');
586         }
587
588         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_TYPE))
589                 == NULL) {
590             /* printf("no type in ARG sentence\n"); */
591             extcap_free_arg(target_arg);
592             return NULL ;
593         }
594
595         if (g_ascii_strcasecmp(v->value, "integer") == 0) {
596             target_arg->arg_type = EXTCAP_ARG_INTEGER;
597         } else if (g_ascii_strcasecmp(v->value, "unsigned") == 0) {
598             target_arg->arg_type = EXTCAP_ARG_UNSIGNED;
599         } else if (g_ascii_strcasecmp(v->value, "long") == 0) {
600             target_arg->arg_type = EXTCAP_ARG_LONG;
601         } else if (g_ascii_strcasecmp(v->value, "double") == 0) {
602             target_arg->arg_type = EXTCAP_ARG_DOUBLE;
603         } else if (g_ascii_strcasecmp(v->value, "boolean") == 0) {
604             target_arg->arg_type = EXTCAP_ARG_BOOLEAN;
605         } else if (g_ascii_strcasecmp(v->value, "boolflag") == 0) {
606             target_arg->arg_type = EXTCAP_ARG_BOOLFLAG;
607         } else if (g_ascii_strcasecmp(v->value, "selector") == 0) {
608             target_arg->arg_type = EXTCAP_ARG_SELECTOR;
609         } else if (g_ascii_strcasecmp(v->value, "radio") == 0) {
610             target_arg->arg_type = EXTCAP_ARG_RADIO;
611         } else if (g_ascii_strcasecmp(v->value, "string") == 0) {
612             target_arg->arg_type = EXTCAP_ARG_STRING;
613         } else if (g_ascii_strcasecmp(v->value, "fileselect") == 0) {
614             target_arg->arg_type = EXTCAP_ARG_FILESELECT;
615         } else if (g_ascii_strcasecmp(v->value, "multicheck") == 0) {
616             target_arg->arg_type = EXTCAP_ARG_MULTICHECK;
617         } else {
618             printf("invalid type %s in ARG sentence\n", v->value);
619             extcap_free_arg(target_arg);
620             return NULL ;
621         }
622
623         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_RANGE))
624                 != NULL) {
625             gchar *cp = g_strstr_len(v->value, -1, ",");
626
627             if (cp == NULL) {
628                 printf("invalid range, expected value,value got %s\n",
629                         v->value);
630                 extcap_free_arg(target_arg);
631                 return NULL ;
632             }
633
634             if ((target_arg->range_start = extcap_parse_complex(
635                     target_arg->arg_type, v->value)) == NULL) {
636                 printf("invalid range, expected value,value got %s\n",
637                         v->value);
638                 extcap_free_arg(target_arg);
639                 return NULL ;
640             }
641
642             if ((target_arg->range_end = extcap_parse_complex(
643                     target_arg->arg_type, cp + 1)) == NULL) {
644                 printf("invalid range, expected value,value got %s\n",
645                         v->value);
646                 extcap_free_arg(target_arg);
647                 return NULL ;
648             }
649         }
650
651         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_DEFAULT))
652                 != NULL) {
653             if ((target_arg->default_complex = extcap_parse_complex(
654                     target_arg->arg_type, v->value)) == NULL) {
655                 printf("invalid default, couldn't parse %s\n", v->value);
656             }
657         }
658
659     } else if (sent == EXTCAP_SENTENCE_VALUE) {
660         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_ARG))
661                 == NULL) {
662             printf("no arg in VALUE sentence\n");
663             return NULL ;
664         }
665
666         if (sscanf(v->value, "%d", &tint) != 1) {
667             printf("invalid arg in VALUE sentence\n");
668             return NULL ;
669         }
670
671         ;
672         if ((entry = g_list_find_custom(args, &tint, glist_find_numbered_arg))
673                 == NULL) {
674             printf("couldn't find arg %d in list for VALUE sentence\n", tint);
675             return NULL ;
676         }
677
678         value = g_new(extcap_value, 1);
679         value->display = NULL;
680         value->call = NULL;
681         value->enabled = FALSE;
682         value->is_default = FALSE;
683         value->arg_num = tint;
684         value->parent = NULL;
685
686         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_VALUE))
687                 == NULL) {
688             /* printf("no value in VALUE sentence\n"); */
689             extcap_free_value(value);
690             return NULL ;
691         }
692         value->call = g_strdup(v->value);
693
694         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_DISPLAY))
695                 == NULL) {
696             /* printf("no display in VALUE sentence\n"); */
697             extcap_free_value(value);
698             return NULL ;
699         }
700         value->display = g_strdup(v->value);
701
702         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_PARENT))
703                 != NULL) {
704             value->parent = g_strdup(v->value);
705         }
706
707         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_DEFAULT))
708                 != NULL) {
709             /* printf("found default value\n"); */
710             value->is_default = (v->value[0] == 't' || v->value[0] == 'T');
711         }
712
713         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_ENABLED))
714                 != NULL) {
715             value->enabled = (v->value[0] == 't' || v->value[0] == 'T');
716         }
717
718         ((extcap_arg*) entry->data)->values = g_list_append(
719                 ((extcap_arg*) entry->data)->values, value);
720
721         return NULL ;
722     }
723
724     return target_arg;
725 }
726
727 GList * extcap_parse_args(extcap_token_sentence *first_s) {
728     GList * args = NULL;
729
730     while (first_s) {
731         extcap_arg *ra = NULL;
732
733         if ((ra = extcap_parse_arg_sentence(args, first_s)) != NULL)
734             args = g_list_append(args, (gpointer) ra);
735
736         first_s = first_s->next_sentence;
737     }
738
739     return args;
740 }
741
742 int extcap_parse_interface_sentence(extcap_token_sentence *s,
743         extcap_interface **ri) {
744     extcap_token_param *v = NULL;
745     extcap_sentence_type sent = EXTCAP_SENTENCE_UNKNOWN;
746
747     *ri = NULL;
748
749     if (s == NULL)
750         return -1;
751
752     if (g_ascii_strcasecmp(s->sentence, "interface") == 0) {
753         sent = EXTCAP_SENTENCE_INTERFACE;
754         /* printf("INTERFACE sentence\n"); */
755     }
756
757     if (sent == EXTCAP_SENTENCE_UNKNOWN)
758         return -1;
759
760     *ri = extcap_new_interface();
761
762     if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_VALUE))
763             == NULL) {
764         printf("No value in INTERFACE sentence\n");
765         extcap_free_interface(*ri);
766         return -1;
767     }
768     (*ri)->call = g_strdup(v->value);
769
770     if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_DISPLAY))
771             == NULL) {
772         printf("No display in INTERFACE sentence\n");
773         extcap_free_interface(*ri);
774         return -1;
775     }
776     (*ri)->display = g_strdup(v->value);
777
778     return 1;
779 }
780
781 int extcap_parse_interfaces(extcap_token_sentence *first_s,
782         extcap_interface **first_int) {
783     extcap_interface *first_i = NULL, *last_i = NULL;
784
785     while (first_s) {
786         extcap_interface *ri;
787
788         if (extcap_parse_interface_sentence(first_s, &ri) >= 0 && ri != NULL) {
789             if (first_i == NULL) {
790                 first_i = last_i = ri;
791             } else {
792                 last_i->next_interface = ri;
793                 last_i = ri;
794             }
795         }
796
797         first_s = first_s->next_sentence;
798     }
799
800     *first_int = first_i;
801
802     return 1;
803 }
804
805 int extcap_parse_dlt_sentence(extcap_token_sentence *s, extcap_dlt **rd) {
806     extcap_token_param *v = NULL;
807     extcap_sentence_type sent = EXTCAP_SENTENCE_UNKNOWN;
808
809     *rd = NULL;
810
811     if (s == NULL)
812         return -1;
813
814     if (g_ascii_strcasecmp(s->sentence, "dlt") == 0) {
815         sent = EXTCAP_SENTENCE_DLT;
816     }
817
818     if (sent == EXTCAP_SENTENCE_UNKNOWN)
819         return -1;
820
821     *rd = extcap_new_dlt();
822
823     if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_ARGNUM))
824             == NULL) {
825         printf("No number in DLT sentence\n");
826         extcap_free_dlt(*rd);
827         return -1;
828     }
829     if (sscanf(v->value, "%d", &((*rd)->number)) != 1) {
830         printf("Invalid number in DLT sentence\n");
831         extcap_free_dlt(*rd);
832         return -1;
833     }
834
835     if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_NAME))
836             == NULL) {
837         printf("No name in DLT sentence\n");
838         extcap_free_dlt(*rd);
839         return -1;
840     }
841     (*rd)->name = g_strdup(v->value);
842
843     if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_DISPLAY))
844             == NULL) {
845         printf("No display in DLT sentence\n");
846         extcap_free_dlt(*rd);
847         return -1;
848     }
849     (*rd)->display = g_strdup(v->value);
850
851     return 1;
852 }
853
854 int extcap_parse_dlts(extcap_token_sentence *first_s, extcap_dlt **first_dlt) {
855     extcap_dlt *first_d = NULL, *last_d = NULL;
856
857     while (first_s) {
858         extcap_dlt *rd;
859
860         if (extcap_parse_dlt_sentence(first_s, &rd) >= 0 && rd != NULL) {
861             if (first_d == NULL) {
862                 first_d = last_d = rd;
863             } else {
864                 last_d->next_dlt = rd;
865                 last_d = rd;
866             }
867         }
868
869         first_s = first_s->next_sentence;
870     }
871
872     *first_dlt = first_d;
873
874     return 1;
875 }
876
877 /*
878  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
879  *
880  * Local variables:
881  * c-basic-offset: 4
882  * tab-width: 8
883  * indent-tabs-mode: nil
884  * End:
885  *
886  * vi: set shiftwidth=4 tabstop=8 expandtab:
887  * :indentSize=4:tabSize=8:noTabs=true:
888  */