Fix Wai dissector
[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, "menu") == 0) {
608             target_arg->arg_type = EXTCAP_ARG_MENU;
609         } else if (g_ascii_strcasecmp(v->value, "selector") == 0) {
610             target_arg->arg_type = EXTCAP_ARG_SELECTOR;
611         } else if (g_ascii_strcasecmp(v->value, "radio") == 0) {
612             target_arg->arg_type = EXTCAP_ARG_RADIO;
613         } else if (g_ascii_strcasecmp(v->value, "string") == 0) {
614             target_arg->arg_type = EXTCAP_ARG_STRING;
615         } else if (g_ascii_strcasecmp(v->value, "fileselect") == 0) {
616             target_arg->arg_type = EXTCAP_ARG_FILESELECT;
617         } else if (g_ascii_strcasecmp(v->value, "multicheck") == 0) {
618             target_arg->arg_type = EXTCAP_ARG_MULTICHECK;
619         } else {
620             printf("invalid type %s in ARG sentence\n", v->value);
621             extcap_free_arg(target_arg);
622             return NULL ;
623         }
624
625         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_RANGE))
626                 != NULL) {
627             gchar *cp = g_strstr_len(v->value, -1, ",");
628
629             if (cp == NULL) {
630                 printf("invalid range, expected value,value got %s\n",
631                         v->value);
632                 extcap_free_arg(target_arg);
633                 return NULL ;
634             }
635
636             if ((target_arg->range_start = extcap_parse_complex(
637                     target_arg->arg_type, v->value)) == NULL) {
638                 printf("invalid range, expected value,value got %s\n",
639                         v->value);
640                 extcap_free_arg(target_arg);
641                 return NULL ;
642             }
643
644             if ((target_arg->range_end = extcap_parse_complex(
645                     target_arg->arg_type, cp + 1)) == NULL) {
646                 printf("invalid range, expected value,value got %s\n",
647                         v->value);
648                 extcap_free_arg(target_arg);
649                 return NULL ;
650             }
651         }
652
653         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_DEFAULT))
654                 != NULL) {
655             if ((target_arg->default_complex = extcap_parse_complex(
656                     target_arg->arg_type, v->value)) == NULL) {
657                 printf("invalid default, couldn't parse %s\n", v->value);
658             }
659         }
660
661     } else if (sent == EXTCAP_SENTENCE_VALUE) {
662         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_ARG))
663                 == NULL) {
664             printf("no arg in VALUE sentence\n");
665             return NULL ;
666         }
667
668         if (sscanf(v->value, "%d", &tint) != 1) {
669             printf("invalid arg in VALUE sentence\n");
670             return NULL ;
671         }
672
673         ;
674         if ((entry = g_list_find_custom(args, &tint, glist_find_numbered_arg))
675                 == NULL) {
676             printf("couldn't find arg %d in list for VALUE sentence\n", tint);
677             return NULL ;
678         }
679
680         value = g_new(extcap_value, 1);
681         value->display = NULL;
682         value->call = NULL;
683         value->enabled = FALSE;
684         value->is_default = FALSE;
685         value->arg_num = tint;
686         value->parent = NULL;
687
688         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_VALUE))
689                 == NULL) {
690             /* printf("no value in VALUE sentence\n"); */
691             extcap_free_value(value);
692             return NULL ;
693         }
694         value->call = g_strdup(v->value);
695
696         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_DISPLAY))
697                 == NULL) {
698             /* printf("no display in VALUE sentence\n"); */
699             extcap_free_value(value);
700             return NULL ;
701         }
702         value->display = g_strdup(v->value);
703
704         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_PARENT))
705                 != NULL) {
706             value->parent = g_strdup(v->value);
707         }
708
709         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_DEFAULT))
710                 != NULL) {
711             /* printf("found default value\n"); */
712             value->is_default = (v->value[0] == 't' || v->value[0] == 'T');
713         }
714
715         if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_ENABLED))
716                 != NULL) {
717             value->enabled = (v->value[0] == 't' || v->value[0] == 'T');
718         }
719
720         ((extcap_arg*) entry->data)->values = g_list_append(
721                 ((extcap_arg*) entry->data)->values, value);
722
723         return NULL ;
724     }
725
726     return target_arg;
727 }
728
729 GList * extcap_parse_args(extcap_token_sentence *first_s) {
730     GList * args = NULL;
731
732     while (first_s) {
733         extcap_arg *ra = NULL;
734
735         if ((ra = extcap_parse_arg_sentence(args, first_s)) != NULL)
736             args = g_list_append(args, (gpointer) ra);
737
738         first_s = first_s->next_sentence;
739     }
740
741     return args;
742 }
743
744 int extcap_parse_interface_sentence(extcap_token_sentence *s,
745         extcap_interface **ri) {
746     extcap_token_param *v = NULL;
747     extcap_sentence_type sent = EXTCAP_SENTENCE_UNKNOWN;
748
749     *ri = NULL;
750
751     if (s == NULL)
752         return -1;
753
754     if (g_ascii_strcasecmp(s->sentence, "interface") == 0) {
755         sent = EXTCAP_SENTENCE_INTERFACE;
756         /* printf("INTERFACE sentence\n"); */
757     }
758
759     if (sent == EXTCAP_SENTENCE_UNKNOWN)
760         return -1;
761
762     *ri = extcap_new_interface();
763
764     if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_VALUE))
765             == NULL) {
766         printf("No value in INTERFACE sentence\n");
767         extcap_free_interface(*ri);
768         return -1;
769     }
770     (*ri)->call = g_strdup(v->value);
771
772     if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_DISPLAY))
773             == NULL) {
774         printf("No display in INTERFACE sentence\n");
775         extcap_free_interface(*ri);
776         return -1;
777     }
778     (*ri)->display = g_strdup(v->value);
779
780     return 1;
781 }
782
783 int extcap_parse_interfaces(extcap_token_sentence *first_s,
784         extcap_interface **first_int) {
785     extcap_interface *first_i = NULL, *last_i = NULL;
786
787     while (first_s) {
788         extcap_interface *ri;
789
790         if (extcap_parse_interface_sentence(first_s, &ri) >= 0 && ri != NULL) {
791             if (first_i == NULL) {
792                 first_i = last_i = ri;
793             } else {
794                 last_i->next_interface = ri;
795                 last_i = ri;
796             }
797         }
798
799         first_s = first_s->next_sentence;
800     }
801
802     *first_int = first_i;
803
804     return 1;
805 }
806
807 int extcap_parse_dlt_sentence(extcap_token_sentence *s, extcap_dlt **rd) {
808     extcap_token_param *v = NULL;
809     extcap_sentence_type sent = EXTCAP_SENTENCE_UNKNOWN;
810
811     *rd = NULL;
812
813     if (s == NULL)
814         return -1;
815
816     if (g_ascii_strcasecmp(s->sentence, "dlt") == 0) {
817         sent = EXTCAP_SENTENCE_DLT;
818     }
819
820     if (sent == EXTCAP_SENTENCE_UNKNOWN)
821         return -1;
822
823     *rd = extcap_new_dlt();
824
825     if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_ARGNUM))
826             == NULL) {
827         printf("No number in DLT sentence\n");
828         extcap_free_dlt(*rd);
829         return -1;
830     }
831     if (sscanf(v->value, "%d", &((*rd)->number)) != 1) {
832         printf("Invalid number in DLT sentence\n");
833         extcap_free_dlt(*rd);
834         return -1;
835     }
836
837     if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_NAME))
838             == NULL) {
839         printf("No name in DLT sentence\n");
840         extcap_free_dlt(*rd);
841         return -1;
842     }
843     (*rd)->name = g_strdup(v->value);
844
845     if ((v = extcap_find_param_by_type(s->param_list, EXTCAP_PARAM_DISPLAY))
846             == NULL) {
847         printf("No display in DLT sentence\n");
848         extcap_free_dlt(*rd);
849         return -1;
850     }
851     (*rd)->display = g_strdup(v->value);
852
853     return 1;
854 }
855
856 int extcap_parse_dlts(extcap_token_sentence *first_s, extcap_dlt **first_dlt) {
857     extcap_dlt *first_d = NULL, *last_d = NULL;
858
859     while (first_s) {
860         extcap_dlt *rd;
861
862         if (extcap_parse_dlt_sentence(first_s, &rd) >= 0 && rd != NULL) {
863             if (first_d == NULL) {
864                 first_d = last_d = rd;
865             } else {
866                 last_d->next_dlt = rd;
867                 last_d = rd;
868             }
869         }
870
871         first_s = first_s->next_sentence;
872     }
873
874     *first_dlt = first_d;
875
876     return 1;
877 }
878
879 /*
880  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
881  *
882  * Local variables:
883  * c-basic-offset: 4
884  * tab-width: 8
885  * indent-tabs-mode: nil
886  * End:
887  *
888  * vi: set shiftwidth=4 tabstop=8 expandtab:
889  * :indentSize=4:tabSize=8:noTabs=true:
890  */