1216295Ssyrinx/*-
2216295Ssyrinx * Copyright (c) 2006 The FreeBSD Project
3216295Ssyrinx * All rights reserved.
4216295Ssyrinx *
5216295Ssyrinx * Author: Shteryana Shopova <syrinx@FreeBSD.org>
6216295Ssyrinx *
7216295Ssyrinx * Redistribution of this software and documentation and use in source and
8216295Ssyrinx * binary forms, with or without modification, are permitted provided that
9216295Ssyrinx * the following conditions are met:
10216295Ssyrinx *
11216295Ssyrinx * 1. Redistributions of source code or documentation must retain the above
12216295Ssyrinx *    copyright notice, this list of conditions and the following disclaimer.
13216295Ssyrinx * 2. Redistributions in binary form must reproduce the above copyright
14216295Ssyrinx *    notice, this list of conditions and the following disclaimer in the
15216295Ssyrinx *    documentation and/or other materials provided with the distribution.
16216295Ssyrinx *
17216295Ssyrinx * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18216295Ssyrinx * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19216295Ssyrinx * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20216295Ssyrinx * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21216295Ssyrinx * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22216295Ssyrinx * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23216295Ssyrinx * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24216295Ssyrinx * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25216295Ssyrinx * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26216295Ssyrinx * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27216295Ssyrinx * SUCH DAMAGE.
28216295Ssyrinx *
29216295Ssyrinx * $FreeBSD$
30216295Ssyrinx */
31216295Ssyrinx
32216295Ssyrinx/*
33216295Ssyrinx * Read file containing table description - reuse magic from gensnmptree.c.
34216295Ssyrinx * Hopefully one day most of the code here will be part of libbsnmp and
35216295Ssyrinx * this duplication won't be necessary.
36216295Ssyrinx *
37216295Ssyrinx * Syntax is:
38216295Ssyrinx * ---------
39216295Ssyrinx * file := top | top file
40216295Ssyrinx *
41216295Ssyrinx * top := tree | typedef | include
42216295Ssyrinx *
43216295Ssyrinx * tree := head elements ')'
44216295Ssyrinx *
45216295Ssyrinx * entry := head ':' index STRING elements ')'
46216295Ssyrinx *
47216295Ssyrinx * leaf := head type STRING ACCESS ')'
48216295Ssyrinx *
49216295Ssyrinx * column := head type ACCESS ')'
50216295Ssyrinx *
51216295Ssyrinx * type := BASETYPE | BASETYPE '|' subtype | enum | bits
52216295Ssyrinx *
53216295Ssyrinx * subtype := STRING
54216295Ssyrinx *
55216295Ssyrinx * enum := ENUM '(' value ')'
56216295Ssyrinx *
57216295Ssyrinx * bits := BITS '(' value ')'
58216295Ssyrinx *
59216295Ssyrinx * value := INT STRING | INT STRING value
60216295Ssyrinx *
61216295Ssyrinx * head := '(' INT STRING
62216295Ssyrinx *
63216295Ssyrinx * elements := EMPTY | elements element
64216295Ssyrinx *
65216295Ssyrinx * element := tree | leaf | column
66216295Ssyrinx *
67216295Ssyrinx * index := type | index type
68216295Ssyrinx *
69216295Ssyrinx * typedef := 'typedef' STRING type
70216295Ssyrinx *
71216295Ssyrinx * include := 'include' filespec
72216295Ssyrinx *
73216295Ssyrinx * filespec := '"' STRING '"' | '<' STRING '>'
74216295Ssyrinx */
75216295Ssyrinx
76216295Ssyrinx#include <sys/param.h>
77216295Ssyrinx#include <sys/queue.h>
78216295Ssyrinx#include <sys/uio.h>
79216295Ssyrinx
80216295Ssyrinx#include <ctype.h>
81216295Ssyrinx#include <err.h>
82216295Ssyrinx#include <errno.h>
83216295Ssyrinx#include <fcntl.h>
84216295Ssyrinx#include <stdio.h>
85216295Ssyrinx#include <stdlib.h>
86216295Ssyrinx#include <string.h>
87216295Ssyrinx#include <syslog.h>
88216295Ssyrinx#include <unistd.h>
89216295Ssyrinx
90216295Ssyrinx#include <bsnmp/asn1.h>
91216295Ssyrinx#include <bsnmp/snmp.h>
92216295Ssyrinx#include <bsnmp/snmpagent.h>	/* SNMP_INDEXES_MAX */
93216295Ssyrinx#include "bsnmptc.h"
94216295Ssyrinx#include "bsnmptools.h"
95216295Ssyrinx
96216295Ssyrinxenum snmp_tbl_entry {
97216295Ssyrinx	ENTRY_NONE = 0,
98216295Ssyrinx	ENTRY_INDEX,
99216295Ssyrinx	ENTRY_DATA
100216295Ssyrinx};
101216295Ssyrinx
102216295Ssyrinxenum {
103216295Ssyrinx	FL_GET	= 0x01,
104216295Ssyrinx	FL_SET	= 0x02,
105216295Ssyrinx};
106216295Ssyrinx
107216295Ssyrinx/************************************************************
108216295Ssyrinx *
109216295Ssyrinx * Allocate memory and panic just in the case...
110216295Ssyrinx */
111216295Ssyrinxstatic void *
112216295Ssyrinxxalloc(size_t size)
113216295Ssyrinx{
114216295Ssyrinx	void *ptr;
115216295Ssyrinx
116216295Ssyrinx	if ((ptr = malloc(size)) == NULL)
117216295Ssyrinx		err(1, "allocing %zu bytes", size);
118216295Ssyrinx
119216295Ssyrinx	return (ptr);
120216295Ssyrinx}
121216295Ssyrinx
122216295Ssyrinxstatic char *
123216295Ssyrinxsavestr(const char *s)
124216295Ssyrinx{
125216295Ssyrinx	if (s == NULL)
126216295Ssyrinx		return (NULL);
127216295Ssyrinx
128216295Ssyrinx	return (strcpy(xalloc(strlen(s) + 1), s));
129216295Ssyrinx}
130216295Ssyrinx
131216295Ssyrinx/************************************************************
132216295Ssyrinx *
133216295Ssyrinx * Input stack
134216295Ssyrinx */
135216295Ssyrinxstruct input {
136216295Ssyrinx	FILE		*fp;
137216295Ssyrinx	uint32_t	lno;
138216295Ssyrinx	char		*fname;
139216295Ssyrinx	char		*path;
140216295Ssyrinx	LIST_ENTRY(input) link;
141216295Ssyrinx};
142216295Ssyrinx
143216295SsyrinxLIST_HEAD(, input) inputs = LIST_HEAD_INITIALIZER(inputs);
144216295Ssyrinxstruct input *input = NULL;
145216295Ssyrinxint32_t pbchar = -1;
146216295Ssyrinx
147216295Ssyrinx#define	MAX_PATHS	100
148216295Ssyrinx
149216295Ssyrinxstatic const char *paths[MAX_PATHS + 1] = {
150216295Ssyrinx	"/usr/share/snmp/defs",
151216295Ssyrinx	"/usr/local/share/snmp/defs",
152216295Ssyrinx	NULL
153216295Ssyrinx};
154216295Ssyrinx
155216295Ssyrinxstatic void
156216295Ssyrinxinput_new(FILE *fp, const char *path, const char *fname)
157216295Ssyrinx{
158216295Ssyrinx	struct input *ip;
159216295Ssyrinx
160216295Ssyrinx	ip = xalloc(sizeof(*ip));
161216295Ssyrinx	ip->fp = fp;
162216295Ssyrinx	ip->lno = 1;
163216295Ssyrinx	ip->fname = savestr(fname);
164216295Ssyrinx	ip->path = savestr(path);
165216295Ssyrinx	LIST_INSERT_HEAD(&inputs, ip, link);
166216295Ssyrinx
167216295Ssyrinx	input = ip;
168216295Ssyrinx}
169216295Ssyrinx
170216295Ssyrinxstatic void
171216295Ssyrinxinput_close(void)
172216295Ssyrinx{
173216295Ssyrinx	if (input == NULL)
174216295Ssyrinx		return;
175216295Ssyrinx
176216295Ssyrinx	fclose(input->fp);
177216295Ssyrinx	free(input->fname);
178216295Ssyrinx	free(input->path);
179216295Ssyrinx	LIST_REMOVE(input, link);
180216295Ssyrinx	free(input);
181216295Ssyrinx
182216295Ssyrinx	input = LIST_FIRST(&inputs);
183216295Ssyrinx}
184216295Ssyrinx
185216295Ssyrinxstatic FILE *
186216295Ssyrinxtryopen(const char *path, const char *fname)
187216295Ssyrinx{
188216295Ssyrinx	char *fn;
189216295Ssyrinx	FILE *fp;
190216295Ssyrinx
191216295Ssyrinx	if (path == NULL)
192216295Ssyrinx		fn = savestr(fname);
193216295Ssyrinx	else {
194216295Ssyrinx		fn = xalloc(strlen(path) + strlen(fname) + 2);
195216295Ssyrinx		sprintf(fn, "%s/%s", path, fname);
196216295Ssyrinx	}
197216295Ssyrinx	fp = fopen(fn, "r");
198216295Ssyrinx	free(fn);
199216295Ssyrinx	return (fp);
200216295Ssyrinx}
201216295Ssyrinx
202216295Ssyrinxstatic int32_t
203216295Ssyrinxinput_fopen(const char *fname)
204216295Ssyrinx{
205216295Ssyrinx	FILE *fp;
206216295Ssyrinx	u_int p;
207216295Ssyrinx
208216295Ssyrinx	if (fname[0] == '/' || fname[0] == '.' || fname[0] == '~') {
209216295Ssyrinx		if ((fp = tryopen(NULL, fname)) != NULL) {
210216295Ssyrinx			input_new(fp, NULL, fname);
211216295Ssyrinx			return (0);
212216295Ssyrinx		}
213216295Ssyrinx
214216295Ssyrinx	} else {
215216295Ssyrinx
216216295Ssyrinx		for (p = 0; paths[p] != NULL; p++)
217216295Ssyrinx			if ((fp = tryopen(paths[p], fname)) != NULL) {
218216295Ssyrinx				input_new(fp, paths[p], fname);
219216295Ssyrinx				return (0);
220216295Ssyrinx			}
221216295Ssyrinx	}
222216295Ssyrinx
223216295Ssyrinx	warnx("cannot open '%s'", fname);
224216295Ssyrinx	return (-1);
225216295Ssyrinx}
226216295Ssyrinx
227216295Ssyrinxstatic int32_t
228216295Ssyrinxtgetc(void)
229216295Ssyrinx{
230216295Ssyrinx	int c;
231216295Ssyrinx
232216295Ssyrinx	if (pbchar != -1) {
233216295Ssyrinx		c = pbchar;
234216295Ssyrinx		pbchar = -1;
235216295Ssyrinx		return (c);
236216295Ssyrinx	}
237216295Ssyrinx
238216295Ssyrinx	for (;;) {
239216295Ssyrinx		if (input == NULL)
240216295Ssyrinx			return (EOF);
241216295Ssyrinx
242216295Ssyrinx		if ((c = getc(input->fp)) != EOF)
243216295Ssyrinx			return (c);
244216295Ssyrinx
245216295Ssyrinx		input_close();
246216295Ssyrinx	}
247216295Ssyrinx}
248216295Ssyrinx
249216295Ssyrinxstatic int32_t
250216295Ssyrinxtungetc(int c)
251216295Ssyrinx{
252216295Ssyrinx
253216295Ssyrinx	if (pbchar != -1)
254216295Ssyrinx		return (-1);
255216295Ssyrinx
256216295Ssyrinx	pbchar = c;
257216295Ssyrinx	return (1);
258216295Ssyrinx}
259216295Ssyrinx
260216295Ssyrinx/************************************************************
261216295Ssyrinx *
262216295Ssyrinx * Parsing input
263216295Ssyrinx */
264216295Ssyrinxenum tok {
265216295Ssyrinx	TOK_EOF = 0200,	/* end-of-file seen */
266216295Ssyrinx	TOK_NUM,	/* number */
267216295Ssyrinx	TOK_STR,	/* string */
268216295Ssyrinx	TOK_ACCESS,	/* access operator */
269216295Ssyrinx	TOK_TYPE,	/* type operator */
270216295Ssyrinx	TOK_ENUM,	/* enum token (kind of a type) */
271216295Ssyrinx	TOK_TYPEDEF,	/* typedef directive */
272216295Ssyrinx	TOK_DEFTYPE,	/* defined type */
273216295Ssyrinx	TOK_INCLUDE,	/* include directive */
274216295Ssyrinx	TOK_FILENAME,	/* filename ("foo.bar" or <foo.bar>) */
275216295Ssyrinx	TOK_BITS,	/* bits token (kind of a type) */
276216295Ssyrinx	TOK_ERR		/* unexpected char - exit */
277216295Ssyrinx};
278216295Ssyrinx
279216295Ssyrinxstatic const struct {
280216295Ssyrinx	const char	*str;
281216295Ssyrinx	enum tok	tok;
282216295Ssyrinx	uint32_t	val;
283216295Ssyrinx} keywords[] = {
284216295Ssyrinx	{ "GET", TOK_ACCESS, FL_GET },
285216295Ssyrinx	{ "SET", TOK_ACCESS, FL_SET },
286216295Ssyrinx	{ "NULL", TOK_TYPE, SNMP_SYNTAX_NULL },
287216295Ssyrinx	{ "INTEGER", TOK_TYPE, SNMP_SYNTAX_INTEGER },
288216295Ssyrinx	{ "INTEGER32", TOK_TYPE, SNMP_SYNTAX_INTEGER },
289216295Ssyrinx	{ "UNSIGNED32", TOK_TYPE, SNMP_SYNTAX_GAUGE },
290216295Ssyrinx	{ "OCTETSTRING", TOK_TYPE, SNMP_SYNTAX_OCTETSTRING },
291216295Ssyrinx	{ "IPADDRESS", TOK_TYPE, SNMP_SYNTAX_IPADDRESS },
292216295Ssyrinx	{ "OID", TOK_TYPE, SNMP_SYNTAX_OID },
293216295Ssyrinx	{ "TIMETICKS", TOK_TYPE, SNMP_SYNTAX_TIMETICKS },
294216295Ssyrinx	{ "COUNTER", TOK_TYPE, SNMP_SYNTAX_COUNTER },
295216295Ssyrinx	{ "GAUGE", TOK_TYPE, SNMP_SYNTAX_GAUGE },
296216295Ssyrinx	{ "COUNTER64", TOK_TYPE, SNMP_SYNTAX_COUNTER64 },
297216295Ssyrinx	{ "ENUM", TOK_ENUM, SNMP_SYNTAX_INTEGER },
298216295Ssyrinx	{ "BITS", TOK_BITS, SNMP_SYNTAX_OCTETSTRING },
299216295Ssyrinx	{ "typedef", TOK_TYPEDEF, 0 },
300216295Ssyrinx	{ "include", TOK_INCLUDE, 0 },
301216295Ssyrinx	{ NULL, 0, 0 }
302216295Ssyrinx};
303216295Ssyrinx
304216295Ssyrinxstruct {
305216295Ssyrinx	/* Current OID type, regarding table membership. */
306216295Ssyrinx	enum snmp_tbl_entry	tbl_type;
307216295Ssyrinx	/* A pointer to a structure in table list to add to its members. */
308216295Ssyrinx	struct snmp_index_entry	*table_idx;
309216295Ssyrinx} table_data;
310216295Ssyrinx
311216295Ssyrinxstruct asn_oid current_oid;
312216295Ssyrinxchar nexttok[MAXSTR];
313216295Ssyrinxu_long val;		/* integer values */
314216295Ssyrinxint32_t	all_cond;	/* all conditions are true */
315216295Ssyrinxint32_t saved_token = -1;
316216295Ssyrinx
317216295Ssyrinx/* Prepare the global data before parsing a new file. */
318216295Ssyrinxstatic void
319216295Ssyrinxsnmp_import_init(struct asn_oid *append)
320216295Ssyrinx{
321216295Ssyrinx	memset(&table_data, 0, sizeof(table_data));
322216295Ssyrinx	memset(&current_oid, 0, sizeof(struct asn_oid));
323216295Ssyrinx	memset(nexttok, 0, MAXSTR);
324216295Ssyrinx
325216295Ssyrinx	if (append != NULL)
326216295Ssyrinx		asn_append_oid(&current_oid, append);
327216295Ssyrinx
328216295Ssyrinx	all_cond = 0;
329216295Ssyrinx	val = 0;
330216295Ssyrinx	saved_token = -1;
331216295Ssyrinx}
332216295Ssyrinx
333216295Ssyrinxstatic int32_t
334216295Ssyrinxgettoken(struct snmp_toolinfo *snmptoolctx)
335216295Ssyrinx{
336216295Ssyrinx	int c;
337216295Ssyrinx	struct enum_type *t;
338216295Ssyrinx
339216295Ssyrinx	if (saved_token != -1) {
340216295Ssyrinx		c = saved_token;
341216295Ssyrinx		saved_token = -1;
342216295Ssyrinx		return (c);
343216295Ssyrinx	}
344216295Ssyrinx
345216295Ssyrinx  again:
346216295Ssyrinx	/*
347216295Ssyrinx	 * Skip any whitespace before the next token.
348216295Ssyrinx	 */
349216295Ssyrinx	while ((c = tgetc()) != EOF) {
350216295Ssyrinx		if (c == '\n')
351216295Ssyrinx			input->lno++;
352216295Ssyrinx		if (!isspace(c))
353216295Ssyrinx			break;
354216295Ssyrinx	}
355216295Ssyrinx	if (c == EOF)
356216295Ssyrinx		return (TOK_EOF);
357216295Ssyrinx
358216295Ssyrinx	if (!isascii(c)) {
359216295Ssyrinx		warnx("unexpected character %#2x", (u_int) c);
360216295Ssyrinx		return (TOK_ERR);
361216295Ssyrinx	}
362216295Ssyrinx
363216295Ssyrinx	/*
364216295Ssyrinx	 * Skip comments.
365216295Ssyrinx	 */
366216295Ssyrinx	if (c == '#') {
367216295Ssyrinx		while ((c = tgetc()) != EOF) {
368216295Ssyrinx			if (c == '\n') {
369216295Ssyrinx				input->lno++;
370216295Ssyrinx				goto again;
371216295Ssyrinx			}
372216295Ssyrinx		}
373216295Ssyrinx		warnx("unexpected EOF in comment");
374216295Ssyrinx		return (TOK_ERR);
375216295Ssyrinx	}
376216295Ssyrinx
377216295Ssyrinx	/*
378216295Ssyrinx	 * Single character tokens.
379216295Ssyrinx	 */
380216295Ssyrinx	if (strchr("():|", c) != NULL)
381216295Ssyrinx		return (c);
382216295Ssyrinx
383216295Ssyrinx	if (c == '"' || c == '<') {
384216295Ssyrinx		int32_t end = c;
385216295Ssyrinx		size_t n = 0;
386216295Ssyrinx
387216295Ssyrinx		val = 1;
388216295Ssyrinx		if (c == '<') {
389216295Ssyrinx			val = 0;
390216295Ssyrinx			end = '>';
391216295Ssyrinx		}
392216295Ssyrinx
393216295Ssyrinx		while ((c = tgetc()) != EOF) {
394216295Ssyrinx			if (c == end)
395216295Ssyrinx				break;
396216295Ssyrinx			if (n == sizeof(nexttok) - 1) {
397216295Ssyrinx				nexttok[n++] = '\0';
398216295Ssyrinx				warnx("filename too long '%s...'", nexttok);
399216295Ssyrinx				return (TOK_ERR);
400216295Ssyrinx			}
401216295Ssyrinx			nexttok[n++] = c;
402216295Ssyrinx		}
403216295Ssyrinx		nexttok[n++] = '\0';
404216295Ssyrinx		return (TOK_FILENAME);
405216295Ssyrinx	}
406216295Ssyrinx
407216295Ssyrinx	/*
408216295Ssyrinx	 * Sort out numbers.
409216295Ssyrinx	 */
410216295Ssyrinx	if (isdigit(c)) {
411216295Ssyrinx		size_t n = 0;
412216295Ssyrinx		nexttok[n++] = c;
413216295Ssyrinx		while ((c = tgetc()) != EOF) {
414216295Ssyrinx			if (!isdigit(c)) {
415216295Ssyrinx				if (tungetc(c) < 0)
416216295Ssyrinx					return (TOK_ERR);
417216295Ssyrinx				break;
418216295Ssyrinx			}
419216295Ssyrinx			if (n == sizeof(nexttok) - 1) {
420216295Ssyrinx				nexttok[n++] = '\0';
421216295Ssyrinx				warnx("number too long '%s...'", nexttok);
422216295Ssyrinx				return (TOK_ERR);
423216295Ssyrinx			}
424216295Ssyrinx			nexttok[n++] = c;
425216295Ssyrinx		}
426216295Ssyrinx		nexttok[n++] = '\0';
427216295Ssyrinx		sscanf(nexttok, "%lu", &val);
428216295Ssyrinx		return (TOK_NUM);
429216295Ssyrinx	}
430216295Ssyrinx
431216295Ssyrinx	/*
432216295Ssyrinx	 * So that has to be a string.
433216295Ssyrinx	 */
434216295Ssyrinx	if (isalpha(c) || c == '_' || c == '-') {
435216295Ssyrinx		size_t n = 0;
436216295Ssyrinx		nexttok[n++] = c;
437216295Ssyrinx		while ((c = tgetc()) != EOF) {
438216295Ssyrinx			if (!isalnum(c) && c != '_' && c != '-') {
439216295Ssyrinx				if (tungetc (c) < 0)
440216295Ssyrinx					return (TOK_ERR);
441216295Ssyrinx				break;
442216295Ssyrinx			}
443216295Ssyrinx			if (n == sizeof(nexttok) - 1) {
444216295Ssyrinx				nexttok[n++] = '\0';
445216295Ssyrinx				warnx("string too long '%s...'", nexttok);
446216295Ssyrinx				return (TOK_ERR);
447216295Ssyrinx			}
448216295Ssyrinx			nexttok[n++] = c;
449216295Ssyrinx		}
450216295Ssyrinx		nexttok[n++] = '\0';
451216295Ssyrinx
452216295Ssyrinx		/*
453216295Ssyrinx		 * Keywords.
454216295Ssyrinx		 */
455216295Ssyrinx		for (c = 0; keywords[c].str != NULL; c++)
456216295Ssyrinx			if (strcmp(keywords[c].str, nexttok) == 0) {
457216295Ssyrinx				val = keywords[c].val;
458216295Ssyrinx				return (keywords[c].tok);
459216295Ssyrinx			}
460216295Ssyrinx
461216295Ssyrinx		if ((t = snmp_enumtc_lookup(snmptoolctx, nexttok)) != NULL) {
462216295Ssyrinx			val = t->syntax;
463216295Ssyrinx			return (TOK_DEFTYPE);
464216295Ssyrinx		}
465216295Ssyrinx
466216295Ssyrinx		return (TOK_STR);
467216295Ssyrinx	}
468216295Ssyrinx
469216295Ssyrinx	if (isprint(c))
470216295Ssyrinx		warnx("%u: unexpected character '%c'", input->lno, c);
471216295Ssyrinx	else
472216295Ssyrinx		warnx("%u: unexpected character 0x%02x", input->lno, (u_int) c);
473216295Ssyrinx
474216295Ssyrinx	return (TOK_ERR);
475216295Ssyrinx}
476216295Ssyrinx
477216295Ssyrinx/*
478216295Ssyrinx * Update table information.
479216295Ssyrinx */
480216295Ssyrinxstatic struct snmp_index_entry *
481216295Ssyrinxsnmp_import_update_table(enum snmp_tbl_entry te, struct snmp_index_entry *tbl)
482216295Ssyrinx{
483216295Ssyrinx	switch (te) {
484216295Ssyrinx		case ENTRY_NONE:
485216295Ssyrinx			if (table_data.tbl_type == ENTRY_NONE)
486216295Ssyrinx				return (NULL);
487216295Ssyrinx			if (table_data.tbl_type == ENTRY_INDEX)
488216295Ssyrinx				table_data.table_idx = NULL;
489216295Ssyrinx			table_data.tbl_type--;
490216295Ssyrinx			return (NULL);
491216295Ssyrinx
492216295Ssyrinx		case ENTRY_INDEX:
493216295Ssyrinx			if (tbl == NULL)
494216295Ssyrinx				warnx("No table_index to add!!!");
495216295Ssyrinx			table_data.table_idx = tbl;
496216295Ssyrinx			table_data.tbl_type = ENTRY_INDEX;
497216295Ssyrinx			return (tbl);
498216295Ssyrinx
499216295Ssyrinx		case ENTRY_DATA:
500216295Ssyrinx			if (table_data.tbl_type == ENTRY_INDEX) {
501216295Ssyrinx				table_data.tbl_type = ENTRY_DATA;
502216295Ssyrinx				return (table_data.table_idx);
503216295Ssyrinx			}
504216295Ssyrinx			return (NULL);
505216295Ssyrinx
506216295Ssyrinx		default:
507216295Ssyrinx			/* NOTREACHED */
508216295Ssyrinx			warnx("Unknown table entry type!!!");
509216295Ssyrinx			break;
510216295Ssyrinx	}
511216295Ssyrinx
512216295Ssyrinx	return (NULL);
513216295Ssyrinx}
514216295Ssyrinx
515216295Ssyrinxstatic int32_t
516216295Ssyrinxparse_enum(struct snmp_toolinfo *snmptoolctx, enum tok *tok,
517216295Ssyrinx    struct enum_pairs *enums)
518216295Ssyrinx{
519216295Ssyrinx	while ((*tok = gettoken(snmptoolctx)) == TOK_STR) {
520216295Ssyrinx		if (enum_pair_insert(enums, val, nexttok) < 0)
521216295Ssyrinx			return (-1);
522216295Ssyrinx		if ((*tok = gettoken(snmptoolctx)) != TOK_NUM)
523216295Ssyrinx			break;
524216295Ssyrinx	}
525216295Ssyrinx
526216295Ssyrinx	if (*tok != ')') {
527216295Ssyrinx		warnx("')' at end of enums");
528216295Ssyrinx		return (-1);
529216295Ssyrinx	}
530216295Ssyrinx
531216295Ssyrinx	return (1);
532216295Ssyrinx}
533216295Ssyrinx
534216295Ssyrinxstatic int32_t
535216295Ssyrinxparse_subtype(struct snmp_toolinfo *snmptoolctx, enum tok *tok,
536216295Ssyrinx    enum snmp_tc *tc)
537216295Ssyrinx{
538216295Ssyrinx	if ((*tok = gettoken(snmptoolctx)) != TOK_STR) {
539216295Ssyrinx		warnx("subtype expected after '|'");
540216295Ssyrinx		return (-1);
541216295Ssyrinx	}
542216295Ssyrinx
543216295Ssyrinx	*tc = snmp_get_tc(nexttok);
544216295Ssyrinx	*tok = gettoken(snmptoolctx);
545216295Ssyrinx
546216295Ssyrinx	return (1);
547216295Ssyrinx}
548216295Ssyrinx
549216295Ssyrinxstatic int32_t
550216295Ssyrinxparse_type(struct snmp_toolinfo *snmptoolctx, enum tok *tok,
551216295Ssyrinx    enum snmp_tc *tc, struct enum_pairs **snmp_enum)
552216295Ssyrinx{
553216295Ssyrinx	int32_t syntax, mem;
554216295Ssyrinx
555216295Ssyrinx	syntax = val;
556216295Ssyrinx	*tc = 0;
557216295Ssyrinx
558216295Ssyrinx	if (*tok == TOK_ENUM || *tok == TOK_BITS) {
559216295Ssyrinx		if (*snmp_enum == NULL) {
560216295Ssyrinx			if ((*snmp_enum = enum_pairs_init()) == NULL)
561216295Ssyrinx				return (-1);
562216295Ssyrinx			mem = 1;
563216295Ssyrinx			*tc = SNMP_TC_OWN;
564216295Ssyrinx		} else
565216295Ssyrinx			mem = 0;
566216295Ssyrinx
567216295Ssyrinx		if (gettoken(snmptoolctx) != '(') {
568216295Ssyrinx			warnx("'(' expected after ENUM/BITS");
569216295Ssyrinx			return (-1);
570216295Ssyrinx		}
571216295Ssyrinx
572216295Ssyrinx		if ((*tok = gettoken(snmptoolctx)) != TOK_NUM) {
573216295Ssyrinx			warnx("need value for ENUM//BITS");
574216295Ssyrinx			if (mem == 1) {
575216295Ssyrinx				free(*snmp_enum);
576216295Ssyrinx				*snmp_enum = NULL;
577216295Ssyrinx			}
578216295Ssyrinx			return (-1);
579216295Ssyrinx		}
580216295Ssyrinx
581216295Ssyrinx		if (parse_enum(snmptoolctx, tok, *snmp_enum) < 0) {
582216295Ssyrinx			enum_pairs_free(*snmp_enum);
583216295Ssyrinx			*snmp_enum = NULL;
584216295Ssyrinx			return (-1);
585216295Ssyrinx		}
586216295Ssyrinx
587216295Ssyrinx		*tok = gettoken(snmptoolctx);
588216295Ssyrinx
589216295Ssyrinx	} else if (*tok == TOK_DEFTYPE) {
590216295Ssyrinx		struct enum_type *t;
591216295Ssyrinx
592216295Ssyrinx		*tc = 0;
593216295Ssyrinx		t = snmp_enumtc_lookup(snmptoolctx, nexttok);
594216295Ssyrinx		if (t != NULL)
595216295Ssyrinx			*snmp_enum = t->snmp_enum;
596216295Ssyrinx
597216295Ssyrinx		*tok = gettoken(snmptoolctx);
598216295Ssyrinx
599216295Ssyrinx	} else {
600216295Ssyrinx		if ((*tok = gettoken(snmptoolctx)) == '|') {
601216295Ssyrinx			if (parse_subtype(snmptoolctx, tok, tc) < 0)
602216295Ssyrinx				return (-1);
603216295Ssyrinx		}
604216295Ssyrinx	}
605216295Ssyrinx
606216295Ssyrinx	return (syntax);
607216295Ssyrinx}
608216295Ssyrinx
609216295Ssyrinxstatic int32_t
610216295Ssyrinxsnmp_import_head(struct snmp_toolinfo *snmptoolctx)
611216295Ssyrinx{
612216295Ssyrinx	enum tok tok;
613216295Ssyrinx
614216295Ssyrinx	if ((tok = gettoken(snmptoolctx)) == '(')
615216295Ssyrinx		tok = gettoken(snmptoolctx);
616216295Ssyrinx
617216295Ssyrinx	if (tok != TOK_NUM  || val > ASN_MAXID ) {
618216295Ssyrinx		warnx("Suboid expected - line %d", input->lno);
619216295Ssyrinx		return (-1);
620216295Ssyrinx	}
621216295Ssyrinx
622216295Ssyrinx	if (gettoken(snmptoolctx) != TOK_STR) {
623216295Ssyrinx		warnx("Node name expected at line %d", input->lno);
624216295Ssyrinx		return (-1);
625216295Ssyrinx	}
626216295Ssyrinx
627216295Ssyrinx	return (1);
628216295Ssyrinx}
629216295Ssyrinx
630216295Ssyrinxstatic int32_t
631216295Ssyrinxsnmp_import_table(struct snmp_toolinfo *snmptoolctx, struct snmp_oid2str *obj)
632216295Ssyrinx{
633216295Ssyrinx	int32_t i;
634216295Ssyrinx	enum snmp_tc tc;
635216295Ssyrinx	enum tok tok;
636216295Ssyrinx	struct snmp_index_entry *entry;
637216295Ssyrinx
638216295Ssyrinx	if ((entry = malloc(sizeof(struct snmp_index_entry))) == NULL) {
639216295Ssyrinx		syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
640216295Ssyrinx		return (-1);
641216295Ssyrinx	}
642216295Ssyrinx
643216295Ssyrinx	memset(entry, 0, sizeof(struct snmp_index_entry));
644216295Ssyrinx	STAILQ_INIT(&(entry->index_list));
645216295Ssyrinx
646216295Ssyrinx	for (i = 0, tok = gettoken(snmptoolctx); i < SNMP_INDEXES_MAX; i++) {
647216295Ssyrinx		int32_t syntax;
648216295Ssyrinx		struct enum_pairs *enums = NULL;
649216295Ssyrinx
650216295Ssyrinx		if (tok != TOK_TYPE && tok != TOK_DEFTYPE && tok != TOK_ENUM &&
651216295Ssyrinx		    tok != TOK_BITS)
652216295Ssyrinx			break;
653216295Ssyrinx
654216295Ssyrinx		if ((syntax = parse_type(snmptoolctx, &tok, &tc, &enums)) < 0) {
655216295Ssyrinx			enum_pairs_free(enums);
656216295Ssyrinx			snmp_index_listfree(&(entry->index_list));
657216295Ssyrinx			free(entry);
658216295Ssyrinx			return (-1);
659216295Ssyrinx		}
660216295Ssyrinx
661216295Ssyrinx		if (snmp_syntax_insert(&(entry->index_list), enums, syntax,
662216295Ssyrinx		    tc) < 0) {
663216295Ssyrinx			snmp_index_listfree(&(entry->index_list));
664216295Ssyrinx			enum_pairs_free(enums);
665216295Ssyrinx			free(entry);
666216295Ssyrinx			return (-1);
667216295Ssyrinx		}
668216295Ssyrinx	}
669216295Ssyrinx
670216295Ssyrinx	if (i == 0 || i > SNMP_INDEXES_MAX) {
671216295Ssyrinx		warnx("Bad number of indexes at line %d", input->lno);
672216295Ssyrinx		snmp_index_listfree(&(entry->index_list));
673216295Ssyrinx		free(entry);
674216295Ssyrinx		return (-1);
675216295Ssyrinx	}
676216295Ssyrinx
677216295Ssyrinx	if (tok != TOK_STR) {
678216295Ssyrinx		warnx("String expected after indexes at line %d", input->lno);
679216295Ssyrinx		snmp_index_listfree(&(entry->index_list));
680216295Ssyrinx		free(entry);
681216295Ssyrinx		return (-1);
682216295Ssyrinx	}
683216295Ssyrinx
684216295Ssyrinx	entry->string = obj->string;
685216295Ssyrinx	entry->strlen = obj->strlen;
686216295Ssyrinx	asn_append_oid(&(entry->var), &(obj->var));
687216295Ssyrinx
688216295Ssyrinx	if ((i = snmp_table_insert(snmptoolctx, entry)) < 0) {
689216295Ssyrinx		snmp_index_listfree(&(entry->index_list));
690216295Ssyrinx		free(entry);
691216295Ssyrinx		return (-1);
692216295Ssyrinx	} else if (i == 0) {
693216295Ssyrinx		/* Same entry already present in lists. */
694216295Ssyrinx		free(entry->string);
695216295Ssyrinx		free(entry);
696216295Ssyrinx	}
697216295Ssyrinx
698216295Ssyrinx	(void) snmp_import_update_table(ENTRY_INDEX, entry);
699216295Ssyrinx
700216295Ssyrinx	return (1);
701216295Ssyrinx}
702216295Ssyrinx
703216295Ssyrinx/*
704216295Ssyrinx * Read everything after the syntax type that is certainly a leaf OID info.
705216295Ssyrinx */
706216295Ssyrinxstatic int32_t
707216295Ssyrinxsnmp_import_leaf(struct snmp_toolinfo *snmptoolctx, enum tok *tok,
708216295Ssyrinx    struct snmp_oid2str *oid2str)
709216295Ssyrinx{
710216295Ssyrinx	int32_t i, syntax;
711216295Ssyrinx
712216295Ssyrinx	if ((syntax = parse_type(snmptoolctx, tok, &(oid2str->tc), &(oid2str->snmp_enum)))
713216295Ssyrinx	    < 0)
714216295Ssyrinx		return(-1);
715216295Ssyrinx
716216295Ssyrinx	oid2str->syntax = syntax;
717216295Ssyrinx	/*
718216295Ssyrinx	 * That is the name of the function, corresponding to the entry.
719216295Ssyrinx	 * It is used by bsnmpd, but is not interesting for us.
720216295Ssyrinx	 */
721216295Ssyrinx	if (*tok == TOK_STR)
722216295Ssyrinx		*tok = gettoken(snmptoolctx);
723216295Ssyrinx
724216295Ssyrinx	for (i = 0; i < SNMP_ACCESS_GETSET && *tok == TOK_ACCESS; i++) {
725216295Ssyrinx		oid2str->access |=  (uint32_t) val;
726216295Ssyrinx		*tok = gettoken(snmptoolctx);
727216295Ssyrinx	}
728216295Ssyrinx
729216295Ssyrinx	if (*tok != ')') {
730216295Ssyrinx		warnx("')' expected at end of line %d", input->lno);
731216295Ssyrinx		return (-1);
732216295Ssyrinx	}
733216295Ssyrinx
734216295Ssyrinx	oid2str->table_idx = snmp_import_update_table(ENTRY_DATA,  NULL);
735216295Ssyrinx
736216295Ssyrinx	if ((i = snmp_leaf_insert(snmptoolctx, oid2str)) < 0) {
737216295Ssyrinx		warnx("Error adding leaf %s to list", oid2str->string);
738216295Ssyrinx		return (-1);
739216295Ssyrinx	}
740216295Ssyrinx
741216295Ssyrinx	/*
742216295Ssyrinx	 * Same entry is already present in the mapping lists and
743216295Ssyrinx	 * the new one was not inserted.
744216295Ssyrinx	 */
745216295Ssyrinx	if (i == 0)  {
746216295Ssyrinx		free(oid2str->string);
747216295Ssyrinx		free(oid2str);
748216295Ssyrinx	}
749216295Ssyrinx
750216295Ssyrinx	(void) snmp_import_update_table(ENTRY_NONE, NULL);
751216295Ssyrinx
752216295Ssyrinx	return (1);
753216295Ssyrinx}
754216295Ssyrinx
755216295Ssyrinxstatic int32_t
756216295Ssyrinxsnmp_import_object(struct snmp_toolinfo *snmptoolctx)
757216295Ssyrinx{
758216295Ssyrinx	char *string;
759216295Ssyrinx	int i;
760216295Ssyrinx	enum tok tok;
761216295Ssyrinx	struct snmp_oid2str *oid2str;
762216295Ssyrinx
763216295Ssyrinx	if (snmp_import_head(snmptoolctx) < 0)
764216295Ssyrinx		return (-1);
765216295Ssyrinx
766216295Ssyrinx	if ((oid2str = malloc(sizeof(struct snmp_oid2str))) == NULL) {
767216295Ssyrinx		syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
768216295Ssyrinx		return (-1);
769216295Ssyrinx	}
770216295Ssyrinx
771216295Ssyrinx	if ((string = malloc(strlen(nexttok) + 1)) == NULL) {
772216295Ssyrinx		syslog(LOG_ERR, "malloc() failed: %s", strerror(errno));
773216295Ssyrinx		free(oid2str);
774216295Ssyrinx		return (-1);
775216295Ssyrinx	}
776216295Ssyrinx
777216295Ssyrinx	memset(oid2str, 0, sizeof(struct snmp_oid2str));
778216295Ssyrinx	strlcpy(string, nexttok, strlen(nexttok) + 1);
779216295Ssyrinx	oid2str->string = string;
780216295Ssyrinx	oid2str->strlen = strlen(nexttok);
781216295Ssyrinx
782216295Ssyrinx	asn_append_oid(&(oid2str->var), &(current_oid));
783216295Ssyrinx	if (snmp_suboid_append(&(oid2str->var), (asn_subid_t) val) < 0)
784216295Ssyrinx		goto error;
785216295Ssyrinx
786216295Ssyrinx	/*
787216295Ssyrinx	 * Prepared the entry - now figure out where to insert it.
788216295Ssyrinx	 * After the object we have following options:
789216295Ssyrinx	 * 1) new line, blank, ) - then it is an enum oid -> snmp_enumlist;
790216295Ssyrinx	 * 2) new line , ( - nonleaf oid -> snmp_nodelist;
791216295Ssyrinx	 * 2) ':' - table entry - a variable length SYNTAX_TYPE (one or more)
792216295Ssyrinx	 *     may follow and second string must end line -> snmp_tablelist;
793216295Ssyrinx	 * 3) OID , string  ) - this is a trap entry or a leaf -> snmp_oidlist;
794216295Ssyrinx	 * 4) SYNTAX_TYPE, string (not always), get/set modifier - always last
795216295Ssyrinx	 *     and )- this is definitely a leaf.
796216295Ssyrinx	 */
797216295Ssyrinx
798216295Ssyrinx	switch (tok = gettoken(snmptoolctx)) {
799216295Ssyrinx	    case  ')':
800216295Ssyrinx		if ((i = snmp_enum_insert(snmptoolctx, oid2str)) < 0)
801216295Ssyrinx			goto error;
802216295Ssyrinx		if (i == 0) {
803216295Ssyrinx			free(oid2str->string);
804216295Ssyrinx			free(oid2str);
805216295Ssyrinx		}
806216295Ssyrinx		return (1);
807216295Ssyrinx
808216295Ssyrinx	    case '(':
809216295Ssyrinx		if (snmp_suboid_append(&current_oid, (asn_subid_t) val) < 0)
810216295Ssyrinx			goto error;
811216295Ssyrinx
812216295Ssyrinx		/*
813216295Ssyrinx		 * Ignore the error for nodes since the .def files currently
814216295Ssyrinx		 * contain different strings for 1.3.6.1.2.1 - mibII. Only make
815216295Ssyrinx		 * sure the memory is freed and don't complain.
816216295Ssyrinx		 */
817216295Ssyrinx		if ((i = snmp_node_insert(snmptoolctx, oid2str)) <= 0) {
818216295Ssyrinx			free(string);
819216295Ssyrinx			free(oid2str);
820216295Ssyrinx		}
821216295Ssyrinx		return (snmp_import_object(snmptoolctx));
822216295Ssyrinx
823216295Ssyrinx	    case ':':
824216295Ssyrinx		if (snmp_suboid_append(&current_oid, (asn_subid_t) val) < 0)
825216295Ssyrinx			goto error;
826216295Ssyrinx		if (snmp_import_table(snmptoolctx, oid2str) < 0)
827216295Ssyrinx			goto error;
828216295Ssyrinx		/*
829216295Ssyrinx		 * A different table entry type was malloced and the data is
830216295Ssyrinx		 * contained there.
831216295Ssyrinx		 */
832216295Ssyrinx		free(oid2str);
833216295Ssyrinx		return (1);
834216295Ssyrinx
835216295Ssyrinx	    case TOK_TYPE:
836216295Ssyrinx		/* FALLTHROUGH */
837216295Ssyrinx	    case TOK_DEFTYPE:
838216295Ssyrinx		/* FALLTHROUGH */
839216295Ssyrinx	    case TOK_ENUM:
840216295Ssyrinx	    	/* FALLTHROUGH */
841216295Ssyrinx	    case TOK_BITS:
842216295Ssyrinx		if (snmp_import_leaf(snmptoolctx, &tok, oid2str) < 0)
843216295Ssyrinx				goto error;
844216295Ssyrinx		return (1);
845216295Ssyrinx
846216295Ssyrinx	    default:
847216295Ssyrinx		warnx("Unexpected token at line %d - %s", input->lno,
848216295Ssyrinx		    input->fname);
849216295Ssyrinx		break;
850216295Ssyrinx	}
851216295Ssyrinx
852216295Ssyrinxerror:
853216295Ssyrinx	snmp_mapping_entryfree(oid2str);
854216295Ssyrinx
855216295Ssyrinx	return (-1);
856216295Ssyrinx}
857216295Ssyrinx
858216295Ssyrinxstatic int32_t
859216295Ssyrinxsnmp_import_tree(struct snmp_toolinfo *snmptoolctx, enum tok *tok)
860216295Ssyrinx{
861216295Ssyrinx	while (*tok != TOK_EOF) {
862216295Ssyrinx		switch (*tok) {
863216295Ssyrinx		    case TOK_ERR:
864216295Ssyrinx			return (-1);
865216295Ssyrinx		    case '(':
866216295Ssyrinx			if (snmp_import_object(snmptoolctx) < 0)
867216295Ssyrinx			    return (-1);
868216295Ssyrinx			break;
869216295Ssyrinx		    case ')':
870216295Ssyrinx			if (snmp_suboid_pop(&current_oid) < 0)
871216295Ssyrinx			    return (-1);
872216295Ssyrinx			(void) snmp_import_update_table(ENTRY_NONE, NULL);
873216295Ssyrinx			break;
874216295Ssyrinx		    default:
875216295Ssyrinx			/* Anything else here would be illegal. */
876216295Ssyrinx			return (-1);
877216295Ssyrinx		}
878216295Ssyrinx		*tok = gettoken(snmptoolctx);
879216295Ssyrinx	}
880216295Ssyrinx
881216295Ssyrinx	return (0);
882216295Ssyrinx}
883216295Ssyrinx
884216295Ssyrinxstatic int32_t
885216295Ssyrinxsnmp_import_top(struct snmp_toolinfo *snmptoolctx, enum tok *tok)
886216295Ssyrinx{
887216295Ssyrinx	enum snmp_tc tc;
888216295Ssyrinx	struct enum_type *t;
889216295Ssyrinx
890216295Ssyrinx	if (*tok == '(')
891216295Ssyrinx		return (snmp_import_tree(snmptoolctx, tok));
892216295Ssyrinx
893216295Ssyrinx	if (*tok == TOK_TYPEDEF) {
894216295Ssyrinx		if ((*tok = gettoken(snmptoolctx)) != TOK_STR) {
895216295Ssyrinx			warnx("type name expected after typedef - %s",
896216295Ssyrinx			    input->fname);
897216295Ssyrinx			return (-1);
898216295Ssyrinx		}
899216295Ssyrinx
900216295Ssyrinx		t = snmp_enumtc_init(nexttok);
901216295Ssyrinx
902216295Ssyrinx		*tok = gettoken(snmptoolctx);
903216295Ssyrinx		t->is_enum = (*tok == TOK_ENUM);
904216295Ssyrinx		t->is_bits = (*tok == TOK_BITS);
905216295Ssyrinx		t->syntax = parse_type(snmptoolctx, tok, &tc, &(t->snmp_enum));
906216295Ssyrinx		snmp_enumtc_insert(snmptoolctx, t);
907216295Ssyrinx
908216295Ssyrinx		return (1);
909216295Ssyrinx	}
910216295Ssyrinx
911216295Ssyrinx	if (*tok == TOK_INCLUDE) {
912216295Ssyrinx		int i;
913216295Ssyrinx
914216295Ssyrinx		*tok = gettoken(snmptoolctx);
915216295Ssyrinx		if (*tok != TOK_FILENAME) {
916216295Ssyrinx			warnx("filename expected in include directive - %s",
917216295Ssyrinx			    nexttok);
918216295Ssyrinx			return (-1);
919216295Ssyrinx		}
920216295Ssyrinx
921216295Ssyrinx		if (( i = add_filename(snmptoolctx, nexttok, NULL, 1)) == 0) {
922216295Ssyrinx			*tok = gettoken(snmptoolctx);
923216295Ssyrinx			return (1);
924216295Ssyrinx		}
925216295Ssyrinx
926216295Ssyrinx		if (i == -1)
927216295Ssyrinx			return (-1);
928216295Ssyrinx
929216295Ssyrinx		input_fopen(nexttok);
930216295Ssyrinx		*tok = gettoken(snmptoolctx);
931216295Ssyrinx		return (1);
932216295Ssyrinx	}
933216295Ssyrinx
934216295Ssyrinx	warnx("'(' or 'typedef' expected - %s", nexttok);
935216295Ssyrinx	return (-1);
936216295Ssyrinx}
937216295Ssyrinx
938216295Ssyrinxstatic int32_t
939216295Ssyrinxsnmp_import(struct snmp_toolinfo *snmptoolctx)
940216295Ssyrinx{
941216295Ssyrinx	int i;
942216295Ssyrinx	enum tok tok;
943216295Ssyrinx
944216295Ssyrinx	tok = gettoken(snmptoolctx);
945216295Ssyrinx
946216295Ssyrinx	do
947216295Ssyrinx		i = snmp_import_top(snmptoolctx, &tok);
948216295Ssyrinx	while (i > 0);
949216295Ssyrinx
950216295Ssyrinx	return (i);
951216295Ssyrinx}
952216295Ssyrinx
953216295Ssyrinx/*
954216295Ssyrinx * Read a .def file and import oid<->string mapping.
955216295Ssyrinx * Mappings are inserted into a global structure containing list for each OID
956216295Ssyrinx * syntax type.
957216295Ssyrinx */
958216295Ssyrinxint32_t
959216295Ssyrinxsnmp_import_file(struct snmp_toolinfo *snmptoolctx, struct fname *file)
960216295Ssyrinx{
961216295Ssyrinx	int idx;
962216295Ssyrinx
963216295Ssyrinx	snmp_import_init(&(file->cut));
964216295Ssyrinx	input_fopen(file->name);
965216295Ssyrinx	if ((idx = snmp_import(snmptoolctx)) < 0)
966216295Ssyrinx		warnx("Failed to read mappings from file %s", file->name);
967216295Ssyrinx
968216295Ssyrinx	input_close();
969216295Ssyrinx
970216295Ssyrinx	return (idx);
971216295Ssyrinx}
972