1a7398723SShteryana Shopova /*-
2a7398723SShteryana Shopova * Copyright (c) 2006 The FreeBSD Project
3a7398723SShteryana Shopova * All rights reserved.
4a7398723SShteryana Shopova *
5a7398723SShteryana Shopova * Author: Shteryana Shopova <syrinx@FreeBSD.org>
6a7398723SShteryana Shopova *
7a7398723SShteryana Shopova * Redistribution of this software and documentation and use in source and
8a7398723SShteryana Shopova * binary forms, with or without modification, are permitted provided that
9a7398723SShteryana Shopova * the following conditions are met:
10a7398723SShteryana Shopova *
11a7398723SShteryana Shopova * 1. Redistributions of source code or documentation must retain the above
12a7398723SShteryana Shopova * copyright notice, this list of conditions and the following disclaimer.
13a7398723SShteryana Shopova * 2. Redistributions in binary form must reproduce the above copyright
14a7398723SShteryana Shopova * notice, this list of conditions and the following disclaimer in the
15a7398723SShteryana Shopova * documentation and/or other materials provided with the distribution.
16a7398723SShteryana Shopova *
17a7398723SShteryana Shopova * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18a7398723SShteryana Shopova * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19a7398723SShteryana Shopova * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20a7398723SShteryana Shopova * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21a7398723SShteryana Shopova * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22a7398723SShteryana Shopova * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23a7398723SShteryana Shopova * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24a7398723SShteryana Shopova * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25a7398723SShteryana Shopova * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26a7398723SShteryana Shopova * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27a7398723SShteryana Shopova * SUCH DAMAGE.
28a7398723SShteryana Shopova */
29a7398723SShteryana Shopova
30a7398723SShteryana Shopova /*
31a7398723SShteryana Shopova * Read file containing table description - reuse magic from gensnmptree.c.
32a7398723SShteryana Shopova * Hopefully one day most of the code here will be part of libbsnmp and
33a7398723SShteryana Shopova * this duplication won't be necessary.
34a7398723SShteryana Shopova *
35a7398723SShteryana Shopova * Syntax is:
36a7398723SShteryana Shopova * ---------
37a7398723SShteryana Shopova * file := top | top file
38a7398723SShteryana Shopova *
39a7398723SShteryana Shopova * top := tree | typedef | include
40a7398723SShteryana Shopova *
41a7398723SShteryana Shopova * tree := head elements ')'
42a7398723SShteryana Shopova *
43a7398723SShteryana Shopova * entry := head ':' index STRING elements ')'
44a7398723SShteryana Shopova *
45a7398723SShteryana Shopova * leaf := head type STRING ACCESS ')'
46a7398723SShteryana Shopova *
47a7398723SShteryana Shopova * column := head type ACCESS ')'
48a7398723SShteryana Shopova *
49a7398723SShteryana Shopova * type := BASETYPE | BASETYPE '|' subtype | enum | bits
50a7398723SShteryana Shopova *
51a7398723SShteryana Shopova * subtype := STRING
52a7398723SShteryana Shopova *
53a7398723SShteryana Shopova * enum := ENUM '(' value ')'
54a7398723SShteryana Shopova *
55a7398723SShteryana Shopova * bits := BITS '(' value ')'
56a7398723SShteryana Shopova *
57a7398723SShteryana Shopova * value := INT STRING | INT STRING value
58a7398723SShteryana Shopova *
59a7398723SShteryana Shopova * head := '(' INT STRING
60a7398723SShteryana Shopova *
61a7398723SShteryana Shopova * elements := EMPTY | elements element
62a7398723SShteryana Shopova *
63a7398723SShteryana Shopova * element := tree | leaf | column
64a7398723SShteryana Shopova *
65a7398723SShteryana Shopova * index := type | index type
66a7398723SShteryana Shopova *
67a7398723SShteryana Shopova * typedef := 'typedef' STRING type
68a7398723SShteryana Shopova *
69a7398723SShteryana Shopova * include := 'include' filespec
70a7398723SShteryana Shopova *
71a7398723SShteryana Shopova * filespec := '"' STRING '"' | '<' STRING '>'
72a7398723SShteryana Shopova */
73a7398723SShteryana Shopova
74a7398723SShteryana Shopova #include <sys/param.h>
75a7398723SShteryana Shopova #include <sys/queue.h>
76a7398723SShteryana Shopova #include <sys/uio.h>
77a7398723SShteryana Shopova
78a7398723SShteryana Shopova #include <ctype.h>
79a7398723SShteryana Shopova #include <err.h>
80a7398723SShteryana Shopova #include <errno.h>
81a7398723SShteryana Shopova #include <fcntl.h>
82*1f474190SStefan Eßer #include <paths.h>
83a7398723SShteryana Shopova #include <stdio.h>
84a7398723SShteryana Shopova #include <stdlib.h>
85a7398723SShteryana Shopova #include <string.h>
86a7398723SShteryana Shopova #include <syslog.h>
87a7398723SShteryana Shopova #include <unistd.h>
88a7398723SShteryana Shopova
89a7398723SShteryana Shopova #include <bsnmp/asn1.h>
90a7398723SShteryana Shopova #include <bsnmp/snmp.h>
91a7398723SShteryana Shopova #include <bsnmp/snmpagent.h> /* SNMP_INDEXES_MAX */
92a7398723SShteryana Shopova #include "bsnmptc.h"
93a7398723SShteryana Shopova #include "bsnmptools.h"
94a7398723SShteryana Shopova
95a7398723SShteryana Shopova enum snmp_tbl_entry {
96a7398723SShteryana Shopova ENTRY_NONE = 0,
97a7398723SShteryana Shopova ENTRY_INDEX,
98a7398723SShteryana Shopova ENTRY_DATA
99a7398723SShteryana Shopova };
100a7398723SShteryana Shopova
101a7398723SShteryana Shopova enum {
102a7398723SShteryana Shopova FL_GET = 0x01,
103a7398723SShteryana Shopova FL_SET = 0x02,
104a7398723SShteryana Shopova };
105a7398723SShteryana Shopova
106a7398723SShteryana Shopova /************************************************************
107a7398723SShteryana Shopova *
108a7398723SShteryana Shopova * Allocate memory and panic just in the case...
109a7398723SShteryana Shopova */
110a7398723SShteryana Shopova static void *
xalloc(size_t size)111a7398723SShteryana Shopova xalloc(size_t size)
112a7398723SShteryana Shopova {
113a7398723SShteryana Shopova void *ptr;
114a7398723SShteryana Shopova
115a7398723SShteryana Shopova if ((ptr = malloc(size)) == NULL)
116a7398723SShteryana Shopova err(1, "allocing %zu bytes", size);
117a7398723SShteryana Shopova
118a7398723SShteryana Shopova return (ptr);
119a7398723SShteryana Shopova }
120a7398723SShteryana Shopova
121a7398723SShteryana Shopova static char *
savestr(const char * s)122a7398723SShteryana Shopova savestr(const char *s)
123a7398723SShteryana Shopova {
124a7398723SShteryana Shopova if (s == NULL)
125a7398723SShteryana Shopova return (NULL);
126a7398723SShteryana Shopova
127a7398723SShteryana Shopova return (strcpy(xalloc(strlen(s) + 1), s));
128a7398723SShteryana Shopova }
129a7398723SShteryana Shopova
130a7398723SShteryana Shopova /************************************************************
131a7398723SShteryana Shopova *
132a7398723SShteryana Shopova * Input stack
133a7398723SShteryana Shopova */
134a7398723SShteryana Shopova struct input {
135a7398723SShteryana Shopova FILE *fp;
136a7398723SShteryana Shopova uint32_t lno;
137a7398723SShteryana Shopova char *fname;
138a7398723SShteryana Shopova char *path;
139a7398723SShteryana Shopova LIST_ENTRY(input) link;
140a7398723SShteryana Shopova };
141a7398723SShteryana Shopova
14229517fcaSEnji Cooper static LIST_HEAD(, input) inputs = LIST_HEAD_INITIALIZER(inputs);
14329517fcaSEnji Cooper static struct input *input = NULL;
14429517fcaSEnji Cooper static int32_t pbchar = -1;
145a7398723SShteryana Shopova
146a7398723SShteryana Shopova #define MAX_PATHS 100
147a7398723SShteryana Shopova
148a7398723SShteryana Shopova static const char *paths[MAX_PATHS + 1] = {
149a7398723SShteryana Shopova "/usr/share/snmp/defs",
150*1f474190SStefan Eßer _PATH_LOCALBASE "/share/snmp/defs",
151a7398723SShteryana Shopova NULL
152a7398723SShteryana Shopova };
153a7398723SShteryana Shopova
154a7398723SShteryana Shopova static void
input_new(FILE * fp,const char * path,const char * fname)155a7398723SShteryana Shopova input_new(FILE *fp, const char *path, const char *fname)
156a7398723SShteryana Shopova {
157a7398723SShteryana Shopova struct input *ip;
158a7398723SShteryana Shopova
159a7398723SShteryana Shopova ip = xalloc(sizeof(*ip));
160a7398723SShteryana Shopova ip->fp = fp;
161a7398723SShteryana Shopova ip->lno = 1;
162a7398723SShteryana Shopova ip->fname = savestr(fname);
163a7398723SShteryana Shopova ip->path = savestr(path);
164a7398723SShteryana Shopova LIST_INSERT_HEAD(&inputs, ip, link);
165a7398723SShteryana Shopova
166a7398723SShteryana Shopova input = ip;
167a7398723SShteryana Shopova }
168a7398723SShteryana Shopova
169a7398723SShteryana Shopova static void
input_close(void)170a7398723SShteryana Shopova input_close(void)
171a7398723SShteryana Shopova {
172a7398723SShteryana Shopova if (input == NULL)
173a7398723SShteryana Shopova return;
174a7398723SShteryana Shopova
175a7398723SShteryana Shopova fclose(input->fp);
176a7398723SShteryana Shopova free(input->fname);
177a7398723SShteryana Shopova free(input->path);
178a7398723SShteryana Shopova LIST_REMOVE(input, link);
179a7398723SShteryana Shopova free(input);
180a7398723SShteryana Shopova
181a7398723SShteryana Shopova input = LIST_FIRST(&inputs);
182a7398723SShteryana Shopova }
183a7398723SShteryana Shopova
184a7398723SShteryana Shopova static FILE *
tryopen(const char * path,const char * fname)185a7398723SShteryana Shopova tryopen(const char *path, const char *fname)
186a7398723SShteryana Shopova {
187a7398723SShteryana Shopova char *fn;
188a7398723SShteryana Shopova FILE *fp;
189a7398723SShteryana Shopova
190a7398723SShteryana Shopova if (path == NULL)
191a7398723SShteryana Shopova fn = savestr(fname);
192a7398723SShteryana Shopova else {
193a7398723SShteryana Shopova fn = xalloc(strlen(path) + strlen(fname) + 2);
194a7398723SShteryana Shopova sprintf(fn, "%s/%s", path, fname);
195a7398723SShteryana Shopova }
196a7398723SShteryana Shopova fp = fopen(fn, "r");
197a7398723SShteryana Shopova free(fn);
198a7398723SShteryana Shopova return (fp);
199a7398723SShteryana Shopova }
200a7398723SShteryana Shopova
201a7398723SShteryana Shopova static int32_t
input_fopen(const char * fname)202a7398723SShteryana Shopova input_fopen(const char *fname)
203a7398723SShteryana Shopova {
204a7398723SShteryana Shopova FILE *fp;
205a7398723SShteryana Shopova u_int p;
206a7398723SShteryana Shopova
207a7398723SShteryana Shopova if (fname[0] == '/' || fname[0] == '.' || fname[0] == '~') {
208a7398723SShteryana Shopova if ((fp = tryopen(NULL, fname)) != NULL) {
209a7398723SShteryana Shopova input_new(fp, NULL, fname);
210a7398723SShteryana Shopova return (0);
211a7398723SShteryana Shopova }
212a7398723SShteryana Shopova
213a7398723SShteryana Shopova } else {
214a7398723SShteryana Shopova
215a7398723SShteryana Shopova for (p = 0; paths[p] != NULL; p++)
216a7398723SShteryana Shopova if ((fp = tryopen(paths[p], fname)) != NULL) {
217a7398723SShteryana Shopova input_new(fp, paths[p], fname);
218a7398723SShteryana Shopova return (0);
219a7398723SShteryana Shopova }
220a7398723SShteryana Shopova }
221a7398723SShteryana Shopova
222a7398723SShteryana Shopova warnx("cannot open '%s'", fname);
223a7398723SShteryana Shopova return (-1);
224a7398723SShteryana Shopova }
225a7398723SShteryana Shopova
226a7398723SShteryana Shopova static int32_t
tgetc(void)227a7398723SShteryana Shopova tgetc(void)
228a7398723SShteryana Shopova {
229a7398723SShteryana Shopova int c;
230a7398723SShteryana Shopova
231a7398723SShteryana Shopova if (pbchar != -1) {
232a7398723SShteryana Shopova c = pbchar;
233a7398723SShteryana Shopova pbchar = -1;
234a7398723SShteryana Shopova return (c);
235a7398723SShteryana Shopova }
236a7398723SShteryana Shopova
237a7398723SShteryana Shopova for (;;) {
238a7398723SShteryana Shopova if (input == NULL)
239a7398723SShteryana Shopova return (EOF);
240a7398723SShteryana Shopova
241a7398723SShteryana Shopova if ((c = getc(input->fp)) != EOF)
242a7398723SShteryana Shopova return (c);
243a7398723SShteryana Shopova
244a7398723SShteryana Shopova input_close();
245a7398723SShteryana Shopova }
246a7398723SShteryana Shopova }
247a7398723SShteryana Shopova
248a7398723SShteryana Shopova static int32_t
tungetc(int c)249a7398723SShteryana Shopova tungetc(int c)
250a7398723SShteryana Shopova {
251a7398723SShteryana Shopova
252a7398723SShteryana Shopova if (pbchar != -1)
253a7398723SShteryana Shopova return (-1);
254a7398723SShteryana Shopova
255a7398723SShteryana Shopova pbchar = c;
256a7398723SShteryana Shopova return (1);
257a7398723SShteryana Shopova }
258a7398723SShteryana Shopova
259a7398723SShteryana Shopova /************************************************************
260a7398723SShteryana Shopova *
261a7398723SShteryana Shopova * Parsing input
262a7398723SShteryana Shopova */
263a7398723SShteryana Shopova enum tok {
264a7398723SShteryana Shopova TOK_EOF = 0200, /* end-of-file seen */
265a7398723SShteryana Shopova TOK_NUM, /* number */
266a7398723SShteryana Shopova TOK_STR, /* string */
267a7398723SShteryana Shopova TOK_ACCESS, /* access operator */
268a7398723SShteryana Shopova TOK_TYPE, /* type operator */
269a7398723SShteryana Shopova TOK_ENUM, /* enum token (kind of a type) */
270a7398723SShteryana Shopova TOK_TYPEDEF, /* typedef directive */
271a7398723SShteryana Shopova TOK_DEFTYPE, /* defined type */
272a7398723SShteryana Shopova TOK_INCLUDE, /* include directive */
273a7398723SShteryana Shopova TOK_FILENAME, /* filename ("foo.bar" or <foo.bar>) */
274a7398723SShteryana Shopova TOK_BITS, /* bits token (kind of a type) */
275a7398723SShteryana Shopova TOK_ERR /* unexpected char - exit */
276a7398723SShteryana Shopova };
277a7398723SShteryana Shopova
278a7398723SShteryana Shopova static const struct {
279a7398723SShteryana Shopova const char *str;
280a7398723SShteryana Shopova enum tok tok;
281a7398723SShteryana Shopova uint32_t val;
282a7398723SShteryana Shopova } keywords[] = {
283a7398723SShteryana Shopova { "GET", TOK_ACCESS, FL_GET },
284a7398723SShteryana Shopova { "SET", TOK_ACCESS, FL_SET },
285a7398723SShteryana Shopova { "NULL", TOK_TYPE, SNMP_SYNTAX_NULL },
286a7398723SShteryana Shopova { "INTEGER", TOK_TYPE, SNMP_SYNTAX_INTEGER },
287a7398723SShteryana Shopova { "INTEGER32", TOK_TYPE, SNMP_SYNTAX_INTEGER },
288a7398723SShteryana Shopova { "UNSIGNED32", TOK_TYPE, SNMP_SYNTAX_GAUGE },
289a7398723SShteryana Shopova { "OCTETSTRING", TOK_TYPE, SNMP_SYNTAX_OCTETSTRING },
290a7398723SShteryana Shopova { "IPADDRESS", TOK_TYPE, SNMP_SYNTAX_IPADDRESS },
291a7398723SShteryana Shopova { "OID", TOK_TYPE, SNMP_SYNTAX_OID },
292a7398723SShteryana Shopova { "TIMETICKS", TOK_TYPE, SNMP_SYNTAX_TIMETICKS },
293a7398723SShteryana Shopova { "COUNTER", TOK_TYPE, SNMP_SYNTAX_COUNTER },
294a7398723SShteryana Shopova { "GAUGE", TOK_TYPE, SNMP_SYNTAX_GAUGE },
295a7398723SShteryana Shopova { "COUNTER64", TOK_TYPE, SNMP_SYNTAX_COUNTER64 },
296a7398723SShteryana Shopova { "ENUM", TOK_ENUM, SNMP_SYNTAX_INTEGER },
297a7398723SShteryana Shopova { "BITS", TOK_BITS, SNMP_SYNTAX_OCTETSTRING },
298a7398723SShteryana Shopova { "typedef", TOK_TYPEDEF, 0 },
299a7398723SShteryana Shopova { "include", TOK_INCLUDE, 0 },
300a7398723SShteryana Shopova { NULL, 0, 0 }
301a7398723SShteryana Shopova };
302a7398723SShteryana Shopova
30329517fcaSEnji Cooper static struct {
304a7398723SShteryana Shopova /* Current OID type, regarding table membership. */
305a7398723SShteryana Shopova enum snmp_tbl_entry tbl_type;
306a7398723SShteryana Shopova /* A pointer to a structure in table list to add to its members. */
307a7398723SShteryana Shopova struct snmp_index_entry *table_idx;
308a7398723SShteryana Shopova } table_data;
309a7398723SShteryana Shopova
31029517fcaSEnji Cooper static struct asn_oid current_oid;
31129517fcaSEnji Cooper static char nexttok[MAXSTR];
31229517fcaSEnji Cooper static u_long val; /* integer values */
31329517fcaSEnji Cooper static int32_t all_cond; /* all conditions are true */
31429517fcaSEnji Cooper static int32_t saved_token = -1;
315a7398723SShteryana Shopova
316a7398723SShteryana Shopova /* Prepare the global data before parsing a new file. */
317a7398723SShteryana Shopova static void
snmp_import_init(struct asn_oid * append)318a7398723SShteryana Shopova snmp_import_init(struct asn_oid *append)
319a7398723SShteryana Shopova {
320a7398723SShteryana Shopova memset(&table_data, 0, sizeof(table_data));
321a7398723SShteryana Shopova memset(¤t_oid, 0, sizeof(struct asn_oid));
322a7398723SShteryana Shopova memset(nexttok, 0, MAXSTR);
323a7398723SShteryana Shopova
324a7398723SShteryana Shopova if (append != NULL)
325a7398723SShteryana Shopova asn_append_oid(¤t_oid, append);
326a7398723SShteryana Shopova
327a7398723SShteryana Shopova all_cond = 0;
328a7398723SShteryana Shopova val = 0;
329a7398723SShteryana Shopova saved_token = -1;
330a7398723SShteryana Shopova }
331a7398723SShteryana Shopova
332a7398723SShteryana Shopova static int32_t
gettoken(struct snmp_toolinfo * snmptoolctx)333a7398723SShteryana Shopova gettoken(struct snmp_toolinfo *snmptoolctx)
334a7398723SShteryana Shopova {
335a7398723SShteryana Shopova int c;
336a7398723SShteryana Shopova struct enum_type *t;
337a7398723SShteryana Shopova
338a7398723SShteryana Shopova if (saved_token != -1) {
339a7398723SShteryana Shopova c = saved_token;
340a7398723SShteryana Shopova saved_token = -1;
341a7398723SShteryana Shopova return (c);
342a7398723SShteryana Shopova }
343a7398723SShteryana Shopova
344a7398723SShteryana Shopova again:
345a7398723SShteryana Shopova /*
346a7398723SShteryana Shopova * Skip any whitespace before the next token.
347a7398723SShteryana Shopova */
348a7398723SShteryana Shopova while ((c = tgetc()) != EOF) {
349a7398723SShteryana Shopova if (c == '\n')
350a7398723SShteryana Shopova input->lno++;
351a7398723SShteryana Shopova if (!isspace(c))
352a7398723SShteryana Shopova break;
353a7398723SShteryana Shopova }
354a7398723SShteryana Shopova if (c == EOF)
355a7398723SShteryana Shopova return (TOK_EOF);
356a7398723SShteryana Shopova
357a7398723SShteryana Shopova if (!isascii(c)) {
358a7398723SShteryana Shopova warnx("unexpected character %#2x", (u_int) c);
359a7398723SShteryana Shopova return (TOK_ERR);
360a7398723SShteryana Shopova }
361a7398723SShteryana Shopova
362a7398723SShteryana Shopova /*
363a7398723SShteryana Shopova * Skip comments.
364a7398723SShteryana Shopova */
365a7398723SShteryana Shopova if (c == '#') {
366a7398723SShteryana Shopova while ((c = tgetc()) != EOF) {
367a7398723SShteryana Shopova if (c == '\n') {
368a7398723SShteryana Shopova input->lno++;
369a7398723SShteryana Shopova goto again;
370a7398723SShteryana Shopova }
371a7398723SShteryana Shopova }
372a7398723SShteryana Shopova warnx("unexpected EOF in comment");
373a7398723SShteryana Shopova return (TOK_ERR);
374a7398723SShteryana Shopova }
375a7398723SShteryana Shopova
376a7398723SShteryana Shopova /*
377a7398723SShteryana Shopova * Single character tokens.
378a7398723SShteryana Shopova */
379a7398723SShteryana Shopova if (strchr("():|", c) != NULL)
380a7398723SShteryana Shopova return (c);
381a7398723SShteryana Shopova
382a7398723SShteryana Shopova if (c == '"' || c == '<') {
383a7398723SShteryana Shopova int32_t end = c;
384a7398723SShteryana Shopova size_t n = 0;
385a7398723SShteryana Shopova
386a7398723SShteryana Shopova val = 1;
387a7398723SShteryana Shopova if (c == '<') {
388a7398723SShteryana Shopova val = 0;
389a7398723SShteryana Shopova end = '>';
390a7398723SShteryana Shopova }
391a7398723SShteryana Shopova
392a7398723SShteryana Shopova while ((c = tgetc()) != EOF) {
393a7398723SShteryana Shopova if (c == end)
394a7398723SShteryana Shopova break;
395a7398723SShteryana Shopova if (n == sizeof(nexttok) - 1) {
396a7398723SShteryana Shopova nexttok[n++] = '\0';
397a7398723SShteryana Shopova warnx("filename too long '%s...'", nexttok);
398a7398723SShteryana Shopova return (TOK_ERR);
399a7398723SShteryana Shopova }
400a7398723SShteryana Shopova nexttok[n++] = c;
401a7398723SShteryana Shopova }
402a7398723SShteryana Shopova nexttok[n++] = '\0';
403a7398723SShteryana Shopova return (TOK_FILENAME);
404a7398723SShteryana Shopova }
405a7398723SShteryana Shopova
406a7398723SShteryana Shopova /*
407a7398723SShteryana Shopova * Sort out numbers.
408a7398723SShteryana Shopova */
409a7398723SShteryana Shopova if (isdigit(c)) {
410a7398723SShteryana Shopova size_t n = 0;
411a7398723SShteryana Shopova nexttok[n++] = c;
412a7398723SShteryana Shopova while ((c = tgetc()) != EOF) {
413a7398723SShteryana Shopova if (!isdigit(c)) {
414a7398723SShteryana Shopova if (tungetc(c) < 0)
415a7398723SShteryana Shopova return (TOK_ERR);
416a7398723SShteryana Shopova break;
417a7398723SShteryana Shopova }
418a7398723SShteryana Shopova if (n == sizeof(nexttok) - 1) {
419a7398723SShteryana Shopova nexttok[n++] = '\0';
420a7398723SShteryana Shopova warnx("number too long '%s...'", nexttok);
421a7398723SShteryana Shopova return (TOK_ERR);
422a7398723SShteryana Shopova }
423a7398723SShteryana Shopova nexttok[n++] = c;
424a7398723SShteryana Shopova }
425a7398723SShteryana Shopova nexttok[n++] = '\0';
426a7398723SShteryana Shopova sscanf(nexttok, "%lu", &val);
427a7398723SShteryana Shopova return (TOK_NUM);
428a7398723SShteryana Shopova }
429a7398723SShteryana Shopova
430a7398723SShteryana Shopova /*
431a7398723SShteryana Shopova * So that has to be a string.
432a7398723SShteryana Shopova */
433a7398723SShteryana Shopova if (isalpha(c) || c == '_' || c == '-') {
434a7398723SShteryana Shopova size_t n = 0;
435a7398723SShteryana Shopova nexttok[n++] = c;
436a7398723SShteryana Shopova while ((c = tgetc()) != EOF) {
437a7398723SShteryana Shopova if (!isalnum(c) && c != '_' && c != '-') {
438a7398723SShteryana Shopova if (tungetc (c) < 0)
439a7398723SShteryana Shopova return (TOK_ERR);
440a7398723SShteryana Shopova break;
441a7398723SShteryana Shopova }
442a7398723SShteryana Shopova if (n == sizeof(nexttok) - 1) {
443a7398723SShteryana Shopova nexttok[n++] = '\0';
444a7398723SShteryana Shopova warnx("string too long '%s...'", nexttok);
445a7398723SShteryana Shopova return (TOK_ERR);
446a7398723SShteryana Shopova }
447a7398723SShteryana Shopova nexttok[n++] = c;
448a7398723SShteryana Shopova }
449a7398723SShteryana Shopova nexttok[n++] = '\0';
450a7398723SShteryana Shopova
451a7398723SShteryana Shopova /*
452a7398723SShteryana Shopova * Keywords.
453a7398723SShteryana Shopova */
454a7398723SShteryana Shopova for (c = 0; keywords[c].str != NULL; c++)
455a7398723SShteryana Shopova if (strcmp(keywords[c].str, nexttok) == 0) {
456a7398723SShteryana Shopova val = keywords[c].val;
457a7398723SShteryana Shopova return (keywords[c].tok);
458a7398723SShteryana Shopova }
459a7398723SShteryana Shopova
460a7398723SShteryana Shopova if ((t = snmp_enumtc_lookup(snmptoolctx, nexttok)) != NULL) {
461a7398723SShteryana Shopova val = t->syntax;
462a7398723SShteryana Shopova return (TOK_DEFTYPE);
463a7398723SShteryana Shopova }
464a7398723SShteryana Shopova
465a7398723SShteryana Shopova return (TOK_STR);
466a7398723SShteryana Shopova }
467a7398723SShteryana Shopova
468a7398723SShteryana Shopova if (isprint(c))
469a7398723SShteryana Shopova warnx("%u: unexpected character '%c'", input->lno, c);
470a7398723SShteryana Shopova else
471a7398723SShteryana Shopova warnx("%u: unexpected character 0x%02x", input->lno, (u_int) c);
472a7398723SShteryana Shopova
473a7398723SShteryana Shopova return (TOK_ERR);
474a7398723SShteryana Shopova }
475a7398723SShteryana Shopova
476a7398723SShteryana Shopova /*
477a7398723SShteryana Shopova * Update table information.
478a7398723SShteryana Shopova */
479a7398723SShteryana Shopova static struct snmp_index_entry *
snmp_import_update_table(enum snmp_tbl_entry te,struct snmp_index_entry * tbl)480a7398723SShteryana Shopova snmp_import_update_table(enum snmp_tbl_entry te, struct snmp_index_entry *tbl)
481a7398723SShteryana Shopova {
482a7398723SShteryana Shopova switch (te) {
483a7398723SShteryana Shopova case ENTRY_NONE:
484a7398723SShteryana Shopova if (table_data.tbl_type == ENTRY_NONE)
485a7398723SShteryana Shopova return (NULL);
486a7398723SShteryana Shopova if (table_data.tbl_type == ENTRY_INDEX)
487a7398723SShteryana Shopova table_data.table_idx = NULL;
488a7398723SShteryana Shopova table_data.tbl_type--;
489a7398723SShteryana Shopova return (NULL);
490a7398723SShteryana Shopova
491a7398723SShteryana Shopova case ENTRY_INDEX:
492a7398723SShteryana Shopova if (tbl == NULL)
493a7398723SShteryana Shopova warnx("No table_index to add!!!");
494a7398723SShteryana Shopova table_data.table_idx = tbl;
495a7398723SShteryana Shopova table_data.tbl_type = ENTRY_INDEX;
496a7398723SShteryana Shopova return (tbl);
497a7398723SShteryana Shopova
498a7398723SShteryana Shopova case ENTRY_DATA:
499a7398723SShteryana Shopova if (table_data.tbl_type == ENTRY_INDEX) {
500a7398723SShteryana Shopova table_data.tbl_type = ENTRY_DATA;
501a7398723SShteryana Shopova return (table_data.table_idx);
502a7398723SShteryana Shopova }
503a7398723SShteryana Shopova return (NULL);
504a7398723SShteryana Shopova
505a7398723SShteryana Shopova default:
506a7398723SShteryana Shopova /* NOTREACHED */
507a7398723SShteryana Shopova warnx("Unknown table entry type!!!");
508a7398723SShteryana Shopova break;
509a7398723SShteryana Shopova }
510a7398723SShteryana Shopova
511a7398723SShteryana Shopova return (NULL);
512a7398723SShteryana Shopova }
513a7398723SShteryana Shopova
514a7398723SShteryana Shopova static int32_t
parse_enum(struct snmp_toolinfo * snmptoolctx,int32_t * tok,struct enum_pairs * enums)5154a2b63d5SEnji Cooper parse_enum(struct snmp_toolinfo *snmptoolctx, int32_t *tok,
516a7398723SShteryana Shopova struct enum_pairs *enums)
517a7398723SShteryana Shopova {
518a7398723SShteryana Shopova while ((*tok = gettoken(snmptoolctx)) == TOK_STR) {
519a7398723SShteryana Shopova if (enum_pair_insert(enums, val, nexttok) < 0)
520a7398723SShteryana Shopova return (-1);
521a7398723SShteryana Shopova if ((*tok = gettoken(snmptoolctx)) != TOK_NUM)
522a7398723SShteryana Shopova break;
523a7398723SShteryana Shopova }
524a7398723SShteryana Shopova
525a7398723SShteryana Shopova if (*tok != ')') {
526a7398723SShteryana Shopova warnx("')' at end of enums");
527a7398723SShteryana Shopova return (-1);
528a7398723SShteryana Shopova }
529a7398723SShteryana Shopova
530a7398723SShteryana Shopova return (1);
531a7398723SShteryana Shopova }
532a7398723SShteryana Shopova
533a7398723SShteryana Shopova static int32_t
parse_subtype(struct snmp_toolinfo * snmptoolctx,int32_t * tok,enum snmp_tc * tc)5344a2b63d5SEnji Cooper parse_subtype(struct snmp_toolinfo *snmptoolctx, int32_t *tok,
535a7398723SShteryana Shopova enum snmp_tc *tc)
536a7398723SShteryana Shopova {
537a7398723SShteryana Shopova if ((*tok = gettoken(snmptoolctx)) != TOK_STR) {
538a7398723SShteryana Shopova warnx("subtype expected after '|'");
539a7398723SShteryana Shopova return (-1);
540a7398723SShteryana Shopova }
541a7398723SShteryana Shopova
542a7398723SShteryana Shopova *tc = snmp_get_tc(nexttok);
543a7398723SShteryana Shopova *tok = gettoken(snmptoolctx);
544a7398723SShteryana Shopova
545a7398723SShteryana Shopova return (1);
546a7398723SShteryana Shopova }
547a7398723SShteryana Shopova
548a7398723SShteryana Shopova static int32_t
parse_type(struct snmp_toolinfo * snmptoolctx,int32_t * tok,enum snmp_tc * tc,struct enum_pairs ** snmp_enum)5494a2b63d5SEnji Cooper parse_type(struct snmp_toolinfo *snmptoolctx, int32_t *tok,
550a7398723SShteryana Shopova enum snmp_tc *tc, struct enum_pairs **snmp_enum)
551a7398723SShteryana Shopova {
552a7398723SShteryana Shopova int32_t syntax, mem;
553a7398723SShteryana Shopova
554a7398723SShteryana Shopova syntax = val;
555a7398723SShteryana Shopova *tc = 0;
556a7398723SShteryana Shopova
557a7398723SShteryana Shopova if (*tok == TOK_ENUM || *tok == TOK_BITS) {
558a7398723SShteryana Shopova if (*snmp_enum == NULL) {
559a7398723SShteryana Shopova if ((*snmp_enum = enum_pairs_init()) == NULL)
560a7398723SShteryana Shopova return (-1);
561a7398723SShteryana Shopova mem = 1;
562a7398723SShteryana Shopova *tc = SNMP_TC_OWN;
563a7398723SShteryana Shopova } else
564a7398723SShteryana Shopova mem = 0;
565a7398723SShteryana Shopova
566a7398723SShteryana Shopova if (gettoken(snmptoolctx) != '(') {
567a7398723SShteryana Shopova warnx("'(' expected after ENUM/BITS");
568a7398723SShteryana Shopova return (-1);
569a7398723SShteryana Shopova }
570a7398723SShteryana Shopova
571a7398723SShteryana Shopova if ((*tok = gettoken(snmptoolctx)) != TOK_NUM) {
572a7398723SShteryana Shopova warnx("need value for ENUM//BITS");
573a7398723SShteryana Shopova if (mem == 1) {
574a7398723SShteryana Shopova free(*snmp_enum);
575a7398723SShteryana Shopova *snmp_enum = NULL;
576a7398723SShteryana Shopova }
577a7398723SShteryana Shopova return (-1);
578a7398723SShteryana Shopova }
579a7398723SShteryana Shopova
580a7398723SShteryana Shopova if (parse_enum(snmptoolctx, tok, *snmp_enum) < 0) {
581a7398723SShteryana Shopova enum_pairs_free(*snmp_enum);
582a7398723SShteryana Shopova *snmp_enum = NULL;
583a7398723SShteryana Shopova return (-1);
584a7398723SShteryana Shopova }
585a7398723SShteryana Shopova
586a7398723SShteryana Shopova *tok = gettoken(snmptoolctx);
587a7398723SShteryana Shopova
588a7398723SShteryana Shopova } else if (*tok == TOK_DEFTYPE) {
589a7398723SShteryana Shopova struct enum_type *t;
590a7398723SShteryana Shopova
591a7398723SShteryana Shopova *tc = 0;
592a7398723SShteryana Shopova t = snmp_enumtc_lookup(snmptoolctx, nexttok);
593a7398723SShteryana Shopova if (t != NULL)
594a7398723SShteryana Shopova *snmp_enum = t->snmp_enum;
595a7398723SShteryana Shopova
596a7398723SShteryana Shopova *tok = gettoken(snmptoolctx);
597a7398723SShteryana Shopova
598a7398723SShteryana Shopova } else {
599a7398723SShteryana Shopova if ((*tok = gettoken(snmptoolctx)) == '|') {
600a7398723SShteryana Shopova if (parse_subtype(snmptoolctx, tok, tc) < 0)
601a7398723SShteryana Shopova return (-1);
602a7398723SShteryana Shopova }
603a7398723SShteryana Shopova }
604a7398723SShteryana Shopova
605a7398723SShteryana Shopova return (syntax);
606a7398723SShteryana Shopova }
607a7398723SShteryana Shopova
608a7398723SShteryana Shopova static int32_t
snmp_import_head(struct snmp_toolinfo * snmptoolctx)609a7398723SShteryana Shopova snmp_import_head(struct snmp_toolinfo *snmptoolctx)
610a7398723SShteryana Shopova {
611a7398723SShteryana Shopova enum tok tok;
612a7398723SShteryana Shopova
613a7398723SShteryana Shopova if ((tok = gettoken(snmptoolctx)) == '(')
614a7398723SShteryana Shopova tok = gettoken(snmptoolctx);
615a7398723SShteryana Shopova
616a7398723SShteryana Shopova if (tok != TOK_NUM || val > ASN_MAXID ) {
617a7398723SShteryana Shopova warnx("Suboid expected - line %d", input->lno);
618a7398723SShteryana Shopova return (-1);
619a7398723SShteryana Shopova }
620a7398723SShteryana Shopova
621a7398723SShteryana Shopova if (gettoken(snmptoolctx) != TOK_STR) {
622a7398723SShteryana Shopova warnx("Node name expected at line %d", input->lno);
623a7398723SShteryana Shopova return (-1);
624a7398723SShteryana Shopova }
625a7398723SShteryana Shopova
626a7398723SShteryana Shopova return (1);
627a7398723SShteryana Shopova }
628a7398723SShteryana Shopova
629a7398723SShteryana Shopova static int32_t
snmp_import_table(struct snmp_toolinfo * snmptoolctx,struct snmp_oid2str * obj)630a7398723SShteryana Shopova snmp_import_table(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *obj)
631a7398723SShteryana Shopova {
6324a2b63d5SEnji Cooper int32_t i, tok;
633a7398723SShteryana Shopova enum snmp_tc tc;
634a7398723SShteryana Shopova struct snmp_index_entry *entry;
635a7398723SShteryana Shopova
63666987347SEnji Cooper if ((entry = calloc(1, sizeof(struct snmp_index_entry))) == NULL) {
637a7398723SShteryana Shopova syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
638a7398723SShteryana Shopova return (-1);
639a7398723SShteryana Shopova }
640a7398723SShteryana Shopova
641a7398723SShteryana Shopova STAILQ_INIT(&(entry->index_list));
642a7398723SShteryana Shopova
643a7398723SShteryana Shopova for (i = 0, tok = gettoken(snmptoolctx); i < SNMP_INDEXES_MAX; i++) {
644a7398723SShteryana Shopova int32_t syntax;
645a7398723SShteryana Shopova struct enum_pairs *enums = NULL;
646a7398723SShteryana Shopova
647a7398723SShteryana Shopova if (tok != TOK_TYPE && tok != TOK_DEFTYPE && tok != TOK_ENUM &&
648a7398723SShteryana Shopova tok != TOK_BITS)
649a7398723SShteryana Shopova break;
650a7398723SShteryana Shopova
651a7398723SShteryana Shopova if ((syntax = parse_type(snmptoolctx, &tok, &tc, &enums)) < 0) {
652a7398723SShteryana Shopova enum_pairs_free(enums);
653a7398723SShteryana Shopova snmp_index_listfree(&(entry->index_list));
654a7398723SShteryana Shopova free(entry);
655a7398723SShteryana Shopova return (-1);
656a7398723SShteryana Shopova }
657a7398723SShteryana Shopova
658a7398723SShteryana Shopova if (snmp_syntax_insert(&(entry->index_list), enums, syntax,
659a7398723SShteryana Shopova tc) < 0) {
660a7398723SShteryana Shopova snmp_index_listfree(&(entry->index_list));
661a7398723SShteryana Shopova enum_pairs_free(enums);
662a7398723SShteryana Shopova free(entry);
663a7398723SShteryana Shopova return (-1);
664a7398723SShteryana Shopova }
665a7398723SShteryana Shopova }
666a7398723SShteryana Shopova
667a7398723SShteryana Shopova if (i == 0 || i > SNMP_INDEXES_MAX) {
668a7398723SShteryana Shopova warnx("Bad number of indexes at line %d", input->lno);
669a7398723SShteryana Shopova snmp_index_listfree(&(entry->index_list));
670a7398723SShteryana Shopova free(entry);
671a7398723SShteryana Shopova return (-1);
672a7398723SShteryana Shopova }
673a7398723SShteryana Shopova
674a7398723SShteryana Shopova if (tok != TOK_STR) {
675a7398723SShteryana Shopova warnx("String expected after indexes at line %d", input->lno);
676a7398723SShteryana Shopova snmp_index_listfree(&(entry->index_list));
677a7398723SShteryana Shopova free(entry);
678a7398723SShteryana Shopova return (-1);
679a7398723SShteryana Shopova }
680a7398723SShteryana Shopova
681a7398723SShteryana Shopova entry->string = obj->string;
682a7398723SShteryana Shopova entry->strlen = obj->strlen;
683a7398723SShteryana Shopova asn_append_oid(&(entry->var), &(obj->var));
684a7398723SShteryana Shopova
685a7398723SShteryana Shopova if ((i = snmp_table_insert(snmptoolctx, entry)) < 0) {
686a7398723SShteryana Shopova snmp_index_listfree(&(entry->index_list));
687a7398723SShteryana Shopova free(entry);
688a7398723SShteryana Shopova return (-1);
689a7398723SShteryana Shopova } else if (i == 0) {
690a7398723SShteryana Shopova /* Same entry already present in lists. */
691a7398723SShteryana Shopova free(entry->string);
692a7398723SShteryana Shopova free(entry);
69381b38680SEnji Cooper return (0);
694a7398723SShteryana Shopova }
695a7398723SShteryana Shopova
696a7398723SShteryana Shopova (void) snmp_import_update_table(ENTRY_INDEX, entry);
697a7398723SShteryana Shopova
698a7398723SShteryana Shopova return (1);
699a7398723SShteryana Shopova }
700a7398723SShteryana Shopova
701a7398723SShteryana Shopova /*
702a7398723SShteryana Shopova * Read everything after the syntax type that is certainly a leaf OID info.
703a7398723SShteryana Shopova */
704a7398723SShteryana Shopova static int32_t
snmp_import_leaf(struct snmp_toolinfo * snmptoolctx,int32_t * tok,struct snmp_oid2str * oid2str)7054a2b63d5SEnji Cooper snmp_import_leaf(struct snmp_toolinfo *snmptoolctx, int32_t *tok,
706a7398723SShteryana Shopova struct snmp_oid2str *oid2str)
707a7398723SShteryana Shopova {
708a7398723SShteryana Shopova int32_t i, syntax;
709a7398723SShteryana Shopova
710a7398723SShteryana Shopova if ((syntax = parse_type(snmptoolctx, tok, &(oid2str->tc), &(oid2str->snmp_enum)))
711a7398723SShteryana Shopova < 0)
712a7398723SShteryana Shopova return(-1);
713a7398723SShteryana Shopova
714a7398723SShteryana Shopova oid2str->syntax = syntax;
715a7398723SShteryana Shopova /*
716a7398723SShteryana Shopova * That is the name of the function, corresponding to the entry.
717a7398723SShteryana Shopova * It is used by bsnmpd, but is not interesting for us.
718a7398723SShteryana Shopova */
719a7398723SShteryana Shopova if (*tok == TOK_STR)
720a7398723SShteryana Shopova *tok = gettoken(snmptoolctx);
721a7398723SShteryana Shopova
722a7398723SShteryana Shopova for (i = 0; i < SNMP_ACCESS_GETSET && *tok == TOK_ACCESS; i++) {
723a7398723SShteryana Shopova oid2str->access |= (uint32_t) val;
724a7398723SShteryana Shopova *tok = gettoken(snmptoolctx);
725a7398723SShteryana Shopova }
726a7398723SShteryana Shopova
727a7398723SShteryana Shopova if (*tok != ')') {
728a7398723SShteryana Shopova warnx("')' expected at end of line %d", input->lno);
729a7398723SShteryana Shopova return (-1);
730a7398723SShteryana Shopova }
731a7398723SShteryana Shopova
732a7398723SShteryana Shopova oid2str->table_idx = snmp_import_update_table(ENTRY_DATA, NULL);
733a7398723SShteryana Shopova
734a7398723SShteryana Shopova if ((i = snmp_leaf_insert(snmptoolctx, oid2str)) < 0) {
735a7398723SShteryana Shopova warnx("Error adding leaf %s to list", oid2str->string);
736a7398723SShteryana Shopova return (-1);
737a7398723SShteryana Shopova }
738a7398723SShteryana Shopova
739a7398723SShteryana Shopova /*
740a7398723SShteryana Shopova * Same entry is already present in the mapping lists and
741a7398723SShteryana Shopova * the new one was not inserted.
742a7398723SShteryana Shopova */
743a7398723SShteryana Shopova if (i == 0) {
744a7398723SShteryana Shopova free(oid2str->string);
745a7398723SShteryana Shopova free(oid2str);
746a7398723SShteryana Shopova }
747a7398723SShteryana Shopova
748a7398723SShteryana Shopova (void) snmp_import_update_table(ENTRY_NONE, NULL);
749a7398723SShteryana Shopova
750a7398723SShteryana Shopova return (1);
751a7398723SShteryana Shopova }
752a7398723SShteryana Shopova
753a7398723SShteryana Shopova static int32_t
snmp_import_object(struct snmp_toolinfo * snmptoolctx)754a7398723SShteryana Shopova snmp_import_object(struct snmp_toolinfo *snmptoolctx)
755a7398723SShteryana Shopova {
756a7398723SShteryana Shopova char *string;
757a7398723SShteryana Shopova int i;
7584a2b63d5SEnji Cooper int32_t tok;
759a7398723SShteryana Shopova struct snmp_oid2str *oid2str;
760a7398723SShteryana Shopova
761a7398723SShteryana Shopova if (snmp_import_head(snmptoolctx) < 0)
762a7398723SShteryana Shopova return (-1);
763a7398723SShteryana Shopova
76466987347SEnji Cooper if ((oid2str = calloc(1, sizeof(struct snmp_oid2str))) == NULL) {
76527c7c238SEnji Cooper syslog(LOG_ERR, "calloc() failed: %s", strerror(errno));
766a7398723SShteryana Shopova return (-1);
767a7398723SShteryana Shopova }
768a7398723SShteryana Shopova
76927c7c238SEnji Cooper if ((string = strdup(nexttok)) == NULL) {
77027c7c238SEnji Cooper syslog(LOG_ERR, "strdup() failed: %s", strerror(errno));
771a7398723SShteryana Shopova free(oid2str);
772a7398723SShteryana Shopova return (-1);
773a7398723SShteryana Shopova }
774a7398723SShteryana Shopova
775a7398723SShteryana Shopova oid2str->string = string;
776a7398723SShteryana Shopova oid2str->strlen = strlen(nexttok);
777a7398723SShteryana Shopova
778a7398723SShteryana Shopova asn_append_oid(&(oid2str->var), &(current_oid));
779a7398723SShteryana Shopova if (snmp_suboid_append(&(oid2str->var), (asn_subid_t) val) < 0)
780a7398723SShteryana Shopova goto error;
781a7398723SShteryana Shopova
782a7398723SShteryana Shopova /*
783a7398723SShteryana Shopova * Prepared the entry - now figure out where to insert it.
784a7398723SShteryana Shopova * After the object we have following options:
785a7398723SShteryana Shopova * 1) new line, blank, ) - then it is an enum oid -> snmp_enumlist;
786a7398723SShteryana Shopova * 2) new line , ( - nonleaf oid -> snmp_nodelist;
787a7398723SShteryana Shopova * 2) ':' - table entry - a variable length SYNTAX_TYPE (one or more)
788a7398723SShteryana Shopova * may follow and second string must end line -> snmp_tablelist;
789a7398723SShteryana Shopova * 3) OID , string ) - this is a trap entry or a leaf -> snmp_oidlist;
790a7398723SShteryana Shopova * 4) SYNTAX_TYPE, string (not always), get/set modifier - always last
791a7398723SShteryana Shopova * and )- this is definitely a leaf.
792a7398723SShteryana Shopova */
793a7398723SShteryana Shopova
794a7398723SShteryana Shopova switch (tok = gettoken(snmptoolctx)) {
795a7398723SShteryana Shopova case ')':
796a7398723SShteryana Shopova if ((i = snmp_enum_insert(snmptoolctx, oid2str)) < 0)
797a7398723SShteryana Shopova goto error;
798a7398723SShteryana Shopova if (i == 0) {
799a7398723SShteryana Shopova free(oid2str->string);
800a7398723SShteryana Shopova free(oid2str);
801a7398723SShteryana Shopova }
802a7398723SShteryana Shopova return (1);
803a7398723SShteryana Shopova
804a7398723SShteryana Shopova case '(':
805a7398723SShteryana Shopova if (snmp_suboid_append(¤t_oid, (asn_subid_t) val) < 0)
806a7398723SShteryana Shopova goto error;
807a7398723SShteryana Shopova
808a7398723SShteryana Shopova /*
809a7398723SShteryana Shopova * Ignore the error for nodes since the .def files currently
810a7398723SShteryana Shopova * contain different strings for 1.3.6.1.2.1 - mibII. Only make
811a7398723SShteryana Shopova * sure the memory is freed and don't complain.
812a7398723SShteryana Shopova */
813a7398723SShteryana Shopova if ((i = snmp_node_insert(snmptoolctx, oid2str)) <= 0) {
814a7398723SShteryana Shopova free(string);
815a7398723SShteryana Shopova free(oid2str);
816a7398723SShteryana Shopova }
817a7398723SShteryana Shopova return (snmp_import_object(snmptoolctx));
818a7398723SShteryana Shopova
819a7398723SShteryana Shopova case ':':
820a7398723SShteryana Shopova if (snmp_suboid_append(¤t_oid, (asn_subid_t) val) < 0)
821a7398723SShteryana Shopova goto error;
822a7398723SShteryana Shopova if (snmp_import_table(snmptoolctx, oid2str) < 0)
823a7398723SShteryana Shopova goto error;
824a7398723SShteryana Shopova /*
825a7398723SShteryana Shopova * A different table entry type was malloced and the data is
826a7398723SShteryana Shopova * contained there.
827a7398723SShteryana Shopova */
828a7398723SShteryana Shopova free(oid2str);
829a7398723SShteryana Shopova return (1);
830a7398723SShteryana Shopova
831a7398723SShteryana Shopova case TOK_TYPE:
832a7398723SShteryana Shopova /* FALLTHROUGH */
833a7398723SShteryana Shopova case TOK_DEFTYPE:
834a7398723SShteryana Shopova /* FALLTHROUGH */
835a7398723SShteryana Shopova case TOK_ENUM:
836a7398723SShteryana Shopova /* FALLTHROUGH */
837a7398723SShteryana Shopova case TOK_BITS:
838a7398723SShteryana Shopova if (snmp_import_leaf(snmptoolctx, &tok, oid2str) < 0)
839a7398723SShteryana Shopova goto error;
840a7398723SShteryana Shopova return (1);
841a7398723SShteryana Shopova
842a7398723SShteryana Shopova default:
843a7398723SShteryana Shopova warnx("Unexpected token at line %d - %s", input->lno,
844a7398723SShteryana Shopova input->fname);
845a7398723SShteryana Shopova break;
846a7398723SShteryana Shopova }
847a7398723SShteryana Shopova
848a7398723SShteryana Shopova error:
849a7398723SShteryana Shopova snmp_mapping_entryfree(oid2str);
850a7398723SShteryana Shopova
851a7398723SShteryana Shopova return (-1);
852a7398723SShteryana Shopova }
853a7398723SShteryana Shopova
854a7398723SShteryana Shopova static int32_t
snmp_import_tree(struct snmp_toolinfo * snmptoolctx,int32_t * tok)8554a2b63d5SEnji Cooper snmp_import_tree(struct snmp_toolinfo *snmptoolctx, int32_t *tok)
856a7398723SShteryana Shopova {
857a7398723SShteryana Shopova while (*tok != TOK_EOF) {
858a7398723SShteryana Shopova switch (*tok) {
859a7398723SShteryana Shopova case TOK_ERR:
860a7398723SShteryana Shopova return (-1);
861a7398723SShteryana Shopova case '(':
862a7398723SShteryana Shopova if (snmp_import_object(snmptoolctx) < 0)
863a7398723SShteryana Shopova return (-1);
864a7398723SShteryana Shopova break;
865a7398723SShteryana Shopova case ')':
866a7398723SShteryana Shopova if (snmp_suboid_pop(¤t_oid) < 0)
867a7398723SShteryana Shopova return (-1);
868a7398723SShteryana Shopova (void) snmp_import_update_table(ENTRY_NONE, NULL);
869a7398723SShteryana Shopova break;
870a7398723SShteryana Shopova default:
871a7398723SShteryana Shopova /* Anything else here would be illegal. */
872a7398723SShteryana Shopova return (-1);
873a7398723SShteryana Shopova }
874a7398723SShteryana Shopova *tok = gettoken(snmptoolctx);
875a7398723SShteryana Shopova }
876a7398723SShteryana Shopova
877a7398723SShteryana Shopova return (0);
878a7398723SShteryana Shopova }
879a7398723SShteryana Shopova
880a7398723SShteryana Shopova static int32_t
snmp_import_top(struct snmp_toolinfo * snmptoolctx,int32_t * tok)8814a2b63d5SEnji Cooper snmp_import_top(struct snmp_toolinfo *snmptoolctx, int32_t *tok)
882a7398723SShteryana Shopova {
883a7398723SShteryana Shopova enum snmp_tc tc;
884a7398723SShteryana Shopova struct enum_type *t;
885a7398723SShteryana Shopova
886a7398723SShteryana Shopova if (*tok == '(')
887a7398723SShteryana Shopova return (snmp_import_tree(snmptoolctx, tok));
888a7398723SShteryana Shopova
889a7398723SShteryana Shopova if (*tok == TOK_TYPEDEF) {
890a7398723SShteryana Shopova if ((*tok = gettoken(snmptoolctx)) != TOK_STR) {
891a7398723SShteryana Shopova warnx("type name expected after typedef - %s",
892a7398723SShteryana Shopova input->fname);
893a7398723SShteryana Shopova return (-1);
894a7398723SShteryana Shopova }
895a7398723SShteryana Shopova
896a7398723SShteryana Shopova t = snmp_enumtc_init(nexttok);
897a7398723SShteryana Shopova
898a7398723SShteryana Shopova *tok = gettoken(snmptoolctx);
899a7398723SShteryana Shopova t->is_enum = (*tok == TOK_ENUM);
900a7398723SShteryana Shopova t->is_bits = (*tok == TOK_BITS);
901a7398723SShteryana Shopova t->syntax = parse_type(snmptoolctx, tok, &tc, &(t->snmp_enum));
902a7398723SShteryana Shopova snmp_enumtc_insert(snmptoolctx, t);
903a7398723SShteryana Shopova
904a7398723SShteryana Shopova return (1);
905a7398723SShteryana Shopova }
906a7398723SShteryana Shopova
907a7398723SShteryana Shopova if (*tok == TOK_INCLUDE) {
908a7398723SShteryana Shopova int i;
909a7398723SShteryana Shopova
910a7398723SShteryana Shopova *tok = gettoken(snmptoolctx);
911a7398723SShteryana Shopova if (*tok != TOK_FILENAME) {
912a7398723SShteryana Shopova warnx("filename expected in include directive - %s",
913a7398723SShteryana Shopova nexttok);
914a7398723SShteryana Shopova return (-1);
915a7398723SShteryana Shopova }
916a7398723SShteryana Shopova
917a7398723SShteryana Shopova if (( i = add_filename(snmptoolctx, nexttok, NULL, 1)) == 0) {
918a7398723SShteryana Shopova *tok = gettoken(snmptoolctx);
919a7398723SShteryana Shopova return (1);
920a7398723SShteryana Shopova }
921a7398723SShteryana Shopova
922a7398723SShteryana Shopova if (i == -1)
923a7398723SShteryana Shopova return (-1);
924a7398723SShteryana Shopova
925a7398723SShteryana Shopova input_fopen(nexttok);
926a7398723SShteryana Shopova *tok = gettoken(snmptoolctx);
927a7398723SShteryana Shopova return (1);
928a7398723SShteryana Shopova }
929a7398723SShteryana Shopova
930a7398723SShteryana Shopova warnx("'(' or 'typedef' expected - %s", nexttok);
931a7398723SShteryana Shopova return (-1);
932a7398723SShteryana Shopova }
933a7398723SShteryana Shopova
934a7398723SShteryana Shopova static int32_t
snmp_import(struct snmp_toolinfo * snmptoolctx)935a7398723SShteryana Shopova snmp_import(struct snmp_toolinfo *snmptoolctx)
936a7398723SShteryana Shopova {
937a7398723SShteryana Shopova int i;
9384a2b63d5SEnji Cooper int32_t tok;
939a7398723SShteryana Shopova
940a7398723SShteryana Shopova tok = gettoken(snmptoolctx);
941a7398723SShteryana Shopova
942a7398723SShteryana Shopova do
943a7398723SShteryana Shopova i = snmp_import_top(snmptoolctx, &tok);
944a7398723SShteryana Shopova while (i > 0);
945a7398723SShteryana Shopova
946a7398723SShteryana Shopova return (i);
947a7398723SShteryana Shopova }
948a7398723SShteryana Shopova
949a7398723SShteryana Shopova /*
950a7398723SShteryana Shopova * Read a .def file and import oid<->string mapping.
951a7398723SShteryana Shopova * Mappings are inserted into a global structure containing list for each OID
952a7398723SShteryana Shopova * syntax type.
953a7398723SShteryana Shopova */
954a7398723SShteryana Shopova int32_t
snmp_import_file(struct snmp_toolinfo * snmptoolctx,struct fname * file)955a7398723SShteryana Shopova snmp_import_file(struct snmp_toolinfo *snmptoolctx, struct fname *file)
956a7398723SShteryana Shopova {
957a7398723SShteryana Shopova int idx;
958a7398723SShteryana Shopova
959a7398723SShteryana Shopova snmp_import_init(&(file->cut));
960a7398723SShteryana Shopova input_fopen(file->name);
961a7398723SShteryana Shopova if ((idx = snmp_import(snmptoolctx)) < 0)
962a7398723SShteryana Shopova warnx("Failed to read mappings from file %s", file->name);
963a7398723SShteryana Shopova
964a7398723SShteryana Shopova input_close();
965a7398723SShteryana Shopova
966a7398723SShteryana Shopova return (idx);
967a7398723SShteryana Shopova }
968