1*0Sstevel@tonic-gate /* Copyright %G% Sun Microsystems, Inc. All Rights Reserved.
2*0Sstevel@tonic-gate  */
3*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
4*0Sstevel@tonic-gate 
5*0Sstevel@tonic-gate /******************************************************************
6*0Sstevel@tonic-gate 	Copyright 1989, 1991, 1992 by Carnegie Mellon University
7*0Sstevel@tonic-gate 
8*0Sstevel@tonic-gate                       All Rights Reserved
9*0Sstevel@tonic-gate 
10*0Sstevel@tonic-gate Permission to use, copy, modify, and distribute this software and its
11*0Sstevel@tonic-gate documentation for any purpose and without fee is hereby granted,
12*0Sstevel@tonic-gate provided that the above copyright notice appear in all copies and that
13*0Sstevel@tonic-gate both that copyright notice and this permission notice appear in
14*0Sstevel@tonic-gate supporting documentation, and that the name of CMU not be
15*0Sstevel@tonic-gate used in advertising or publicity pertaining to distribution of the
16*0Sstevel@tonic-gate software without specific, written prior permission.
17*0Sstevel@tonic-gate 
18*0Sstevel@tonic-gate CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
19*0Sstevel@tonic-gate ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
20*0Sstevel@tonic-gate CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
21*0Sstevel@tonic-gate ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22*0Sstevel@tonic-gate WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
23*0Sstevel@tonic-gate ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
24*0Sstevel@tonic-gate SOFTWARE.
25*0Sstevel@tonic-gate ******************************************************************/
26*0Sstevel@tonic-gate /*
27*0Sstevel@tonic-gate  * parse.c
28*0Sstevel@tonic-gate  */
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate /* HISTORY
31*0Sstevel@tonic-gate  * Jerry Yeung	6-6-96
32*0Sstevel@tonic-gate  * Jerry Yeung	1-9-97	fix 4019317
33*0Sstevel@tonic-gate  */
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate #include <stdio.h>
36*0Sstevel@tonic-gate #include <ctype.h>
37*0Sstevel@tonic-gate #include <stdlib.h>
38*0Sstevel@tonic-gate #include <sys/types.h>
39*0Sstevel@tonic-gate #include "parse.h"
40*0Sstevel@tonic-gate 
41*0Sstevel@tonic-gate struct trap_item *trap_list = NULL;
42*0Sstevel@tonic-gate 
43*0Sstevel@tonic-gate /* A quoted string value-- too long for a general "token" */
44*0Sstevel@tonic-gate char *quoted_string_buffer;
45*0Sstevel@tonic-gate 
46*0Sstevel@tonic-gate /*
47*0Sstevel@tonic-gate  * This is one element of an object identifier with either an integer
48*0Sstevel@tonic-gate  * subidentifier, or a textual string label, or both.
49*0Sstevel@tonic-gate  * The subid is -1 if not present, and label is NULL if not present.
50*0Sstevel@tonic-gate  */
51*0Sstevel@tonic-gate struct subid {
52*0Sstevel@tonic-gate     int subid;
53*0Sstevel@tonic-gate     char *label;
54*0Sstevel@tonic-gate };
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate #define MAXTC	128
57*0Sstevel@tonic-gate struct tc {	/* textual conventions */
58*0Sstevel@tonic-gate     int type;
59*0Sstevel@tonic-gate     char descriptor[MAXTOKEN];
60*0Sstevel@tonic-gate     struct enum_list *enums;
61*0Sstevel@tonic-gate } tclist[MAXTC];
62*0Sstevel@tonic-gate 
63*0Sstevel@tonic-gate 
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate int Line = 1;
66*0Sstevel@tonic-gate 
67*0Sstevel@tonic-gate #define SYNTAX_MASK	0x80
68*0Sstevel@tonic-gate /* types of tokens
69*0Sstevel@tonic-gate  Tokens wiht the SYNTAX_MASK bit set are syntax tokens */
70*0Sstevel@tonic-gate #define	CONTINUE    -1
71*0Sstevel@tonic-gate #define ENDOFFILE   0
72*0Sstevel@tonic-gate #define LABEL	    1
73*0Sstevel@tonic-gate #define SUBTREE	    2
74*0Sstevel@tonic-gate #define SYNTAX	    3
75*0Sstevel@tonic-gate #define PARSE_OBJID	    (4 | SYNTAX_MASK)
76*0Sstevel@tonic-gate #define OCTETSTR    (5 | SYNTAX_MASK)
77*0Sstevel@tonic-gate #define PARSE_INTEGER	    (6 | SYNTAX_MASK)
78*0Sstevel@tonic-gate #define NETADDR	    (7 | SYNTAX_MASK)
79*0Sstevel@tonic-gate #define	IPADDR	    (8 | SYNTAX_MASK)
80*0Sstevel@tonic-gate #define PARSE_COUNTER	    (9 | SYNTAX_MASK)
81*0Sstevel@tonic-gate #define PARSE_GUAGE	    (10 | SYNTAX_MASK)
82*0Sstevel@tonic-gate #define PARSE_TIMETICKS   (11 | SYNTAX_MASK)
83*0Sstevel@tonic-gate #define PARSE_OPAQUE	    (12 | SYNTAX_MASK)
84*0Sstevel@tonic-gate #define NUL	    (13 | SYNTAX_MASK)
85*0Sstevel@tonic-gate #define SEQUENCE    14
86*0Sstevel@tonic-gate #define OF	    15	/* SEQUENCE OF */
87*0Sstevel@tonic-gate #define OBJTYPE	    16
88*0Sstevel@tonic-gate #define ACCESS	    17
89*0Sstevel@tonic-gate #define READONLY    18
90*0Sstevel@tonic-gate #define READWRITE   19
91*0Sstevel@tonic-gate #define	WRITEONLY   20
92*0Sstevel@tonic-gate #define NOACCESS    21
93*0Sstevel@tonic-gate #define STATUS	    22
94*0Sstevel@tonic-gate #define MANDATORY   23
95*0Sstevel@tonic-gate #define OPTIONAL    24
96*0Sstevel@tonic-gate #define OBSOLETE    25
97*0Sstevel@tonic-gate /* #define RECOMMENDED 26 */
98*0Sstevel@tonic-gate #define PUNCT	    27
99*0Sstevel@tonic-gate #define EQUALS	    28
100*0Sstevel@tonic-gate #define NUMBER	    29
101*0Sstevel@tonic-gate #define LEFTBRACKET 30
102*0Sstevel@tonic-gate #define RIGHTBRACKET 31
103*0Sstevel@tonic-gate #define	LEFTPAREN   32
104*0Sstevel@tonic-gate #define RIGHTPAREN  33
105*0Sstevel@tonic-gate #define COMMA	    34
106*0Sstevel@tonic-gate #define DESCRIPTION 35
107*0Sstevel@tonic-gate #define QUOTESTRING 36
108*0Sstevel@tonic-gate #define INDEX       37
109*0Sstevel@tonic-gate #define DEFVAL      38
110*0Sstevel@tonic-gate #define DEPRECATED  39
111*0Sstevel@tonic-gate #define SIZE        40
112*0Sstevel@tonic-gate #define BITSTRING   (41 | SYNTAX_MASK)
113*0Sstevel@tonic-gate #define NSAPADDRESS (42 | SYNTAX_MASK)
114*0Sstevel@tonic-gate #define PARSE_COUNTER64   (43 | SYNTAX_MASK)
115*0Sstevel@tonic-gate #define OBJGROUP    44
116*0Sstevel@tonic-gate #define NOTIFTYPE   45
117*0Sstevel@tonic-gate #define AUGMENTS    46
118*0Sstevel@tonic-gate #define COMPLIANCE  47
119*0Sstevel@tonic-gate #define READCREATE  48
120*0Sstevel@tonic-gate #define UNITS       49
121*0Sstevel@tonic-gate #define REFERENCE   50
122*0Sstevel@tonic-gate #define NUM_ENTRIES 51
123*0Sstevel@tonic-gate #define MODULEIDENTITY 52
124*0Sstevel@tonic-gate #define LASTUPDATED 53
125*0Sstevel@tonic-gate #define ORGANIZATION 54
126*0Sstevel@tonic-gate #define CONTACTINFO 55
127*0Sstevel@tonic-gate #define UINTEGER32 (56 | SYNTAX_MASK)
128*0Sstevel@tonic-gate #define CURRENT	    57
129*0Sstevel@tonic-gate #define DEFINITIONS 58
130*0Sstevel@tonic-gate #define END         59
131*0Sstevel@tonic-gate #define SEMI        60
132*0Sstevel@tonic-gate 
133*0Sstevel@tonic-gate /*
134*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
135*0Sstevel@tonic-gate */
136*0Sstevel@tonic-gate #define PSEUDO_TOKEN_TABLE        61
137*0Sstevel@tonic-gate #define PSEUDO_TOKEN_ENTRY        62
138*0Sstevel@tonic-gate 
139*0Sstevel@tonic-gate /* Jerry Yeung 6-6-96 (trap-support) */
140*0Sstevel@tonic-gate #define TRAPTYPE 63
141*0Sstevel@tonic-gate #define ENTERPRISE 64
142*0Sstevel@tonic-gate #define VARIABLES 65
143*0Sstevel@tonic-gate 
144*0Sstevel@tonic-gate struct tok {
145*0Sstevel@tonic-gate 	char *name;			/* token name */
146*0Sstevel@tonic-gate 	int len;			/* length not counting nul */
147*0Sstevel@tonic-gate 	int token;			/* value */
148*0Sstevel@tonic-gate 	int hash;			/* hash of name */
149*0Sstevel@tonic-gate 	struct tok *next;		/* pointer to next in hash table */
150*0Sstevel@tonic-gate };
151*0Sstevel@tonic-gate 
152*0Sstevel@tonic-gate 
153*0Sstevel@tonic-gate struct tok tokens[] = {
154*0Sstevel@tonic-gate 	{ "obsolete", sizeof ("obsolete")-1, OBSOLETE },
155*0Sstevel@tonic-gate 	{ "Opaque", sizeof ("Opaque")-1, PARSE_OPAQUE },
156*0Sstevel@tonic-gate /*	{ "recommended", sizeof("recommended")-1, RECOMMENDED },  */
157*0Sstevel@tonic-gate 	{ "optional", sizeof ("optional")-1, OPTIONAL },
158*0Sstevel@tonic-gate 	{ "LAST-UPDATED", sizeof ("LAST-UPDATED")-1, LASTUPDATED },
159*0Sstevel@tonic-gate 	{ "ORGANIZATION", sizeof ("ORGANIZATION")-1, ORGANIZATION },
160*0Sstevel@tonic-gate 	{ "CONTACT-INFO", sizeof ("CONTACT-INFO")-1, CONTACTINFO },
161*0Sstevel@tonic-gate 	{ "MODULE-IDENTITY", sizeof ("MODULE-IDENTITY")-1, MODULEIDENTITY },
162*0Sstevel@tonic-gate 	{ "MODULE-COMPLIANCE", sizeof ("MODULE-COMPLIANCE")-1, COMPLIANCE },
163*0Sstevel@tonic-gate         { "DEFINITIONS", sizeof("DEFINITIONS")-1, DEFINITIONS},
164*0Sstevel@tonic-gate         { "END", sizeof("END")-1, END},
165*0Sstevel@tonic-gate         { ";", sizeof(";")-1, SEMI},
166*0Sstevel@tonic-gate 	{ "AUGMENTS", sizeof ("AUGMENTS")-1, AUGMENTS },
167*0Sstevel@tonic-gate 	{ "not-accessible", sizeof ("not-accessible")-1, NOACCESS },
168*0Sstevel@tonic-gate 	{ "write-only", sizeof ("write-only")-1, WRITEONLY },
169*0Sstevel@tonic-gate 	{ "NsapAddress", sizeof("NsapAddress")-1, NSAPADDRESS},
170*0Sstevel@tonic-gate 	{ "UNITS", sizeof("Units")-1, UNITS},
171*0Sstevel@tonic-gate 	{ "REFERENCE", sizeof("REFERENCE")-1, REFERENCE},
172*0Sstevel@tonic-gate 	{ "NUM-ENTRIES", sizeof("NUM-ENTRIES")-1, NUM_ENTRIES},
173*0Sstevel@tonic-gate 	{ "BITSTRING", sizeof("BitString")-1, BITSTRING},
174*0Sstevel@tonic-gate 	{ "BIT", sizeof("BIT")-1, CONTINUE},
175*0Sstevel@tonic-gate 	{ "Counter64", sizeof("Counter64")-1, PARSE_COUNTER64},
176*0Sstevel@tonic-gate 	{ "TimeTicks", sizeof ("TimeTicks")-1, PARSE_TIMETICKS },
177*0Sstevel@tonic-gate 	{ "NOTIFICATION-TYPE", sizeof ("NOTIFICATION-TYPE")-1, NOTIFTYPE },
178*0Sstevel@tonic-gate 	{ "OBJECT-GROUP", sizeof ("OBJECT-GROUP")-1, OBJGROUP },
179*0Sstevel@tonic-gate 	{ "OBJECTIDENTIFIER", sizeof ("OBJECTIDENTIFIER")-1, PARSE_OBJID },
180*0Sstevel@tonic-gate 	/*
181*0Sstevel@tonic-gate 	 * This CONTINUE appends the next word onto OBJECT,
182*0Sstevel@tonic-gate 	 * hopefully matching OBJECTIDENTIFIER above.
183*0Sstevel@tonic-gate 	 */
184*0Sstevel@tonic-gate 	{ "OBJECT", sizeof ("OBJECT")-1, CONTINUE },
185*0Sstevel@tonic-gate 	{ "NetworkAddress", sizeof ("NetworkAddress")-1, NETADDR },
186*0Sstevel@tonic-gate 	{ "Gauge", sizeof ("Gauge")-1, PARSE_GUAGE },
187*0Sstevel@tonic-gate 	{ "read-write", sizeof ("read-write")-1, READWRITE },
188*0Sstevel@tonic-gate 	{ "read-create", sizeof ("read-create")-1, READCREATE },
189*0Sstevel@tonic-gate 	{ "OCTETSTRING", sizeof ("OCTETSTRING")-1, OCTETSTR },
190*0Sstevel@tonic-gate 	{ "OCTET", sizeof ("OCTET")-1, -1 },
191*0Sstevel@tonic-gate 	{ "OF", sizeof ("OF")-1, OF },
192*0Sstevel@tonic-gate 	{ "SEQUENCE", sizeof ("SEQUENCE")-1, SEQUENCE },
193*0Sstevel@tonic-gate 	{ "NULL", sizeof ("NULL")-1, NUL },
194*0Sstevel@tonic-gate 	{ "IpAddress", sizeof ("IpAddress")-1, IPADDR },
195*0Sstevel@tonic-gate 	{ "UInteger32", sizeof ("UInteger32")-1, UINTEGER32 },
196*0Sstevel@tonic-gate 	{ "INTEGER", sizeof ("INTEGER")-1, PARSE_INTEGER },
197*0Sstevel@tonic-gate 	{ "Counter", sizeof ("Counter")-1, PARSE_COUNTER },
198*0Sstevel@tonic-gate 	{ "read-only", sizeof ("read-only")-1, READONLY },
199*0Sstevel@tonic-gate         { "DESCRIPTION", sizeof ("DESCRIPTION")-1, DESCRIPTION },
200*0Sstevel@tonic-gate         { "INDEX", sizeof ("INDEX")-1, INDEX },
201*0Sstevel@tonic-gate         { "DEFVAL", sizeof ("DEFVAL")-1, DEFVAL },
202*0Sstevel@tonic-gate         { "deprecated", sizeof ("deprecated")-1, DEPRECATED },
203*0Sstevel@tonic-gate         { "SIZE", sizeof ("SIZE")-1, SIZE },
204*0Sstevel@tonic-gate 	{ "MAX-ACCESS", sizeof ("MAX-ACCESS")-1, ACCESS },
205*0Sstevel@tonic-gate 	{ "ACCESS", sizeof ("ACCESS")-1, ACCESS },
206*0Sstevel@tonic-gate 	{ "mandatory", sizeof ("mandatory")-1, MANDATORY },
207*0Sstevel@tonic-gate 	{ "current", sizeof ("current")-1, CURRENT },
208*0Sstevel@tonic-gate 	{ "STATUS", sizeof ("STATUS")-1, STATUS },
209*0Sstevel@tonic-gate 	{ "SYNTAX", sizeof ("SYNTAX")-1, SYNTAX },
210*0Sstevel@tonic-gate 	{ "OBJECT-TYPE", sizeof ("OBJECT-TYPE")-1, OBJTYPE },
211*0Sstevel@tonic-gate 	{ "{", sizeof ("{")-1, LEFTBRACKET },
212*0Sstevel@tonic-gate 	{ "}", sizeof ("}")-1, RIGHTBRACKET },
213*0Sstevel@tonic-gate 	{ "::=", sizeof ("::=")-1, EQUALS },
214*0Sstevel@tonic-gate 	{ "(", sizeof ("(")-1, LEFTPAREN },
215*0Sstevel@tonic-gate 	{ ")", sizeof (")")-1, RIGHTPAREN },
216*0Sstevel@tonic-gate 	{ ",", sizeof (",")-1, COMMA },
217*0Sstevel@tonic-gate 	{ "TRAP-TYPE", sizeof ("TRAP-TYPE")-1, TRAPTYPE },
218*0Sstevel@tonic-gate 	{ "ENTERPRISE", sizeof ("ENTERPRISE")-1, ENTERPRISE },
219*0Sstevel@tonic-gate 	{ "VARIABLES", sizeof ("VARIABLES")-1, VARIABLES },
220*0Sstevel@tonic-gate 	{ NULL }
221*0Sstevel@tonic-gate };
222*0Sstevel@tonic-gate 
223*0Sstevel@tonic-gate #define	HASHSIZE	32
224*0Sstevel@tonic-gate #define	BUCKET(x)	(x & 0x01F)
225*0Sstevel@tonic-gate 
226*0Sstevel@tonic-gate struct tok	*buckets[HASHSIZE];
227*0Sstevel@tonic-gate static void
228*0Sstevel@tonic-gate do_subtree(struct tree *root, struct node **nodes);
229*0Sstevel@tonic-gate static int
230*0Sstevel@tonic-gate get_token(register FILE *fp, register char *token);
231*0Sstevel@tonic-gate static int
232*0Sstevel@tonic-gate parseQuoteString(register FILE *fp, register char *token);
233*0Sstevel@tonic-gate static int
234*0Sstevel@tonic-gate tossObjectIdentifier(register FILE *fp);
235*0Sstevel@tonic-gate 
236*0Sstevel@tonic-gate int number_value;
237*0Sstevel@tonic-gate 
238*0Sstevel@tonic-gate static void
239*0Sstevel@tonic-gate hash_init()
240*0Sstevel@tonic-gate {
241*0Sstevel@tonic-gate 	register struct tok	*tp;
242*0Sstevel@tonic-gate 	register char	*cp;
243*0Sstevel@tonic-gate 	register int	h;
244*0Sstevel@tonic-gate 	register int	b;
245*0Sstevel@tonic-gate 
246*0Sstevel@tonic-gate /*
247*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
248*0Sstevel@tonic-gate 	bzero((char *)buckets, sizeof(buckets));
249*0Sstevel@tonic-gate */
250*0Sstevel@tonic-gate 	memset((void *) buckets, 0, sizeof(buckets));
251*0Sstevel@tonic-gate 
252*0Sstevel@tonic-gate 	for (tp = tokens; tp->name; tp++) {
253*0Sstevel@tonic-gate 		for (h = 0, cp = tp->name; *cp; cp++)
254*0Sstevel@tonic-gate 			h += *cp;
255*0Sstevel@tonic-gate 		tp->hash = h;
256*0Sstevel@tonic-gate 		b = BUCKET(h);
257*0Sstevel@tonic-gate 		if (buckets[b])
258*0Sstevel@tonic-gate 		    tp->next = buckets[b]; /* BUG ??? */
259*0Sstevel@tonic-gate 		buckets[b] = tp;
260*0Sstevel@tonic-gate 	}
261*0Sstevel@tonic-gate }
262*0Sstevel@tonic-gate 
263*0Sstevel@tonic-gate #define NHASHSIZE    128
264*0Sstevel@tonic-gate #define NBUCKET(x)   (x & 0x7F)
265*0Sstevel@tonic-gate struct node *nbuckets[NHASHSIZE];
266*0Sstevel@tonic-gate 
267*0Sstevel@tonic-gate void init_node_hash(nodes)
268*0Sstevel@tonic-gate      struct node *nodes;
269*0Sstevel@tonic-gate {
270*0Sstevel@tonic-gate      register struct node *np, *nextp;
271*0Sstevel@tonic-gate      register char *cp;
272*0Sstevel@tonic-gate      register int hash;
273*0Sstevel@tonic-gate 
274*0Sstevel@tonic-gate /*
275*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
276*0Sstevel@tonic-gate      bzero((char *)nbuckets,sizeof(nbuckets));
277*0Sstevel@tonic-gate */
278*0Sstevel@tonic-gate      memset((void *) nbuckets, 0, sizeof(nbuckets));
279*0Sstevel@tonic-gate 
280*0Sstevel@tonic-gate      for(np = nodes; np;){
281*0Sstevel@tonic-gate          nextp = np->next;
282*0Sstevel@tonic-gate          hash = 0;
283*0Sstevel@tonic-gate 	 for(cp = np->parent; *cp; cp++)
284*0Sstevel@tonic-gate 	     hash += *cp;
285*0Sstevel@tonic-gate 	 np->next = nbuckets[NBUCKET(hash)];
286*0Sstevel@tonic-gate 	 nbuckets[NBUCKET(hash)] = np;
287*0Sstevel@tonic-gate 	 np = nextp;
288*0Sstevel@tonic-gate      }
289*0Sstevel@tonic-gate }
290*0Sstevel@tonic-gate 
291*0Sstevel@tonic-gate static char *
292*0Sstevel@tonic-gate Malloc(num)
293*0Sstevel@tonic-gate     unsigned num;
294*0Sstevel@tonic-gate {
295*0Sstevel@tonic-gate     char     *buf;
296*0Sstevel@tonic-gate 
297*0Sstevel@tonic-gate     /* this is to fix (what seems to be) a problem with the IBM RT C
298*0Sstevel@tonic-gate library malloc */
299*0Sstevel@tonic-gate     if (num < 16)
300*0Sstevel@tonic-gate 	num = 16;
301*0Sstevel@tonic-gate     buf = (char *)malloc (num);
302*0Sstevel@tonic-gate     if (buf == NULL) {
303*0Sstevel@tonic-gate       fprintf(stderr, "malloc failed.  Exiting\n");
304*0Sstevel@tonic-gate       exit(1);
305*0Sstevel@tonic-gate     }
306*0Sstevel@tonic-gate     return (char *)buf;
307*0Sstevel@tonic-gate }
308*0Sstevel@tonic-gate 
309*0Sstevel@tonic-gate static void
310*0Sstevel@tonic-gate print_error(string, token, type)
311*0Sstevel@tonic-gate     char *string;
312*0Sstevel@tonic-gate     char *token;
313*0Sstevel@tonic-gate     int type;
314*0Sstevel@tonic-gate {
315*0Sstevel@tonic-gate     if (type == ENDOFFILE)
316*0Sstevel@tonic-gate 	fprintf(stderr, "%s(EOF): On or around line %d\n", string, Line);
317*0Sstevel@tonic-gate     else if (token)
318*0Sstevel@tonic-gate 	fprintf(stderr, "%s(%s): On or around line %d\n", string, token, Line);
319*0Sstevel@tonic-gate     else
320*0Sstevel@tonic-gate 	fprintf(stderr, "%s: On or around line %d\n", string, Line);
321*0Sstevel@tonic-gate }
322*0Sstevel@tonic-gate 
323*0Sstevel@tonic-gate /*
324*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
325*0Sstevel@tonic-gate #ifdef TEST
326*0Sstevel@tonic-gate print_subtree(tree, count)
327*0Sstevel@tonic-gate */
328*0Sstevel@tonic-gate void print_subtree(tree, count)
329*0Sstevel@tonic-gate     struct tree *tree;
330*0Sstevel@tonic-gate     int count;
331*0Sstevel@tonic-gate {
332*0Sstevel@tonic-gate     struct tree *tp;
333*0Sstevel@tonic-gate     int i;
334*0Sstevel@tonic-gate 
335*0Sstevel@tonic-gate     for(i = 0; i < count; i++)
336*0Sstevel@tonic-gate 	printf("  ");
337*0Sstevel@tonic-gate     printf("Children of %s:\n", tree->label);
338*0Sstevel@tonic-gate     count++;
339*0Sstevel@tonic-gate     for(tp = tree->child_list; tp; tp = tp->next_peer){
340*0Sstevel@tonic-gate 	for(i = 0; i < count; i++)
341*0Sstevel@tonic-gate 	    printf("  ");
342*0Sstevel@tonic-gate 	printf("%s\n", tp->label);
343*0Sstevel@tonic-gate     }
344*0Sstevel@tonic-gate     for(tp = tree->child_list; tp; tp = tp->next_peer){
345*0Sstevel@tonic-gate 	print_subtree(tp, count);
346*0Sstevel@tonic-gate     }
347*0Sstevel@tonic-gate }
348*0Sstevel@tonic-gate /*
349*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
350*0Sstevel@tonic-gate #endif
351*0Sstevel@tonic-gate */
352*0Sstevel@tonic-gate 
353*0Sstevel@tonic-gate int translation_table[256];
354*0Sstevel@tonic-gate 
355*0Sstevel@tonic-gate void build_translation_table(){
356*0Sstevel@tonic-gate     int count;
357*0Sstevel@tonic-gate 
358*0Sstevel@tonic-gate     for(count = 0; count < 256; count++){
359*0Sstevel@tonic-gate 	switch(count){
360*0Sstevel@tonic-gate 	    case PARSE_OBJID:
361*0Sstevel@tonic-gate 		translation_table[count] = TYPE_OBJID;
362*0Sstevel@tonic-gate 		break;
363*0Sstevel@tonic-gate 	    case OCTETSTR:
364*0Sstevel@tonic-gate 		translation_table[count] = TYPE_OCTETSTR;
365*0Sstevel@tonic-gate 		break;
366*0Sstevel@tonic-gate 	    case PARSE_INTEGER:
367*0Sstevel@tonic-gate 		translation_table[count] = TYPE_INTEGER;
368*0Sstevel@tonic-gate 		break;
369*0Sstevel@tonic-gate 	    case NETADDR:
370*0Sstevel@tonic-gate 		translation_table[count] = TYPE_IPADDR;
371*0Sstevel@tonic-gate 		break;
372*0Sstevel@tonic-gate 	    case IPADDR:
373*0Sstevel@tonic-gate 		translation_table[count] = TYPE_IPADDR;
374*0Sstevel@tonic-gate 		break;
375*0Sstevel@tonic-gate 	    case PARSE_COUNTER:
376*0Sstevel@tonic-gate 		translation_table[count] = TYPE_COUNTER;
377*0Sstevel@tonic-gate 		break;
378*0Sstevel@tonic-gate 	    case PARSE_GUAGE:
379*0Sstevel@tonic-gate 		translation_table[count] = TYPE_GAUGE;
380*0Sstevel@tonic-gate 		break;
381*0Sstevel@tonic-gate 	    case PARSE_TIMETICKS:
382*0Sstevel@tonic-gate 		translation_table[count] = TYPE_TIMETICKS;
383*0Sstevel@tonic-gate 		break;
384*0Sstevel@tonic-gate 	    case PARSE_OPAQUE:
385*0Sstevel@tonic-gate 		translation_table[count] = TYPE_OPAQUE;
386*0Sstevel@tonic-gate 		break;
387*0Sstevel@tonic-gate 	    case NUL:
388*0Sstevel@tonic-gate 		translation_table[count] = TYPE_NULL;
389*0Sstevel@tonic-gate 		break;
390*0Sstevel@tonic-gate 	    case PARSE_COUNTER64:
391*0Sstevel@tonic-gate 		translation_table[count] = TYPE_COUNTER64;
392*0Sstevel@tonic-gate 		break;
393*0Sstevel@tonic-gate 	    case BITSTRING:
394*0Sstevel@tonic-gate 		translation_table[count] = TYPE_BITSTRING;
395*0Sstevel@tonic-gate 		break;
396*0Sstevel@tonic-gate 	    case NSAPADDRESS:
397*0Sstevel@tonic-gate 		translation_table[count] = TYPE_NSAPADDRESS;
398*0Sstevel@tonic-gate 		break;
399*0Sstevel@tonic-gate 	    case UINTEGER32:
400*0Sstevel@tonic-gate 		translation_table[count] = TYPE_UINTEGER;
401*0Sstevel@tonic-gate 		break;
402*0Sstevel@tonic-gate 
403*0Sstevel@tonic-gate /*
404*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
405*0Sstevel@tonic-gate */
406*0Sstevel@tonic-gate 		case PSEUDO_TOKEN_TABLE:
407*0Sstevel@tonic-gate 			translation_table[count] = TYPE_TABLE;
408*0Sstevel@tonic-gate 			break;
409*0Sstevel@tonic-gate 		case PSEUDO_TOKEN_ENTRY:
410*0Sstevel@tonic-gate 			translation_table[count] = TYPE_ENTRY;
411*0Sstevel@tonic-gate 			break;
412*0Sstevel@tonic-gate 
413*0Sstevel@tonic-gate 	    default:
414*0Sstevel@tonic-gate 		translation_table[count] = TYPE_OTHER;
415*0Sstevel@tonic-gate 		break;
416*0Sstevel@tonic-gate 	}
417*0Sstevel@tonic-gate     }
418*0Sstevel@tonic-gate }
419*0Sstevel@tonic-gate 
420*0Sstevel@tonic-gate /*
421*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
422*0Sstevel@tonic-gate static struct tree *
423*0Sstevel@tonic-gate */
424*0Sstevel@tonic-gate struct tree *
425*0Sstevel@tonic-gate build_tree(nodes)
426*0Sstevel@tonic-gate     struct node *nodes;
427*0Sstevel@tonic-gate {
428*0Sstevel@tonic-gate     struct node *np;
429*0Sstevel@tonic-gate     struct tree *tp;
430*0Sstevel@tonic-gate     int bucket, nodes_left = 0;
431*0Sstevel@tonic-gate 
432*0Sstevel@tonic-gate     build_translation_table();
433*0Sstevel@tonic-gate     /* grow tree from this root node */
434*0Sstevel@tonic-gate     init_node_hash(nodes);
435*0Sstevel@tonic-gate 
436*0Sstevel@tonic-gate /*
437*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
438*0Sstevel@tonic-gate      build root node
439*0Sstevel@tonic-gate     tp = (struct tree *)Malloc(sizeof(struct tree));
440*0Sstevel@tonic-gate     tp->parent = NULL;
441*0Sstevel@tonic-gate     tp->next_peer = NULL;
442*0Sstevel@tonic-gate     tp->child_list = NULL;
443*0Sstevel@tonic-gate     tp->enums = NULL;
444*0Sstevel@tonic-gate     strcpy(tp->label, "joint-iso-ccitt");
445*0Sstevel@tonic-gate     tp->subid = 2;
446*0Sstevel@tonic-gate     tp->type = 0;
447*0Sstevel@tonic-gate     tp->description = 0;
448*0Sstevel@tonic-gate      XXX nodes isn't needed in do_subtree() ???
449*0Sstevel@tonic-gate     do_subtree(tp, &nodes);
450*0Sstevel@tonic-gate     lasttp = tp;
451*0Sstevel@tonic-gate 
452*0Sstevel@tonic-gate      build root node
453*0Sstevel@tonic-gate     tp = (struct tree *)Malloc(sizeof(struct tree));
454*0Sstevel@tonic-gate     tp->parent = NULL;
455*0Sstevel@tonic-gate     tp->next_peer = lasttp;
456*0Sstevel@tonic-gate     tp->child_list = NULL;
457*0Sstevel@tonic-gate     tp->enums = NULL;
458*0Sstevel@tonic-gate     strcpy(tp->label, "ccitt");
459*0Sstevel@tonic-gate     tp->subid = 0;
460*0Sstevel@tonic-gate     tp->type = 0;
461*0Sstevel@tonic-gate     tp->description = 0;
462*0Sstevel@tonic-gate      XXX nodes isn't needed in do_subtree() ???
463*0Sstevel@tonic-gate     do_subtree(tp, &nodes);
464*0Sstevel@tonic-gate     lasttp = tp;
465*0Sstevel@tonic-gate */
466*0Sstevel@tonic-gate 
467*0Sstevel@tonic-gate     /* build root node */
468*0Sstevel@tonic-gate     tp = (struct tree *)Malloc(sizeof(struct tree));
469*0Sstevel@tonic-gate     tp->parent = NULL;
470*0Sstevel@tonic-gate /*
471*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
472*0Sstevel@tonic-gate     tp->next_peer = lasttp;
473*0Sstevel@tonic-gate */
474*0Sstevel@tonic-gate     tp->next_peer = NULL;
475*0Sstevel@tonic-gate     tp->child_list = NULL;
476*0Sstevel@tonic-gate     tp->enums = NULL;
477*0Sstevel@tonic-gate     strcpy(tp->label, "iso");
478*0Sstevel@tonic-gate     tp->subid = 1;
479*0Sstevel@tonic-gate     tp->type = 0;
480*0Sstevel@tonic-gate     tp->description = 0;
481*0Sstevel@tonic-gate     /* XXX nodes isn't needed in do_subtree() ??? */
482*0Sstevel@tonic-gate     do_subtree(tp, &nodes);
483*0Sstevel@tonic-gate /*
484*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
485*0Sstevel@tonic-gate */
486*0Sstevel@tonic-gate 	tp->access = 0;
487*0Sstevel@tonic-gate 	tp->indexs = NULL;
488*0Sstevel@tonic-gate 	tp->n_indexs = 0;
489*0Sstevel@tonic-gate 
490*0Sstevel@tonic-gate 
491*0Sstevel@tonic-gate #ifdef TEST
492*0Sstevel@tonic-gate     print_subtree(tp, 0);
493*0Sstevel@tonic-gate #endif /* TEST */
494*0Sstevel@tonic-gate     /* If any nodes are left, the tree is probably inconsistent */
495*0Sstevel@tonic-gate     for(bucket = 0; bucket < NHASHSIZE; bucket++){
496*0Sstevel@tonic-gate         if (nbuckets[bucket]){
497*0Sstevel@tonic-gate 	    nodes_left = 1;
498*0Sstevel@tonic-gate 	    break;
499*0Sstevel@tonic-gate 	}
500*0Sstevel@tonic-gate     }
501*0Sstevel@tonic-gate     if (nodes_left){
502*0Sstevel@tonic-gate 	fprintf(stderr, "The mib description doesn't seem to be consistent.\n");
503*0Sstevel@tonic-gate 	fprintf(stderr, "Some nodes couldn't be linked under the \"iso\" tree.\n");
504*0Sstevel@tonic-gate 	fprintf(stderr, "these nodes are left:\n");
505*0Sstevel@tonic-gate 	for(bucket = 0; bucket < NHASHSIZE; bucket++){
506*0Sstevel@tonic-gate 	    for(np = nbuckets[bucket]; np; np = np->next)
507*0Sstevel@tonic-gate 	        fprintf(stderr, "%s ::= { %s %d } (%d)\n", np->label,
508*0Sstevel@tonic-gate 			np->parent, np->subid, np->type);
509*0Sstevel@tonic-gate 	}
510*0Sstevel@tonic-gate     }
511*0Sstevel@tonic-gate     return tp;
512*0Sstevel@tonic-gate }
513*0Sstevel@tonic-gate 
514*0Sstevel@tonic-gate /*
515*0Sstevel@tonic-gate  * Find all the children of root in the list of nodes.  Link them into the
516*0Sstevel@tonic-gate  * tree and out of the nodes list.
517*0Sstevel@tonic-gate  */
518*0Sstevel@tonic-gate static void
519*0Sstevel@tonic-gate do_subtree(root, nodes)
520*0Sstevel@tonic-gate     struct tree *root;
521*0Sstevel@tonic-gate     struct node **nodes;
522*0Sstevel@tonic-gate {
523*0Sstevel@tonic-gate     register struct tree *tp;
524*0Sstevel@tonic-gate     register struct node *np, **headp;
525*0Sstevel@tonic-gate     struct node *oldnp = NULL, *child_list = NULL, *childp = NULL;
526*0Sstevel@tonic-gate     char *cp;
527*0Sstevel@tonic-gate     int hash;
528*0Sstevel@tonic-gate 
529*0Sstevel@tonic-gate     tp = root;
530*0Sstevel@tonic-gate     hash = 0;
531*0Sstevel@tonic-gate     for(cp = tp->label; *cp; cp++)
532*0Sstevel@tonic-gate         hash += *cp;
533*0Sstevel@tonic-gate     headp = &nbuckets[NBUCKET(hash)];
534*0Sstevel@tonic-gate     /*
535*0Sstevel@tonic-gate      * Search each of the nodes for one whose parent is root, and
536*0Sstevel@tonic-gate      * move each into a separate list.
537*0Sstevel@tonic-gate      */
538*0Sstevel@tonic-gate     for(np = *headp; np; np = np->next){
539*0Sstevel@tonic-gate 	if ((*tp->label != *np->parent) || strcmp(tp->label, np->parent)){
540*0Sstevel@tonic-gate 	    if ((*tp->label == *np->label) && !strcmp(tp->label, np->label)){
541*0Sstevel@tonic-gate 		/* if there is another node with the same label, assume that
542*0Sstevel@tonic-gate 		 * any children after this point in the list belong to the other node.
543*0Sstevel@tonic-gate 		 * This adds some scoping to the table and allows vendors to
544*0Sstevel@tonic-gate 		 * reuse names such as "ip".
545*0Sstevel@tonic-gate 		 */
546*0Sstevel@tonic-gate 		break;
547*0Sstevel@tonic-gate 	    }
548*0Sstevel@tonic-gate 	    oldnp = np;
549*0Sstevel@tonic-gate 	} else {
550*0Sstevel@tonic-gate 	    if (child_list == NULL){
551*0Sstevel@tonic-gate 		child_list = childp = np;   /* first entry in child list */
552*0Sstevel@tonic-gate 	    } else {
553*0Sstevel@tonic-gate 		childp->next = np;
554*0Sstevel@tonic-gate 		childp = np;
555*0Sstevel@tonic-gate 	    }
556*0Sstevel@tonic-gate 	    /* take this node out of the node list */
557*0Sstevel@tonic-gate 	    if (oldnp == NULL){
558*0Sstevel@tonic-gate 		*headp = np->next;  /* fix root of node list */
559*0Sstevel@tonic-gate 	    } else {
560*0Sstevel@tonic-gate 		oldnp->next = np->next;	/* link around this node */
561*0Sstevel@tonic-gate 	    }
562*0Sstevel@tonic-gate 	}
563*0Sstevel@tonic-gate     }
564*0Sstevel@tonic-gate     if (childp)
565*0Sstevel@tonic-gate 	childp->next = 0;	/* re-terminate list */
566*0Sstevel@tonic-gate     /*
567*0Sstevel@tonic-gate      * Take each element in the child list and place it into the tree.
568*0Sstevel@tonic-gate      */
569*0Sstevel@tonic-gate     for(np = child_list; np; np = np->next){
570*0Sstevel@tonic-gate 	tp = (struct tree *)Malloc(sizeof(struct tree));
571*0Sstevel@tonic-gate 	tp->parent = root;
572*0Sstevel@tonic-gate 	tp->next_peer = NULL;
573*0Sstevel@tonic-gate 	tp->child_list = NULL;
574*0Sstevel@tonic-gate 	strcpy(tp->label, np->label);
575*0Sstevel@tonic-gate 	tp->subid = np->subid;
576*0Sstevel@tonic-gate 	tp->type = translation_table[np->type];
577*0Sstevel@tonic-gate         tp->oct_str_len = np->oct_str_len;
578*0Sstevel@tonic-gate 	tp->enums = np->enums;
579*0Sstevel@tonic-gate 	np->enums = NULL;	/* so we don't free them later */
580*0Sstevel@tonic-gate 	tp->description = np->description; /* steals memory from np */
581*0Sstevel@tonic-gate 	np->description = NULL; /* so we don't free it later */
582*0Sstevel@tonic-gate /*
583*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
584*0Sstevel@tonic-gate */
585*0Sstevel@tonic-gate 	tp->access = np->access;
586*0Sstevel@tonic-gate 	tp->indexs = np->indexs;
587*0Sstevel@tonic-gate 	np->indexs = NULL;
588*0Sstevel@tonic-gate 	tp->n_indexs = np->n_indexs;
589*0Sstevel@tonic-gate /*
590*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
591*0Sstevel@tonic-gate -- The goal of this modification is to order the
592*0Sstevel@tonic-gate -- tree according to the subid
593*0Sstevel@tonic-gate 
594*0Sstevel@tonic-gate 	if (root->child_list == NULL){
595*0Sstevel@tonic-gate 	    root->child_list = tp;
596*0Sstevel@tonic-gate 	} else {
597*0Sstevel@tonic-gate 	    peer->next_peer = tp;
598*0Sstevel@tonic-gate 	}
599*0Sstevel@tonic-gate 	peer = tp;
600*0Sstevel@tonic-gate */
601*0Sstevel@tonic-gate 	if(root->child_list == NULL)
602*0Sstevel@tonic-gate 	{
603*0Sstevel@tonic-gate 		root->child_list = tp;
604*0Sstevel@tonic-gate 	}
605*0Sstevel@tonic-gate 	else
606*0Sstevel@tonic-gate 	{
607*0Sstevel@tonic-gate 		struct tree *t = root->child_list;
608*0Sstevel@tonic-gate 		struct tree *l = NULL;
609*0Sstevel@tonic-gate 
610*0Sstevel@tonic-gate 		while(t)
611*0Sstevel@tonic-gate 		{
612*0Sstevel@tonic-gate 			if(tp->subid < t->subid)
613*0Sstevel@tonic-gate 			{
614*0Sstevel@tonic-gate 				break;
615*0Sstevel@tonic-gate 			}
616*0Sstevel@tonic-gate 			l = t;
617*0Sstevel@tonic-gate 			t = t->next_peer;
618*0Sstevel@tonic-gate 		}
619*0Sstevel@tonic-gate 		if(l == NULL)
620*0Sstevel@tonic-gate 		{
621*0Sstevel@tonic-gate 			tp->next_peer = root->child_list;
622*0Sstevel@tonic-gate 			root->child_list = tp;
623*0Sstevel@tonic-gate 		}
624*0Sstevel@tonic-gate 		else
625*0Sstevel@tonic-gate 		{
626*0Sstevel@tonic-gate 			tp->next_peer = l->next_peer;
627*0Sstevel@tonic-gate 			l->next_peer = tp;
628*0Sstevel@tonic-gate 		}
629*0Sstevel@tonic-gate 	}
630*0Sstevel@tonic-gate 
631*0Sstevel@tonic-gate /*	if (tp->type == TYPE_OTHER) */
632*0Sstevel@tonic-gate 	    do_subtree(tp, nodes);	/* recurse on this child if it isn't
633*0Sstevel@tonic-gate 					   an end node */
634*0Sstevel@tonic-gate     }
635*0Sstevel@tonic-gate     /* free all nodes that were copied into tree */
636*0Sstevel@tonic-gate     oldnp = NULL;
637*0Sstevel@tonic-gate     for(np = child_list; np; np = np->next){
638*0Sstevel@tonic-gate 	if (oldnp)
639*0Sstevel@tonic-gate 	    free(oldnp);
640*0Sstevel@tonic-gate 	oldnp = np;
641*0Sstevel@tonic-gate     }
642*0Sstevel@tonic-gate     if (oldnp)
643*0Sstevel@tonic-gate 	free(oldnp);
644*0Sstevel@tonic-gate }
645*0Sstevel@tonic-gate 
646*0Sstevel@tonic-gate 
647*0Sstevel@tonic-gate /*
648*0Sstevel@tonic-gate  * Takes a list of the form:
649*0Sstevel@tonic-gate  * { iso org(3) dod(6) 1 }
650*0Sstevel@tonic-gate  * and creates several nodes, one for each parent-child pair.
651*0Sstevel@tonic-gate  * Returns NULL on error.
652*0Sstevel@tonic-gate  */
653*0Sstevel@tonic-gate static int
654*0Sstevel@tonic-gate getoid(fp, oid,  length)
655*0Sstevel@tonic-gate     register FILE *fp;
656*0Sstevel@tonic-gate     register struct subid *oid;	/* an array of subids */
657*0Sstevel@tonic-gate     int length;	    /* the length of the array */
658*0Sstevel@tonic-gate {
659*0Sstevel@tonic-gate     register int count;
660*0Sstevel@tonic-gate     int type;
661*0Sstevel@tonic-gate     char token[MAXTOKEN];
662*0Sstevel@tonic-gate     register char *cp;
663*0Sstevel@tonic-gate 
664*0Sstevel@tonic-gate #ifdef TRACE_PROC
665*0Sstevel@tonic-gate printf("getoid() invoked\n");
666*0Sstevel@tonic-gate #endif
667*0Sstevel@tonic-gate 
668*0Sstevel@tonic-gate     if ((type = get_token(fp, token)) != LEFTBRACKET){
669*0Sstevel@tonic-gate 	print_error("Expected \"{\"", token, type);
670*0Sstevel@tonic-gate 	return NULL;
671*0Sstevel@tonic-gate     }
672*0Sstevel@tonic-gate     type = get_token(fp, token);
673*0Sstevel@tonic-gate     for(count = 0; count < length; count++, oid++){
674*0Sstevel@tonic-gate 	oid->label = 0;
675*0Sstevel@tonic-gate 	oid->subid = -1;
676*0Sstevel@tonic-gate 	if (type == RIGHTBRACKET){
677*0Sstevel@tonic-gate 	    return count;
678*0Sstevel@tonic-gate 	} else if (type != LABEL && type != NUMBER){
679*0Sstevel@tonic-gate 	    print_error("Not valid for object identifier", token, type);
680*0Sstevel@tonic-gate 	    return NULL;
681*0Sstevel@tonic-gate 	}
682*0Sstevel@tonic-gate 	if (type == LABEL){
683*0Sstevel@tonic-gate 	    /* this entry has a label */
684*0Sstevel@tonic-gate 	    cp = (char *)Malloc((unsigned)strlen(token) + 1);
685*0Sstevel@tonic-gate 	    strcpy(cp, token);
686*0Sstevel@tonic-gate 	    oid->label = cp;
687*0Sstevel@tonic-gate 	    type = get_token(fp, token);
688*0Sstevel@tonic-gate 	    if (type == LEFTPAREN){
689*0Sstevel@tonic-gate 		type = get_token(fp, token);
690*0Sstevel@tonic-gate 		if (type == NUMBER){
691*0Sstevel@tonic-gate 		    oid->subid = atoi(token);
692*0Sstevel@tonic-gate 		    if ((type = get_token(fp, token)) != RIGHTPAREN){
693*0Sstevel@tonic-gate 			print_error("Unexpected a closing parenthesis", token, type);
694*0Sstevel@tonic-gate 			return NULL;
695*0Sstevel@tonic-gate 		    }
696*0Sstevel@tonic-gate 		} else {
697*0Sstevel@tonic-gate 		    print_error("Expected a number", token, type);
698*0Sstevel@tonic-gate 		    return NULL;
699*0Sstevel@tonic-gate 		}
700*0Sstevel@tonic-gate 	    } else {
701*0Sstevel@tonic-gate 		continue;
702*0Sstevel@tonic-gate 	    }
703*0Sstevel@tonic-gate 	} else {
704*0Sstevel@tonic-gate 	    /* this entry  has just an integer sub-identifier */
705*0Sstevel@tonic-gate 	    oid->subid = atoi(token);
706*0Sstevel@tonic-gate 	}
707*0Sstevel@tonic-gate 	type = get_token(fp, token);
708*0Sstevel@tonic-gate     }
709*0Sstevel@tonic-gate     return count;
710*0Sstevel@tonic-gate 
711*0Sstevel@tonic-gate 
712*0Sstevel@tonic-gate }
713*0Sstevel@tonic-gate 
714*0Sstevel@tonic-gate static void
715*0Sstevel@tonic-gate free_node(np)
716*0Sstevel@tonic-gate     struct node *np;
717*0Sstevel@tonic-gate {
718*0Sstevel@tonic-gate     struct enum_list *ep, *tep;
719*0Sstevel@tonic-gate /*
720*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
721*0Sstevel@tonic-gate */
722*0Sstevel@tonic-gate 	struct index_list *ip, *tip;
723*0Sstevel@tonic-gate 
724*0Sstevel@tonic-gate 	ip = np->indexs;
725*0Sstevel@tonic-gate 	while(ip)
726*0Sstevel@tonic-gate 	{
727*0Sstevel@tonic-gate 		tip = ip;
728*0Sstevel@tonic-gate 		ip = ip->next;
729*0Sstevel@tonic-gate 		free((char *)tip);
730*0Sstevel@tonic-gate 	}
731*0Sstevel@tonic-gate 
732*0Sstevel@tonic-gate 
733*0Sstevel@tonic-gate     ep = np->enums;
734*0Sstevel@tonic-gate     while(ep){
735*0Sstevel@tonic-gate 	tep = ep;
736*0Sstevel@tonic-gate 	ep = ep->next;
737*0Sstevel@tonic-gate 	free((char *)tep);
738*0Sstevel@tonic-gate     }
739*0Sstevel@tonic-gate     free((char *)np);
740*0Sstevel@tonic-gate }
741*0Sstevel@tonic-gate 
742*0Sstevel@tonic-gate int parse_traptype(fp,name)
743*0Sstevel@tonic-gate FILE *fp;
744*0Sstevel@tonic-gate char *name;
745*0Sstevel@tonic-gate {
746*0Sstevel@tonic-gate    int type;
747*0Sstevel@tonic-gate    char token[MAXTOKEN];
748*0Sstevel@tonic-gate    struct trap_item *ti;
749*0Sstevel@tonic-gate    struct index_list *ip;
750*0Sstevel@tonic-gate    static struct trap_item *last_trap_item=NULL;
751*0Sstevel@tonic-gate 
752*0Sstevel@tonic-gate #ifdef TRACE_PROC
753*0Sstevel@tonic-gate printf("parse_traptype() invoked\n");
754*0Sstevel@tonic-gate #endif
755*0Sstevel@tonic-gate 
756*0Sstevel@tonic-gate    type = get_token(fp,token);
757*0Sstevel@tonic-gate    if( type == ENTERPRISE){
758*0Sstevel@tonic-gate      if( (type = get_token(fp,token)) == LABEL){
759*0Sstevel@tonic-gate 	/* create a trap item */
760*0Sstevel@tonic-gate         ti = (struct trap_item*)calloc(1, sizeof(struct trap_item));
761*0Sstevel@tonic-gate         if(ti==NULL){
762*0Sstevel@tonic-gate 	 fprintf(stderr,"calloc failed\n");
763*0Sstevel@tonic-gate 	 return 0;
764*0Sstevel@tonic-gate         }
765*0Sstevel@tonic-gate 	strcpy(ti->label,name);
766*0Sstevel@tonic-gate 	strcpy(ti->enterprise_label,token);
767*0Sstevel@tonic-gate 	ti->enterprise_subids[0] = (u_long)-1;
768*0Sstevel@tonic-gate 
769*0Sstevel@tonic-gate 	type = get_token(fp,token);
770*0Sstevel@tonic-gate 	while(type != EQUALS){
771*0Sstevel@tonic-gate 	  switch(type){
772*0Sstevel@tonic-gate 	    case VARIABLES:
773*0Sstevel@tonic-gate 		type = get_token(fp,token);
774*0Sstevel@tonic-gate 		if(type != LEFTBRACKET){
775*0Sstevel@tonic-gate 		  print_error("{ expected in VARIABLES clause",token,type);
776*0Sstevel@tonic-gate 		  free(ti);
777*0Sstevel@tonic-gate 		  return 0;
778*0Sstevel@tonic-gate 		}
779*0Sstevel@tonic-gate 		type = get_token(fp,token);
780*0Sstevel@tonic-gate 		while(type != RIGHTBRACKET)
781*0Sstevel@tonic-gate 		{
782*0Sstevel@tonic-gate 			if(type != LABEL)
783*0Sstevel@tonic-gate 			{
784*0Sstevel@tonic-gate 				print_error("LABEL expected in VARIABLES1 clause",token,type);
785*0Sstevel@tonic-gate 				free(ti);
786*0Sstevel@tonic-gate 				return 0;
787*0Sstevel@tonic-gate 			}
788*0Sstevel@tonic-gate 
789*0Sstevel@tonic-gate 
790*0Sstevel@tonic-gate 			(ti->n_variables)++;
791*0Sstevel@tonic-gate 		    	if(ti->var_list == NULL)
792*0Sstevel@tonic-gate 			{
793*0Sstevel@tonic-gate 				ip = ti->var_list = (struct index_list *)
794*0Sstevel@tonic-gate 					Malloc(sizeof(struct index_list));
795*0Sstevel@tonic-gate 			}
796*0Sstevel@tonic-gate 			else
797*0Sstevel@tonic-gate 			{
798*0Sstevel@tonic-gate 				ip->next = (struct index_list *)
799*0Sstevel@tonic-gate 					Malloc(sizeof(struct enum_list));
800*0Sstevel@tonic-gate 				ip = ip->next;
801*0Sstevel@tonic-gate 			}
802*0Sstevel@tonic-gate 			ip->next = 0;
803*0Sstevel@tonic-gate 			ip->tp = NULL;
804*0Sstevel@tonic-gate 
805*0Sstevel@tonic-gate 			ip->label =
806*0Sstevel@tonic-gate 				(char *)Malloc((unsigned)strlen(token) + 1);
807*0Sstevel@tonic-gate 			strcpy(ip->label, token);
808*0Sstevel@tonic-gate 
809*0Sstevel@tonic-gate 			type = get_token(fp, token);
810*0Sstevel@tonic-gate 
811*0Sstevel@tonic-gate 			switch(type)
812*0Sstevel@tonic-gate 			{
813*0Sstevel@tonic-gate 				case COMMA:
814*0Sstevel@tonic-gate 					type = get_token(fp, token);
815*0Sstevel@tonic-gate 					break;
816*0Sstevel@tonic-gate 
817*0Sstevel@tonic-gate 				case RIGHTBRACKET:
818*0Sstevel@tonic-gate 					break;
819*0Sstevel@tonic-gate 
820*0Sstevel@tonic-gate 				default:
821*0Sstevel@tonic-gate 					print_error(", or } expected in VARIABLES clause",token,type);
822*0Sstevel@tonic-gate 					free(ti);
823*0Sstevel@tonic-gate 					return 0;
824*0Sstevel@tonic-gate 
825*0Sstevel@tonic-gate 			}
826*0Sstevel@tonic-gate 		}
827*0Sstevel@tonic-gate 		break;
828*0Sstevel@tonic-gate 
829*0Sstevel@tonic-gate 	    case DESCRIPTION:
830*0Sstevel@tonic-gate 		type = get_token(fp,token);
831*0Sstevel@tonic-gate 		if(type != QUOTESTRING){
832*0Sstevel@tonic-gate 		  print_error("Bad DESCRIPTION",token,type);
833*0Sstevel@tonic-gate 		  free(ti);
834*0Sstevel@tonic-gate 		  return 0;
835*0Sstevel@tonic-gate 		}
836*0Sstevel@tonic-gate 		ti->description = quoted_string_buffer;
837*0Sstevel@tonic-gate 		quoted_string_buffer = (char*)malloc(MAXQUOTESTR);
838*0Sstevel@tonic-gate 		if(quoted_string_buffer==NULL){
839*0Sstevel@tonic-gate 		  fprintf(stderr,"malloc failed\n");
840*0Sstevel@tonic-gate 		  return 0;
841*0Sstevel@tonic-gate 		}
842*0Sstevel@tonic-gate 		break;
843*0Sstevel@tonic-gate 	    case REFERENCE:
844*0Sstevel@tonic-gate 		type = get_token(fp,token);
845*0Sstevel@tonic-gate 		if(type != QUOTESTRING){
846*0Sstevel@tonic-gate 		  print_error("Bad DESCRIPTION",token,type);
847*0Sstevel@tonic-gate 		  free(ti);
848*0Sstevel@tonic-gate 		  return 0;
849*0Sstevel@tonic-gate 		}
850*0Sstevel@tonic-gate 		break;
851*0Sstevel@tonic-gate 	    default:
852*0Sstevel@tonic-gate 		/* NOTHING*/
853*0Sstevel@tonic-gate 		break;
854*0Sstevel@tonic-gate 	  }
855*0Sstevel@tonic-gate 	  type = get_token(fp,token);
856*0Sstevel@tonic-gate 	}
857*0Sstevel@tonic-gate 	/* get the integer */
858*0Sstevel@tonic-gate 	if( (type = get_token(fp,token)) == NUMBER){
859*0Sstevel@tonic-gate 		ti->value = atoi(token);
860*0Sstevel@tonic-gate 		/* attach the item to list */
861*0Sstevel@tonic-gate 
862*0Sstevel@tonic-gate 
863*0Sstevel@tonic-gate 
864*0Sstevel@tonic-gate 	}else{
865*0Sstevel@tonic-gate         	print_error("Expected a number",token,type);
866*0Sstevel@tonic-gate 		free(ti);
867*0Sstevel@tonic-gate 		return 0;
868*0Sstevel@tonic-gate 	}
869*0Sstevel@tonic-gate      }else{
870*0Sstevel@tonic-gate         print_error("Expected \"enterprise name\"",token,type);
871*0Sstevel@tonic-gate         return 0;
872*0Sstevel@tonic-gate      }
873*0Sstevel@tonic-gate    }else{
874*0Sstevel@tonic-gate      print_error("Expected \"ENTERPRISE\"",token,type);
875*0Sstevel@tonic-gate      return 0;
876*0Sstevel@tonic-gate    }
877*0Sstevel@tonic-gate    if(trap_list == NULL){
878*0Sstevel@tonic-gate 	last_trap_item = trap_list = ti;
879*0Sstevel@tonic-gate    }else{
880*0Sstevel@tonic-gate 	last_trap_item->next = ti;
881*0Sstevel@tonic-gate 	last_trap_item = ti;
882*0Sstevel@tonic-gate    }
883*0Sstevel@tonic-gate    return 1;
884*0Sstevel@tonic-gate }
885*0Sstevel@tonic-gate 
886*0Sstevel@tonic-gate /*
887*0Sstevel@tonic-gate  * Parse an entry of the form:
888*0Sstevel@tonic-gate  * label OBJECT IDENTIFIER ::= { parent 2 }
889*0Sstevel@tonic-gate  * The "label OBJECT IDENTIFIER" portion has already been parsed.
890*0Sstevel@tonic-gate  * Returns 0 on error.
891*0Sstevel@tonic-gate  */
892*0Sstevel@tonic-gate static struct node *
893*0Sstevel@tonic-gate parse_objectid(fp, name)
894*0Sstevel@tonic-gate     FILE *fp;
895*0Sstevel@tonic-gate     char *name;
896*0Sstevel@tonic-gate {
897*0Sstevel@tonic-gate     int type;
898*0Sstevel@tonic-gate     char token[MAXTOKEN];
899*0Sstevel@tonic-gate     register int count;
900*0Sstevel@tonic-gate     register struct subid *op, *nop;
901*0Sstevel@tonic-gate     int length;
902*0Sstevel@tonic-gate     struct subid oid[32];
903*0Sstevel@tonic-gate     struct node *np, *root, *oldnp = NULL;
904*0Sstevel@tonic-gate 
905*0Sstevel@tonic-gate     type = get_token(fp, token);
906*0Sstevel@tonic-gate     if (type != EQUALS){
907*0Sstevel@tonic-gate 	print_error("Bad format", token, type);
908*0Sstevel@tonic-gate 	return 0;
909*0Sstevel@tonic-gate     }
910*0Sstevel@tonic-gate     if ((length = getoid(fp, oid, 32)) != 0){
911*0Sstevel@tonic-gate 	np = root = (struct node *)Malloc(sizeof(struct node));
912*0Sstevel@tonic-gate 
913*0Sstevel@tonic-gate /*
914*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
915*0Sstevel@tonic-gate 	bzero((char *)np, sizeof(struct node));
916*0Sstevel@tonic-gate */
917*0Sstevel@tonic-gate 	memset((void *) np, 0, sizeof(struct node));
918*0Sstevel@tonic-gate 
919*0Sstevel@tonic-gate 	/*
920*0Sstevel@tonic-gate 	 * For each parent-child subid pair in the subid array,
921*0Sstevel@tonic-gate 	 * create a node and link it into the node list.
922*0Sstevel@tonic-gate 	 */
923*0Sstevel@tonic-gate 	for(count = 0, op = oid, nop=oid+1; count < (length - 2); count++,
924*0Sstevel@tonic-gate 	    op++, nop++){
925*0Sstevel@tonic-gate 	    /* every node must have parent's name and child's name or number */
926*0Sstevel@tonic-gate 	    if (op->label && (nop->label || (nop->subid != -1))){
927*0Sstevel@tonic-gate 		strcpy(np->parent, op->label);
928*0Sstevel@tonic-gate 		if (nop->label)
929*0Sstevel@tonic-gate 		    strcpy(np->label, nop->label);
930*0Sstevel@tonic-gate 		if (nop->subid != -1)
931*0Sstevel@tonic-gate 		    np->subid = nop->subid;
932*0Sstevel@tonic-gate 		np->type = 0;
933*0Sstevel@tonic-gate 		np->enums = 0;
934*0Sstevel@tonic-gate /*
935*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
936*0Sstevel@tonic-gate */
937*0Sstevel@tonic-gate 		np->access = 0;
938*0Sstevel@tonic-gate 		np->n_indexs = 0;
939*0Sstevel@tonic-gate 		np->indexs = NULL;
940*0Sstevel@tonic-gate 
941*0Sstevel@tonic-gate 		/* set up next entry */
942*0Sstevel@tonic-gate 		np->next = (struct node *)Malloc(sizeof(*np->next));
943*0Sstevel@tonic-gate 
944*0Sstevel@tonic-gate /*
945*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
946*0Sstevel@tonic-gate 		bzero((char *)np->next, sizeof(struct node));
947*0Sstevel@tonic-gate */
948*0Sstevel@tonic-gate 		memset((void *) np->next, 0, sizeof(struct node));
949*0Sstevel@tonic-gate 
950*0Sstevel@tonic-gate 		oldnp = np;
951*0Sstevel@tonic-gate 		np = np->next;
952*0Sstevel@tonic-gate 	    }
953*0Sstevel@tonic-gate 	}
954*0Sstevel@tonic-gate 	np->next = (struct node *)NULL;
955*0Sstevel@tonic-gate 	/*
956*0Sstevel@tonic-gate 	 * The above loop took care of all but the last pair.  This pair is taken
957*0Sstevel@tonic-gate 	 * care of here.  The name for this node is taken from the label for this
958*0Sstevel@tonic-gate 	 * entry.
959*0Sstevel@tonic-gate 	 * np still points to an unused entry.
960*0Sstevel@tonic-gate 	 */
961*0Sstevel@tonic-gate 	if (count == (length - 2)){
962*0Sstevel@tonic-gate 	    if (op->label){
963*0Sstevel@tonic-gate 		strcpy(np->parent, op->label);
964*0Sstevel@tonic-gate 		strcpy(np->label, name);
965*0Sstevel@tonic-gate 		if (nop->subid != -1)
966*0Sstevel@tonic-gate 		    np->subid = nop->subid;
967*0Sstevel@tonic-gate 		else
968*0Sstevel@tonic-gate 		    print_error("Warning: This entry is pretty silly",
969*0Sstevel@tonic-gate 				np->label, type);
970*0Sstevel@tonic-gate 	    } else {
971*0Sstevel@tonic-gate 		free_node(np);
972*0Sstevel@tonic-gate 		if (oldnp)
973*0Sstevel@tonic-gate 		    oldnp->next = NULL;
974*0Sstevel@tonic-gate 		else
975*0Sstevel@tonic-gate 		    return NULL;
976*0Sstevel@tonic-gate 	    }
977*0Sstevel@tonic-gate 	} else {
978*0Sstevel@tonic-gate 	    print_error("Missing end of oid", (char *)NULL, type);
979*0Sstevel@tonic-gate 	    free_node(np);   /* the last node allocated wasn't used */
980*0Sstevel@tonic-gate 	    if (oldnp)
981*0Sstevel@tonic-gate 		oldnp->next = NULL;
982*0Sstevel@tonic-gate 	    return NULL;
983*0Sstevel@tonic-gate 	}
984*0Sstevel@tonic-gate 	/* free the oid array */
985*0Sstevel@tonic-gate 	for(count = 0, op = oid; count < length; count++, op++){
986*0Sstevel@tonic-gate 	    if (op->label)
987*0Sstevel@tonic-gate 		free(op->label);
988*0Sstevel@tonic-gate 	    op->label = 0;
989*0Sstevel@tonic-gate 	}
990*0Sstevel@tonic-gate 	return root;
991*0Sstevel@tonic-gate     } else {
992*0Sstevel@tonic-gate 	print_error("Bad object identifier", (char *)NULL, type);
993*0Sstevel@tonic-gate 	return 0;
994*0Sstevel@tonic-gate     }
995*0Sstevel@tonic-gate }
996*0Sstevel@tonic-gate 
997*0Sstevel@tonic-gate static int
998*0Sstevel@tonic-gate get_tc(descriptor, ep)
999*0Sstevel@tonic-gate     char *descriptor;
1000*0Sstevel@tonic-gate     struct enum_list **ep;
1001*0Sstevel@tonic-gate {
1002*0Sstevel@tonic-gate     int i;
1003*0Sstevel@tonic-gate 
1004*0Sstevel@tonic-gate     for(i = 0; i < MAXTC; i++){
1005*0Sstevel@tonic-gate 	if (tclist[i].type == 0)
1006*0Sstevel@tonic-gate 	    break;
1007*0Sstevel@tonic-gate 	if (!strcmp(descriptor, tclist[i].descriptor)){
1008*0Sstevel@tonic-gate 	    *ep = tclist[i].enums;
1009*0Sstevel@tonic-gate 	    return tclist[i].type;
1010*0Sstevel@tonic-gate 	}
1011*0Sstevel@tonic-gate     }
1012*0Sstevel@tonic-gate     return LABEL;
1013*0Sstevel@tonic-gate }
1014*0Sstevel@tonic-gate 
1015*0Sstevel@tonic-gate /*
1016*0Sstevel@tonic-gate  * Parses an asn type.  Structures are ignored by this parser.
1017*0Sstevel@tonic-gate  * Returns NULL on error.
1018*0Sstevel@tonic-gate  */
1019*0Sstevel@tonic-gate static int
1020*0Sstevel@tonic-gate parse_asntype(fp, name, ntype, ntoken)
1021*0Sstevel@tonic-gate     FILE *fp;
1022*0Sstevel@tonic-gate     char *name;
1023*0Sstevel@tonic-gate     int *ntype;
1024*0Sstevel@tonic-gate     char *ntoken;
1025*0Sstevel@tonic-gate {
1026*0Sstevel@tonic-gate     int type, i;
1027*0Sstevel@tonic-gate     char token[MAXTOKEN];
1028*0Sstevel@tonic-gate     struct enum_list *ep;
1029*0Sstevel@tonic-gate     struct tc *tcp;
1030*0Sstevel@tonic-gate     int level;
1031*0Sstevel@tonic-gate 
1032*0Sstevel@tonic-gate #ifdef TRACE_PROC
1033*0Sstevel@tonic-gate printf("parse_asntype() invoked\n");
1034*0Sstevel@tonic-gate #endif
1035*0Sstevel@tonic-gate 
1036*0Sstevel@tonic-gate     type = get_token(fp, token);
1037*0Sstevel@tonic-gate     if (type == SEQUENCE){
1038*0Sstevel@tonic-gate 	while((type = get_token(fp, token)) != ENDOFFILE){
1039*0Sstevel@tonic-gate 	    if (type == RIGHTBRACKET){
1040*0Sstevel@tonic-gate 		*ntype = get_token(fp, ntoken);
1041*0Sstevel@tonic-gate 		return 1;
1042*0Sstevel@tonic-gate 	    }
1043*0Sstevel@tonic-gate 	}
1044*0Sstevel@tonic-gate 	print_error("Expected \"}\"", token, type);
1045*0Sstevel@tonic-gate 	return 0;
1046*0Sstevel@tonic-gate     } else {
1047*0Sstevel@tonic-gate 	if (!strcmp(token, "TEXTUAL-CONVENTION")){
1048*0Sstevel@tonic-gate 	    while (type != SYNTAX)
1049*0Sstevel@tonic-gate 		type = get_token(fp, token);
1050*0Sstevel@tonic-gate 	    type = get_token(fp, token);
1051*0Sstevel@tonic-gate 	}
1052*0Sstevel@tonic-gate 	/* textual convention */
1053*0Sstevel@tonic-gate 	for(i = 0; i < MAXTC; i++){
1054*0Sstevel@tonic-gate 	    if (tclist[i].type == 0)
1055*0Sstevel@tonic-gate 		break;
1056*0Sstevel@tonic-gate 	}
1057*0Sstevel@tonic-gate 	if (i == MAXTC){
1058*0Sstevel@tonic-gate 	    print_error("No more textual conventions possible.", token, type);
1059*0Sstevel@tonic-gate 	    return 0;
1060*0Sstevel@tonic-gate 	}
1061*0Sstevel@tonic-gate 	tcp = &tclist[i];
1062*0Sstevel@tonic-gate 	strcpy(tcp->descriptor, name);
1063*0Sstevel@tonic-gate 	if (!(type & SYNTAX_MASK)){
1064*0Sstevel@tonic-gate 
1065*0Sstevel@tonic-gate /*
1066*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
1067*0Sstevel@tonic-gate 	    print_error("Textual convention doesn't map to real type.", token,
1068*0Sstevel@tonic-gate 			type);
1069*0Sstevel@tonic-gate 	    return 0;
1070*0Sstevel@tonic-gate 	}
1071*0Sstevel@tonic-gate */
1072*0Sstevel@tonic-gate 		int w;
1073*0Sstevel@tonic-gate 
1074*0Sstevel@tonic-gate 		w = get_tc(token, &ep);
1075*0Sstevel@tonic-gate 		if(!(w & SYNTAX_MASK))
1076*0Sstevel@tonic-gate 		{
1077*0Sstevel@tonic-gate 	    		print_error("Textual convention doesn't map to real type.", token, type);
1078*0Sstevel@tonic-gate 	    		return 0;
1079*0Sstevel@tonic-gate 		}
1080*0Sstevel@tonic-gate 		type = w;
1081*0Sstevel@tonic-gate 	}
1082*0Sstevel@tonic-gate 
1083*0Sstevel@tonic-gate 	tcp->type = type;
1084*0Sstevel@tonic-gate 	*ntype = get_token(fp, ntoken);
1085*0Sstevel@tonic-gate 	if (*ntype == LEFTPAREN){
1086*0Sstevel@tonic-gate 	    level = 1;
1087*0Sstevel@tonic-gate 	    /* don't record any constraints for now */
1088*0Sstevel@tonic-gate 	    while(level > 0){
1089*0Sstevel@tonic-gate 		*ntype = get_token(fp, ntoken);
1090*0Sstevel@tonic-gate 		if (*ntype == LEFTPAREN)
1091*0Sstevel@tonic-gate 		    level++;
1092*0Sstevel@tonic-gate 		if (*ntype == RIGHTPAREN)
1093*0Sstevel@tonic-gate 		    level--;
1094*0Sstevel@tonic-gate 	    }
1095*0Sstevel@tonic-gate 	    *ntype = get_token(fp, ntoken);
1096*0Sstevel@tonic-gate 	} else if (*ntype == LEFTBRACKET) {
1097*0Sstevel@tonic-gate 	    /* if there is an enumeration list, parse it */
1098*0Sstevel@tonic-gate 	    while((type = get_token(fp, token)) != ENDOFFILE){
1099*0Sstevel@tonic-gate 		if (type == RIGHTBRACKET)
1100*0Sstevel@tonic-gate 		    break;
1101*0Sstevel@tonic-gate 		if (type == LABEL){
1102*0Sstevel@tonic-gate 		    /* this is an enumerated label */
1103*0Sstevel@tonic-gate 		    if (tcp->enums == 0){
1104*0Sstevel@tonic-gate 			ep = tcp->enums = (struct enum_list *)
1105*0Sstevel@tonic-gate 			    Malloc(sizeof(struct enum_list));
1106*0Sstevel@tonic-gate 		    } else {
1107*0Sstevel@tonic-gate 			ep->next = (struct enum_list *)
1108*0Sstevel@tonic-gate 			    Malloc(sizeof(struct enum_list));
1109*0Sstevel@tonic-gate 			ep = ep->next;
1110*0Sstevel@tonic-gate 		    }
1111*0Sstevel@tonic-gate 		    ep->next = 0;
1112*0Sstevel@tonic-gate 		    /* a reasonable approximation for the length */
1113*0Sstevel@tonic-gate 		    ep->label =
1114*0Sstevel@tonic-gate 			(char *)Malloc((unsigned)strlen(token) + 1);
1115*0Sstevel@tonic-gate 		    strcpy(ep->label, token);
1116*0Sstevel@tonic-gate 		    type = get_token(fp, token);
1117*0Sstevel@tonic-gate 		    if (type != LEFTPAREN){
1118*0Sstevel@tonic-gate 			print_error("Expected \"(\"", token, type);
1119*0Sstevel@tonic-gate 			/* free_node(np); */
1120*0Sstevel@tonic-gate 			return 0;
1121*0Sstevel@tonic-gate 		    }
1122*0Sstevel@tonic-gate 		    type = get_token(fp, token);
1123*0Sstevel@tonic-gate 		    if (type != NUMBER){
1124*0Sstevel@tonic-gate 			print_error("Expected integer", token, type);
1125*0Sstevel@tonic-gate 			/* free_node(np); */
1126*0Sstevel@tonic-gate 			return 0;
1127*0Sstevel@tonic-gate 		    }
1128*0Sstevel@tonic-gate 		    ep->value = atoi(token);
1129*0Sstevel@tonic-gate 		    type = get_token(fp, token);
1130*0Sstevel@tonic-gate 		    if (type != RIGHTPAREN){
1131*0Sstevel@tonic-gate 			print_error("Expected \")\"", token, type);
1132*0Sstevel@tonic-gate 			/* free_node(np); */
1133*0Sstevel@tonic-gate 			return 0;
1134*0Sstevel@tonic-gate 		    }
1135*0Sstevel@tonic-gate 		}
1136*0Sstevel@tonic-gate 	    }
1137*0Sstevel@tonic-gate 	    if (type == ENDOFFILE){
1138*0Sstevel@tonic-gate 		print_error("Expected \"}\"", token, type);
1139*0Sstevel@tonic-gate 		/* free_node(np); */
1140*0Sstevel@tonic-gate 		return 0;
1141*0Sstevel@tonic-gate 	    }
1142*0Sstevel@tonic-gate 	    *ntype = get_token(fp, ntoken);
1143*0Sstevel@tonic-gate 	}
1144*0Sstevel@tonic-gate 	return 1;
1145*0Sstevel@tonic-gate     }
1146*0Sstevel@tonic-gate }
1147*0Sstevel@tonic-gate 
1148*0Sstevel@tonic-gate 
1149*0Sstevel@tonic-gate /*
1150*0Sstevel@tonic-gate  * Parses an OBJECT TYPE macro.
1151*0Sstevel@tonic-gate  * Returns 0 on error.
1152*0Sstevel@tonic-gate  */
1153*0Sstevel@tonic-gate static struct node *
1154*0Sstevel@tonic-gate parse_objecttype(fp, name)
1155*0Sstevel@tonic-gate     register FILE *fp;
1156*0Sstevel@tonic-gate     char *name;
1157*0Sstevel@tonic-gate {
1158*0Sstevel@tonic-gate     register int type;
1159*0Sstevel@tonic-gate     char token[MAXTOKEN];
1160*0Sstevel@tonic-gate     int count, length;
1161*0Sstevel@tonic-gate     struct subid oid[32];
1162*0Sstevel@tonic-gate     char syntax[MAXTOKEN];
1163*0Sstevel@tonic-gate     int nexttype, tctype;
1164*0Sstevel@tonic-gate     char nexttoken[MAXTOKEN];
1165*0Sstevel@tonic-gate     register struct node *np;
1166*0Sstevel@tonic-gate     register struct enum_list *ep;
1167*0Sstevel@tonic-gate /*
1168*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
1169*0Sstevel@tonic-gate */
1170*0Sstevel@tonic-gate 	struct index_list *ip;
1171*0Sstevel@tonic-gate 
1172*0Sstevel@tonic-gate     type = get_token(fp, token);
1173*0Sstevel@tonic-gate     if (type != SYNTAX){
1174*0Sstevel@tonic-gate 	print_error("Bad format for OBJECT TYPE", token, type);
1175*0Sstevel@tonic-gate 	return 0;
1176*0Sstevel@tonic-gate     }
1177*0Sstevel@tonic-gate     np = (struct node *)Malloc(sizeof(struct node));
1178*0Sstevel@tonic-gate     np->next = 0;
1179*0Sstevel@tonic-gate     np->enums = 0;
1180*0Sstevel@tonic-gate     np->description = NULL;        /* default to an empty description */
1181*0Sstevel@tonic-gate /*
1182*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
1183*0Sstevel@tonic-gate */
1184*0Sstevel@tonic-gate 	np->access = 0;
1185*0Sstevel@tonic-gate 	np->n_indexs = 0;
1186*0Sstevel@tonic-gate 	np->indexs = 0;
1187*0Sstevel@tonic-gate 
1188*0Sstevel@tonic-gate     type = get_token(fp, token);
1189*0Sstevel@tonic-gate     if (type == LABEL){
1190*0Sstevel@tonic-gate 	tctype = get_tc(token, &(np->enums));
1191*0Sstevel@tonic-gate #if 0
1192*0Sstevel@tonic-gate 	if (tctype == LABEL){
1193*0Sstevel@tonic-gate 	    print_error("No known translation for type", token, type);
1194*0Sstevel@tonic-gate 	    return 0;
1195*0Sstevel@tonic-gate 	}
1196*0Sstevel@tonic-gate #endif
1197*0Sstevel@tonic-gate 	type = tctype;
1198*0Sstevel@tonic-gate     }
1199*0Sstevel@tonic-gate     np->type = type;
1200*0Sstevel@tonic-gate     np->oct_str_len = 0;
1201*0Sstevel@tonic-gate     nexttype = get_token(fp, nexttoken);
1202*0Sstevel@tonic-gate     switch(type){
1203*0Sstevel@tonic-gate 	case SEQUENCE:
1204*0Sstevel@tonic-gate 	    strcpy(syntax, token);
1205*0Sstevel@tonic-gate 	    if (nexttype == OF){
1206*0Sstevel@tonic-gate 		strcat(syntax, " ");
1207*0Sstevel@tonic-gate 		strcat(syntax, nexttoken);
1208*0Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
1209*0Sstevel@tonic-gate 		strcat(syntax, " ");
1210*0Sstevel@tonic-gate 		strcat(syntax, nexttoken);
1211*0Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
1212*0Sstevel@tonic-gate 
1213*0Sstevel@tonic-gate /*
1214*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
1215*0Sstevel@tonic-gate */
1216*0Sstevel@tonic-gate 		np->type = PSEUDO_TOKEN_TABLE;
1217*0Sstevel@tonic-gate 	    }
1218*0Sstevel@tonic-gate 
1219*0Sstevel@tonic-gate 	    break;
1220*0Sstevel@tonic-gate 	case PARSE_INTEGER:
1221*0Sstevel@tonic-gate 	case UINTEGER32:
1222*0Sstevel@tonic-gate 	    strcpy(syntax, token);
1223*0Sstevel@tonic-gate 	    if (nexttype == LEFTBRACKET) {
1224*0Sstevel@tonic-gate 		/* if there is an enumeration list, parse it */
1225*0Sstevel@tonic-gate 		while((type = get_token(fp, token)) != ENDOFFILE){
1226*0Sstevel@tonic-gate 		    if (type == RIGHTBRACKET)
1227*0Sstevel@tonic-gate 			break;
1228*0Sstevel@tonic-gate 		    if (type == LABEL){
1229*0Sstevel@tonic-gate 			/* this is an enumerated label */
1230*0Sstevel@tonic-gate 			if (np->enums == 0){
1231*0Sstevel@tonic-gate 			    ep = np->enums = (struct enum_list *)
1232*0Sstevel@tonic-gate 					Malloc(sizeof(struct enum_list));
1233*0Sstevel@tonic-gate 			} else {
1234*0Sstevel@tonic-gate 			    ep->next = (struct enum_list *)
1235*0Sstevel@tonic-gate 					Malloc(sizeof(struct enum_list));
1236*0Sstevel@tonic-gate 			    ep = ep->next;
1237*0Sstevel@tonic-gate 			}
1238*0Sstevel@tonic-gate 			ep->next = 0;
1239*0Sstevel@tonic-gate 			/* a reasonable approximation for the length */
1240*0Sstevel@tonic-gate 			ep->label =
1241*0Sstevel@tonic-gate 			    (char *)Malloc((unsigned)strlen(token) + 1);
1242*0Sstevel@tonic-gate 			strcpy(ep->label, token);
1243*0Sstevel@tonic-gate 			type = get_token(fp, token);
1244*0Sstevel@tonic-gate 			if (type != LEFTPAREN){
1245*0Sstevel@tonic-gate 			    print_error("Expected \"(\"", token, type);
1246*0Sstevel@tonic-gate 			    free_node(np);
1247*0Sstevel@tonic-gate 			    return 0;
1248*0Sstevel@tonic-gate 			}
1249*0Sstevel@tonic-gate 			type = get_token(fp, token);
1250*0Sstevel@tonic-gate 			if (type != NUMBER){
1251*0Sstevel@tonic-gate 			    print_error("Expected integer", token, type);
1252*0Sstevel@tonic-gate 			    free_node(np);
1253*0Sstevel@tonic-gate 			    return 0;
1254*0Sstevel@tonic-gate 			}
1255*0Sstevel@tonic-gate 			ep->value = atoi(token);
1256*0Sstevel@tonic-gate 			type = get_token(fp, token);
1257*0Sstevel@tonic-gate 			if (type != RIGHTPAREN){
1258*0Sstevel@tonic-gate 			    print_error("Expected \")\"", token, type);
1259*0Sstevel@tonic-gate 			    free_node(np);
1260*0Sstevel@tonic-gate 			    return 0;
1261*0Sstevel@tonic-gate 			}
1262*0Sstevel@tonic-gate 		    }
1263*0Sstevel@tonic-gate 		}
1264*0Sstevel@tonic-gate 		if (type == ENDOFFILE){
1265*0Sstevel@tonic-gate 		    print_error("Expected \"}\"", token, type);
1266*0Sstevel@tonic-gate 		    free_node(np);
1267*0Sstevel@tonic-gate 		    return 0;
1268*0Sstevel@tonic-gate 		}
1269*0Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
1270*0Sstevel@tonic-gate 	    } else if (nexttype == LEFTPAREN){
1271*0Sstevel@tonic-gate 		/* ignore the "constrained integer" for now */
1272*0Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
1273*0Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
1274*0Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
1275*0Sstevel@tonic-gate 	    }
1276*0Sstevel@tonic-gate 	    break;
1277*0Sstevel@tonic-gate 	case BITSTRING:
1278*0Sstevel@tonic-gate 	    strcpy(syntax, token);
1279*0Sstevel@tonic-gate 	    if (nexttype == LEFTBRACKET) {
1280*0Sstevel@tonic-gate 		/* if there is an enumeration list, parse it */
1281*0Sstevel@tonic-gate 		while((type = get_token(fp, token)) != ENDOFFILE){
1282*0Sstevel@tonic-gate 		    if (type == RIGHTBRACKET)
1283*0Sstevel@tonic-gate 			break;
1284*0Sstevel@tonic-gate 		    if (type == LABEL){
1285*0Sstevel@tonic-gate 			/* this is an enumerated label */
1286*0Sstevel@tonic-gate 			if (np->enums == 0){
1287*0Sstevel@tonic-gate 			    ep = np->enums = (struct enum_list *)
1288*0Sstevel@tonic-gate 					Malloc(sizeof(struct enum_list));
1289*0Sstevel@tonic-gate 			} else {
1290*0Sstevel@tonic-gate 			    ep->next = (struct enum_list *)
1291*0Sstevel@tonic-gate 					Malloc(sizeof(struct enum_list));
1292*0Sstevel@tonic-gate 			    ep = ep->next;
1293*0Sstevel@tonic-gate 			}
1294*0Sstevel@tonic-gate 			ep->next = 0;
1295*0Sstevel@tonic-gate 			/* a reasonable approximation for the length */
1296*0Sstevel@tonic-gate 			ep->label =
1297*0Sstevel@tonic-gate 			    (char *)Malloc((unsigned)strlen(token) + 1);
1298*0Sstevel@tonic-gate 			strcpy(ep->label, token);
1299*0Sstevel@tonic-gate 			type = get_token(fp, token);
1300*0Sstevel@tonic-gate 			if (type != LEFTPAREN){
1301*0Sstevel@tonic-gate 			    print_error("Expected \"(\"", token, type);
1302*0Sstevel@tonic-gate 			    free_node(np);
1303*0Sstevel@tonic-gate 			    return 0;
1304*0Sstevel@tonic-gate 			}
1305*0Sstevel@tonic-gate 			type = get_token(fp, token);
1306*0Sstevel@tonic-gate 			if (type != NUMBER){
1307*0Sstevel@tonic-gate 			    print_error("Expected integer", token, type);
1308*0Sstevel@tonic-gate 			    free_node(np);
1309*0Sstevel@tonic-gate 			    return 0;
1310*0Sstevel@tonic-gate 			}
1311*0Sstevel@tonic-gate 			ep->value = atoi(token);
1312*0Sstevel@tonic-gate 			type = get_token(fp, token);
1313*0Sstevel@tonic-gate 			if (type != RIGHTPAREN){
1314*0Sstevel@tonic-gate 			    print_error("Expected \")\"", token, type);
1315*0Sstevel@tonic-gate 			    free_node(np);
1316*0Sstevel@tonic-gate 			    return 0;
1317*0Sstevel@tonic-gate 			}
1318*0Sstevel@tonic-gate 		    }
1319*0Sstevel@tonic-gate 		}
1320*0Sstevel@tonic-gate 		if (type == ENDOFFILE){
1321*0Sstevel@tonic-gate 		    print_error("Expected \"}\"", token, type);
1322*0Sstevel@tonic-gate 		    free_node(np);
1323*0Sstevel@tonic-gate 		    return 0;
1324*0Sstevel@tonic-gate 		}
1325*0Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
1326*0Sstevel@tonic-gate 	    } else if (nexttype == LEFTPAREN){
1327*0Sstevel@tonic-gate 		/* ignore the "constrained integer" for now */
1328*0Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
1329*0Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
1330*0Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
1331*0Sstevel@tonic-gate 	    }
1332*0Sstevel@tonic-gate 	    break;
1333*0Sstevel@tonic-gate 	case OCTETSTR:
1334*0Sstevel@tonic-gate 	    strcpy(syntax, token);
1335*0Sstevel@tonic-gate             /* ignore the "constrained octet string" for now */
1336*0Sstevel@tonic-gate             if (nexttype == LEFTPAREN) {
1337*0Sstevel@tonic-gate                 nexttype = get_token(fp, nexttoken);
1338*0Sstevel@tonic-gate                 if (nexttype == SIZE) {
1339*0Sstevel@tonic-gate                     nexttype = get_token(fp, nexttoken);
1340*0Sstevel@tonic-gate                     if (nexttype == LEFTPAREN) {
1341*0Sstevel@tonic-gate                         nexttype = get_token(fp, nexttoken); /* 0..255 */
1342*0Sstevel@tonic-gate                         np->oct_str_len = number_value;
1343*0Sstevel@tonic-gate                         number_value = 0;
1344*0Sstevel@tonic-gate                         nexttype = get_token(fp, nexttoken); /* ) */
1345*0Sstevel@tonic-gate                         nexttype = get_token(fp, nexttoken); /* ) */
1346*0Sstevel@tonic-gate                         if (nexttype == RIGHTPAREN)
1347*0Sstevel@tonic-gate                         {
1348*0Sstevel@tonic-gate                             nexttype = get_token(fp, nexttoken);
1349*0Sstevel@tonic-gate                             break;
1350*0Sstevel@tonic-gate                         }
1351*0Sstevel@tonic-gate                     }
1352*0Sstevel@tonic-gate                 }
1353*0Sstevel@tonic-gate                 print_error("Bad syntax", token, type);
1354*0Sstevel@tonic-gate                 free_node(np);
1355*0Sstevel@tonic-gate                 return 0;
1356*0Sstevel@tonic-gate             }
1357*0Sstevel@tonic-gate 	    break;
1358*0Sstevel@tonic-gate 	case PARSE_OBJID:
1359*0Sstevel@tonic-gate 	case NETADDR:
1360*0Sstevel@tonic-gate 	case IPADDR:
1361*0Sstevel@tonic-gate 	case PARSE_COUNTER:
1362*0Sstevel@tonic-gate 	case PARSE_GUAGE:
1363*0Sstevel@tonic-gate 	case PARSE_TIMETICKS:
1364*0Sstevel@tonic-gate 	case PARSE_OPAQUE:
1365*0Sstevel@tonic-gate 	case NUL:
1366*0Sstevel@tonic-gate 	case LABEL:
1367*0Sstevel@tonic-gate 	case NSAPADDRESS:
1368*0Sstevel@tonic-gate 	case PARSE_COUNTER64:
1369*0Sstevel@tonic-gate 	    strcpy(syntax, token);
1370*0Sstevel@tonic-gate 	    break;
1371*0Sstevel@tonic-gate 	default:
1372*0Sstevel@tonic-gate 	    print_error("Bad syntax", token, type);
1373*0Sstevel@tonic-gate 	    free_node(np);
1374*0Sstevel@tonic-gate 	    return 0;
1375*0Sstevel@tonic-gate     }
1376*0Sstevel@tonic-gate     if (nexttype == UNITS){
1377*0Sstevel@tonic-gate 	type = get_token(fp, token);
1378*0Sstevel@tonic-gate 	if (type != QUOTESTRING) {
1379*0Sstevel@tonic-gate 	    print_error("Bad DESCRIPTION", token, type);
1380*0Sstevel@tonic-gate 	    free_node(np);
1381*0Sstevel@tonic-gate 	    return 0;
1382*0Sstevel@tonic-gate 	}
1383*0Sstevel@tonic-gate 	nexttype = get_token(fp, nexttoken);
1384*0Sstevel@tonic-gate     }
1385*0Sstevel@tonic-gate     if (nexttype != ACCESS){
1386*0Sstevel@tonic-gate 	print_error("Should be ACCESS", nexttoken, nexttype);
1387*0Sstevel@tonic-gate 	free_node(np);
1388*0Sstevel@tonic-gate 	return 0;
1389*0Sstevel@tonic-gate     }
1390*0Sstevel@tonic-gate     type = get_token(fp, token);
1391*0Sstevel@tonic-gate     if (type != READONLY && type != READWRITE && type != WRITEONLY
1392*0Sstevel@tonic-gate 	&& type != NOACCESS && type != READCREATE){
1393*0Sstevel@tonic-gate 	print_error("Bad access type", nexttoken, nexttype);
1394*0Sstevel@tonic-gate 	free_node(np);
1395*0Sstevel@tonic-gate 	return 0;
1396*0Sstevel@tonic-gate     }
1397*0Sstevel@tonic-gate 
1398*0Sstevel@tonic-gate /*
1399*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
1400*0Sstevel@tonic-gate */
1401*0Sstevel@tonic-gate 	switch(type)
1402*0Sstevel@tonic-gate 	{
1403*0Sstevel@tonic-gate 		case READONLY:
1404*0Sstevel@tonic-gate 			np->access = READ_FLAG;
1405*0Sstevel@tonic-gate 			break;
1406*0Sstevel@tonic-gate 
1407*0Sstevel@tonic-gate 		case READWRITE:
1408*0Sstevel@tonic-gate 			np->access = READ_FLAG | WRITE_FLAG;
1409*0Sstevel@tonic-gate 			break;
1410*0Sstevel@tonic-gate 
1411*0Sstevel@tonic-gate 		case WRITEONLY:
1412*0Sstevel@tonic-gate 			np->access = WRITE_FLAG;
1413*0Sstevel@tonic-gate 			break;
1414*0Sstevel@tonic-gate 
1415*0Sstevel@tonic-gate 		case NOACCESS:
1416*0Sstevel@tonic-gate 			np->access = 0;
1417*0Sstevel@tonic-gate 			break;
1418*0Sstevel@tonic-gate 
1419*0Sstevel@tonic-gate 		case READCREATE:
1420*0Sstevel@tonic-gate 			np->access = READ_FLAG | CREATE_FLAG;
1421*0Sstevel@tonic-gate 			break;
1422*0Sstevel@tonic-gate 	}
1423*0Sstevel@tonic-gate 
1424*0Sstevel@tonic-gate     type = get_token(fp, token);
1425*0Sstevel@tonic-gate     if (type != STATUS){
1426*0Sstevel@tonic-gate 	print_error("Should be STATUS", token, nexttype);
1427*0Sstevel@tonic-gate 	free_node(np);
1428*0Sstevel@tonic-gate 	return 0;
1429*0Sstevel@tonic-gate     }
1430*0Sstevel@tonic-gate     type = get_token(fp, token);
1431*0Sstevel@tonic-gate     if (type != MANDATORY && type != CURRENT && type != OPTIONAL && type != OBSOLETE && type != DEPRECATED){
1432*0Sstevel@tonic-gate 	print_error("Bad status", token, type);
1433*0Sstevel@tonic-gate 	free_node(np);
1434*0Sstevel@tonic-gate 	return 0;
1435*0Sstevel@tonic-gate     }
1436*0Sstevel@tonic-gate     /*
1437*0Sstevel@tonic-gate      * Optional parts of the OBJECT-TYPE macro
1438*0Sstevel@tonic-gate      */
1439*0Sstevel@tonic-gate     type = get_token(fp, token);
1440*0Sstevel@tonic-gate     while (type != EQUALS) {
1441*0Sstevel@tonic-gate       switch (type) {
1442*0Sstevel@tonic-gate         case DESCRIPTION:
1443*0Sstevel@tonic-gate           type = get_token(fp, token);
1444*0Sstevel@tonic-gate           if (type != QUOTESTRING) {
1445*0Sstevel@tonic-gate               print_error("Bad DESCRIPTION", token, type);
1446*0Sstevel@tonic-gate               free_node(np);
1447*0Sstevel@tonic-gate               return 0;
1448*0Sstevel@tonic-gate           }
1449*0Sstevel@tonic-gate #ifdef TEST
1450*0Sstevel@tonic-gate printf("Description== \"%.50s\"\n", quoted_string_buffer);
1451*0Sstevel@tonic-gate #endif
1452*0Sstevel@tonic-gate 	  np->description = quoted_string_buffer;
1453*0Sstevel@tonic-gate 	  quoted_string_buffer = (char *)malloc(MAXQUOTESTR);
1454*0Sstevel@tonic-gate 	  if (!quoted_string_buffer){
1455*0Sstevel@tonic-gate 	    fprintf(stderr, "malloc failed.  Exiting\n");
1456*0Sstevel@tonic-gate 	    exit(1);
1457*0Sstevel@tonic-gate 	  }
1458*0Sstevel@tonic-gate           break;
1459*0Sstevel@tonic-gate 
1460*0Sstevel@tonic-gate 	case REFERENCE:
1461*0Sstevel@tonic-gate 	  type = get_token(fp, token);
1462*0Sstevel@tonic-gate 	  if (type != QUOTESTRING) {
1463*0Sstevel@tonic-gate 	      print_error("Bad DESCRIPTION", token, type);
1464*0Sstevel@tonic-gate 	      free_node(np);
1465*0Sstevel@tonic-gate 	      return 0;
1466*0Sstevel@tonic-gate 	  }
1467*0Sstevel@tonic-gate 	  break;
1468*0Sstevel@tonic-gate /*
1469*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
1470*0Sstevel@tonic-gate */
1471*0Sstevel@tonic-gate        	case INDEX:
1472*0Sstevel@tonic-gate 		np->type = PSEUDO_TOKEN_ENTRY;
1473*0Sstevel@tonic-gate 
1474*0Sstevel@tonic-gate 		type = get_token(fp, token);
1475*0Sstevel@tonic-gate 		if(type != LEFTBRACKET)
1476*0Sstevel@tonic-gate 		{
1477*0Sstevel@tonic-gate 			print_error("{ expected in INDEX clause",token,type);
1478*0Sstevel@tonic-gate 			free_node(np);
1479*0Sstevel@tonic-gate 			return 0;
1480*0Sstevel@tonic-gate 		}
1481*0Sstevel@tonic-gate 		type = get_token(fp, token);
1482*0Sstevel@tonic-gate 		while(type != RIGHTBRACKET)
1483*0Sstevel@tonic-gate 		{
1484*0Sstevel@tonic-gate 			if(type != LABEL)
1485*0Sstevel@tonic-gate 			{
1486*0Sstevel@tonic-gate 				print_error("LABEL expected in INDEX clause",token,type);
1487*0Sstevel@tonic-gate 				free_node(np);
1488*0Sstevel@tonic-gate 				return 0;
1489*0Sstevel@tonic-gate 			}
1490*0Sstevel@tonic-gate 
1491*0Sstevel@tonic-gate 
1492*0Sstevel@tonic-gate 			(np->n_indexs)++;
1493*0Sstevel@tonic-gate 		    	if(np->indexs == NULL)
1494*0Sstevel@tonic-gate 			{
1495*0Sstevel@tonic-gate 				ip = np->indexs = (struct index_list *)
1496*0Sstevel@tonic-gate 					Malloc(sizeof(struct index_list));
1497*0Sstevel@tonic-gate 			}
1498*0Sstevel@tonic-gate 			else
1499*0Sstevel@tonic-gate 			{
1500*0Sstevel@tonic-gate 				ip->next = (struct index_list *)
1501*0Sstevel@tonic-gate 					Malloc(sizeof(struct enum_list));
1502*0Sstevel@tonic-gate 				ip = ip->next;
1503*0Sstevel@tonic-gate 			}
1504*0Sstevel@tonic-gate 			ip->next = 0;
1505*0Sstevel@tonic-gate 			ip->tp = NULL;
1506*0Sstevel@tonic-gate 
1507*0Sstevel@tonic-gate 			ip->label =
1508*0Sstevel@tonic-gate 				(char *)Malloc((unsigned)strlen(token) + 1);
1509*0Sstevel@tonic-gate 			strcpy(ip->label, token);
1510*0Sstevel@tonic-gate 
1511*0Sstevel@tonic-gate 			type = get_token(fp, token);
1512*0Sstevel@tonic-gate 
1513*0Sstevel@tonic-gate 			switch(type)
1514*0Sstevel@tonic-gate 			{
1515*0Sstevel@tonic-gate 				case COMMA:
1516*0Sstevel@tonic-gate 					type = get_token(fp, token);
1517*0Sstevel@tonic-gate 					break;
1518*0Sstevel@tonic-gate 
1519*0Sstevel@tonic-gate 				case RIGHTBRACKET:
1520*0Sstevel@tonic-gate 					break;
1521*0Sstevel@tonic-gate 
1522*0Sstevel@tonic-gate 				default:
1523*0Sstevel@tonic-gate 					print_error(", or } expected in INDEX clause",token,type);
1524*0Sstevel@tonic-gate 					free_node(np);
1525*0Sstevel@tonic-gate 					return 0;
1526*0Sstevel@tonic-gate 
1527*0Sstevel@tonic-gate 			}
1528*0Sstevel@tonic-gate 		}
1529*0Sstevel@tonic-gate 		break;
1530*0Sstevel@tonic-gate 
1531*0Sstevel@tonic-gate         case DEFVAL:
1532*0Sstevel@tonic-gate 	case AUGMENTS:
1533*0Sstevel@tonic-gate 	case NUM_ENTRIES:
1534*0Sstevel@tonic-gate           if (tossObjectIdentifier(fp) != PARSE_OBJID) {
1535*0Sstevel@tonic-gate               print_error("Bad Object Identifier", token, type);
1536*0Sstevel@tonic-gate               free_node(np);
1537*0Sstevel@tonic-gate               return 0;
1538*0Sstevel@tonic-gate           }
1539*0Sstevel@tonic-gate           break;
1540*0Sstevel@tonic-gate 
1541*0Sstevel@tonic-gate         default:
1542*0Sstevel@tonic-gate           print_error("Bad format of optional clauses", token,type);
1543*0Sstevel@tonic-gate           free_node(np);
1544*0Sstevel@tonic-gate           return 0;
1545*0Sstevel@tonic-gate 
1546*0Sstevel@tonic-gate       }
1547*0Sstevel@tonic-gate       type = get_token(fp, token);
1548*0Sstevel@tonic-gate     }
1549*0Sstevel@tonic-gate     if (type != EQUALS){
1550*0Sstevel@tonic-gate 	print_error("Bad format", token, type);
1551*0Sstevel@tonic-gate 	free_node(np);
1552*0Sstevel@tonic-gate 	return 0;
1553*0Sstevel@tonic-gate     }
1554*0Sstevel@tonic-gate     length = getoid(fp, oid, 32);
1555*0Sstevel@tonic-gate     if (length > 1 && length <= 32){
1556*0Sstevel@tonic-gate 	/* just take the last pair in the oid list */
1557*0Sstevel@tonic-gate 	if (oid[length - 2].label)
1558*0Sstevel@tonic-gate 	    strncpy(np->parent, oid[length - 2].label, MAXLABEL);
1559*0Sstevel@tonic-gate 	strcpy(np->label, name);
1560*0Sstevel@tonic-gate 	if (oid[length - 1].subid != -1)
1561*0Sstevel@tonic-gate 	    np->subid = oid[length - 1].subid;
1562*0Sstevel@tonic-gate 	else
1563*0Sstevel@tonic-gate 	    print_error("Warning: This entry is pretty silly", np->label, type);
1564*0Sstevel@tonic-gate     } else {
1565*0Sstevel@tonic-gate 	print_error("No end to oid", (char *)NULL, type);
1566*0Sstevel@tonic-gate 	free_node(np);
1567*0Sstevel@tonic-gate 	np = 0;
1568*0Sstevel@tonic-gate     }
1569*0Sstevel@tonic-gate     /* free oid array */
1570*0Sstevel@tonic-gate     for(count = 0; count < length; count++){
1571*0Sstevel@tonic-gate 	if (oid[count].label)
1572*0Sstevel@tonic-gate 	    free(oid[count].label);
1573*0Sstevel@tonic-gate 	oid[count].label = 0;
1574*0Sstevel@tonic-gate     }
1575*0Sstevel@tonic-gate     return np;
1576*0Sstevel@tonic-gate }
1577*0Sstevel@tonic-gate 
1578*0Sstevel@tonic-gate 
1579*0Sstevel@tonic-gate /*
1580*0Sstevel@tonic-gate  * Parses an OBJECT GROUP macro.
1581*0Sstevel@tonic-gate  * Returns 0 on error.
1582*0Sstevel@tonic-gate  */
1583*0Sstevel@tonic-gate static struct node *
1584*0Sstevel@tonic-gate parse_objectgroup(fp, name)
1585*0Sstevel@tonic-gate     register FILE *fp;
1586*0Sstevel@tonic-gate     char *name;
1587*0Sstevel@tonic-gate {
1588*0Sstevel@tonic-gate     register int type;
1589*0Sstevel@tonic-gate     char token[MAXTOKEN];
1590*0Sstevel@tonic-gate     int count, length;
1591*0Sstevel@tonic-gate     struct subid oid[32];
1592*0Sstevel@tonic-gate     register struct node *np;
1593*0Sstevel@tonic-gate 
1594*0Sstevel@tonic-gate     np = (struct node *)Malloc(sizeof(struct node));
1595*0Sstevel@tonic-gate     np->type = 0;
1596*0Sstevel@tonic-gate     np->next = 0;
1597*0Sstevel@tonic-gate     np->enums = 0;
1598*0Sstevel@tonic-gate     np->description = NULL;        /* default to an empty description */
1599*0Sstevel@tonic-gate 
1600*0Sstevel@tonic-gate /*
1601*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
1602*0Sstevel@tonic-gate */
1603*0Sstevel@tonic-gate 	np->access = 0;
1604*0Sstevel@tonic-gate 	np->n_indexs = 0;
1605*0Sstevel@tonic-gate 	np->indexs = 0;
1606*0Sstevel@tonic-gate 
1607*0Sstevel@tonic-gate     type = get_token(fp, token);
1608*0Sstevel@tonic-gate     while (type != EQUALS) {
1609*0Sstevel@tonic-gate       switch (type) {
1610*0Sstevel@tonic-gate         case DESCRIPTION:
1611*0Sstevel@tonic-gate           type = get_token(fp, token);
1612*0Sstevel@tonic-gate           if (type != QUOTESTRING) {
1613*0Sstevel@tonic-gate               print_error("Bad DESCRIPTION", token, type);
1614*0Sstevel@tonic-gate               free_node(np);
1615*0Sstevel@tonic-gate               return 0;
1616*0Sstevel@tonic-gate           }
1617*0Sstevel@tonic-gate #ifdef TEST
1618*0Sstevel@tonic-gate printf("Description== \"%.50s\"\n", quoted_string_buffer);
1619*0Sstevel@tonic-gate #endif
1620*0Sstevel@tonic-gate 	  np->description = quoted_string_buffer;
1621*0Sstevel@tonic-gate 	  quoted_string_buffer = (char *)malloc(MAXQUOTESTR);
1622*0Sstevel@tonic-gate 	  if (!quoted_string_buffer){
1623*0Sstevel@tonic-gate 	    fprintf(stderr, "malloc failed.  Exiting\n");
1624*0Sstevel@tonic-gate 	    exit(1);
1625*0Sstevel@tonic-gate 	  }
1626*0Sstevel@tonic-gate           break;
1627*0Sstevel@tonic-gate 
1628*0Sstevel@tonic-gate         default:
1629*0Sstevel@tonic-gate 	  /* NOTHING */
1630*0Sstevel@tonic-gate 	  break;
1631*0Sstevel@tonic-gate       }
1632*0Sstevel@tonic-gate       type = get_token(fp, token);
1633*0Sstevel@tonic-gate     }
1634*0Sstevel@tonic-gate     length = getoid(fp, oid, 32);
1635*0Sstevel@tonic-gate     if (length > 1 && length <= 32){
1636*0Sstevel@tonic-gate 	/* just take the last pair in the oid list */
1637*0Sstevel@tonic-gate 	if (oid[length - 2].label)
1638*0Sstevel@tonic-gate 	    strncpy(np->parent, oid[length - 2].label, MAXLABEL);
1639*0Sstevel@tonic-gate 	strcpy(np->label, name);
1640*0Sstevel@tonic-gate 	if (oid[length - 1].subid != -1)
1641*0Sstevel@tonic-gate 	    np->subid = oid[length - 1].subid;
1642*0Sstevel@tonic-gate 	else
1643*0Sstevel@tonic-gate 	    print_error("Warning: This entry is pretty silly", np->label, type);
1644*0Sstevel@tonic-gate     } else {
1645*0Sstevel@tonic-gate 	print_error("No end to oid", (char *)NULL, type);
1646*0Sstevel@tonic-gate 	free_node(np);
1647*0Sstevel@tonic-gate 	np = 0;
1648*0Sstevel@tonic-gate     }
1649*0Sstevel@tonic-gate     /* free oid array */
1650*0Sstevel@tonic-gate     for(count = 0; count < length; count++){
1651*0Sstevel@tonic-gate 	if (oid[count].label)
1652*0Sstevel@tonic-gate 	    free(oid[count].label);
1653*0Sstevel@tonic-gate 	oid[count].label = 0;
1654*0Sstevel@tonic-gate     }
1655*0Sstevel@tonic-gate     return np;
1656*0Sstevel@tonic-gate }
1657*0Sstevel@tonic-gate 
1658*0Sstevel@tonic-gate /*
1659*0Sstevel@tonic-gate  * Parses a NOTIFICATION-TYPE macro.
1660*0Sstevel@tonic-gate  * Returns 0 on error.
1661*0Sstevel@tonic-gate  */
1662*0Sstevel@tonic-gate static struct node *
1663*0Sstevel@tonic-gate parse_notificationDefinition(fp, name)
1664*0Sstevel@tonic-gate     register FILE *fp;
1665*0Sstevel@tonic-gate     char *name;
1666*0Sstevel@tonic-gate {
1667*0Sstevel@tonic-gate     register int type;
1668*0Sstevel@tonic-gate     char token[MAXTOKEN];
1669*0Sstevel@tonic-gate     int count, length;
1670*0Sstevel@tonic-gate     struct subid oid[32];
1671*0Sstevel@tonic-gate     register struct node *np;
1672*0Sstevel@tonic-gate 
1673*0Sstevel@tonic-gate     np = (struct node *)Malloc(sizeof(struct node));
1674*0Sstevel@tonic-gate     np->type = 0;
1675*0Sstevel@tonic-gate     np->next = 0;
1676*0Sstevel@tonic-gate     np->enums = 0;
1677*0Sstevel@tonic-gate     np->description = NULL;        /* default to an empty description */
1678*0Sstevel@tonic-gate /*
1679*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
1680*0Sstevel@tonic-gate */
1681*0Sstevel@tonic-gate 	np->access = 0;
1682*0Sstevel@tonic-gate 	np->n_indexs = 0;
1683*0Sstevel@tonic-gate 	np->indexs = 0;
1684*0Sstevel@tonic-gate 
1685*0Sstevel@tonic-gate     type = get_token(fp, token);
1686*0Sstevel@tonic-gate     while (type != EQUALS) {
1687*0Sstevel@tonic-gate       switch (type) {
1688*0Sstevel@tonic-gate         case DESCRIPTION:
1689*0Sstevel@tonic-gate           type = get_token(fp, token);
1690*0Sstevel@tonic-gate           if (type != QUOTESTRING) {
1691*0Sstevel@tonic-gate               print_error("Bad DESCRIPTION", token, type);
1692*0Sstevel@tonic-gate               free_node(np);
1693*0Sstevel@tonic-gate               return 0;
1694*0Sstevel@tonic-gate           }
1695*0Sstevel@tonic-gate #ifdef TEST
1696*0Sstevel@tonic-gate printf("Description== \"%.50s\"\n", quoted_string_buffer);
1697*0Sstevel@tonic-gate #endif
1698*0Sstevel@tonic-gate 	  np->description = quoted_string_buffer;
1699*0Sstevel@tonic-gate 	  quoted_string_buffer = (char *)malloc(MAXQUOTESTR);
1700*0Sstevel@tonic-gate 	  if (!quoted_string_buffer){
1701*0Sstevel@tonic-gate 	    fprintf(stderr, "malloc failed.  Exiting\n");
1702*0Sstevel@tonic-gate 	    exit(1);
1703*0Sstevel@tonic-gate 	  }
1704*0Sstevel@tonic-gate           break;
1705*0Sstevel@tonic-gate 
1706*0Sstevel@tonic-gate         default:
1707*0Sstevel@tonic-gate 	  /* NOTHING */
1708*0Sstevel@tonic-gate 	  break;
1709*0Sstevel@tonic-gate       }
1710*0Sstevel@tonic-gate       type = get_token(fp, token);
1711*0Sstevel@tonic-gate     }
1712*0Sstevel@tonic-gate     length = getoid(fp, oid, 32);
1713*0Sstevel@tonic-gate     if (length > 1 && length <= 32){
1714*0Sstevel@tonic-gate 	/* just take the last pair in the oid list */
1715*0Sstevel@tonic-gate 	if (oid[length - 2].label)
1716*0Sstevel@tonic-gate 	    strncpy(np->parent, oid[length - 2].label, MAXLABEL);
1717*0Sstevel@tonic-gate 	strcpy(np->label, name);
1718*0Sstevel@tonic-gate 	if (oid[length - 1].subid != -1)
1719*0Sstevel@tonic-gate 	    np->subid = oid[length - 1].subid;
1720*0Sstevel@tonic-gate 	else
1721*0Sstevel@tonic-gate 	    print_error("Warning: This entry is pretty silly", np->label, type);
1722*0Sstevel@tonic-gate     } else {
1723*0Sstevel@tonic-gate 	print_error("No end to oid", (char *)NULL, type);
1724*0Sstevel@tonic-gate 	free_node(np);
1725*0Sstevel@tonic-gate 	np = 0;
1726*0Sstevel@tonic-gate     }
1727*0Sstevel@tonic-gate     /* free oid array */
1728*0Sstevel@tonic-gate     for(count = 0; count < length; count++){
1729*0Sstevel@tonic-gate 	if (oid[count].label)
1730*0Sstevel@tonic-gate 	    free(oid[count].label);
1731*0Sstevel@tonic-gate 	oid[count].label = 0;
1732*0Sstevel@tonic-gate     }
1733*0Sstevel@tonic-gate     return np;
1734*0Sstevel@tonic-gate }
1735*0Sstevel@tonic-gate 
1736*0Sstevel@tonic-gate /*
1737*0Sstevel@tonic-gate  * Parses a compliance macro
1738*0Sstevel@tonic-gate  * Returns 0 on error.
1739*0Sstevel@tonic-gate  */
1740*0Sstevel@tonic-gate static struct node *
1741*0Sstevel@tonic-gate parse_compliance(fp, name)
1742*0Sstevel@tonic-gate     register FILE *fp;
1743*0Sstevel@tonic-gate     char *name;
1744*0Sstevel@tonic-gate {
1745*0Sstevel@tonic-gate     register int type;
1746*0Sstevel@tonic-gate     char token[MAXTOKEN];
1747*0Sstevel@tonic-gate     int count, length;
1748*0Sstevel@tonic-gate     struct subid oid[32];
1749*0Sstevel@tonic-gate     register struct node *np;
1750*0Sstevel@tonic-gate 
1751*0Sstevel@tonic-gate     np = (struct node *)Malloc(sizeof(struct node));
1752*0Sstevel@tonic-gate     np->type = 0;
1753*0Sstevel@tonic-gate     np->next = 0;
1754*0Sstevel@tonic-gate     np->enums = 0;
1755*0Sstevel@tonic-gate     np->description = NULL;        /* default to an empty description */
1756*0Sstevel@tonic-gate /*
1757*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
1758*0Sstevel@tonic-gate */
1759*0Sstevel@tonic-gate 	np->access = 0;
1760*0Sstevel@tonic-gate 	np->n_indexs = 0;
1761*0Sstevel@tonic-gate 	np->indexs = 0;
1762*0Sstevel@tonic-gate 
1763*0Sstevel@tonic-gate     type = get_token(fp, token);
1764*0Sstevel@tonic-gate     while (type != EQUALS) {
1765*0Sstevel@tonic-gate 	type = get_token(fp, token);
1766*0Sstevel@tonic-gate     }
1767*0Sstevel@tonic-gate     length = getoid(fp, oid, 32);
1768*0Sstevel@tonic-gate     if (length > 1 && length <= 32){
1769*0Sstevel@tonic-gate 	/* just take the last pair in the oid list */
1770*0Sstevel@tonic-gate 	if (oid[length - 2].label)
1771*0Sstevel@tonic-gate 	    strncpy(np->parent, oid[length - 2].label, MAXLABEL);
1772*0Sstevel@tonic-gate 	strcpy(np->label, name);
1773*0Sstevel@tonic-gate 	if (oid[length - 1].subid != -1)
1774*0Sstevel@tonic-gate 	    np->subid = oid[length - 1].subid;
1775*0Sstevel@tonic-gate 	else
1776*0Sstevel@tonic-gate 	    print_error("Warning: This entry is pretty silly", np->label, type);
1777*0Sstevel@tonic-gate     } else {
1778*0Sstevel@tonic-gate 	print_error("No end to oid", (char *)NULL, type);
1779*0Sstevel@tonic-gate 	free_node(np);
1780*0Sstevel@tonic-gate 	np = 0;
1781*0Sstevel@tonic-gate     }
1782*0Sstevel@tonic-gate     /* free oid array */
1783*0Sstevel@tonic-gate     for(count = 0; count < length; count++){
1784*0Sstevel@tonic-gate 	if (oid[count].label)
1785*0Sstevel@tonic-gate 	    free(oid[count].label);
1786*0Sstevel@tonic-gate 	oid[count].label = 0;
1787*0Sstevel@tonic-gate     }
1788*0Sstevel@tonic-gate     return np;
1789*0Sstevel@tonic-gate }
1790*0Sstevel@tonic-gate 
1791*0Sstevel@tonic-gate 
1792*0Sstevel@tonic-gate 
1793*0Sstevel@tonic-gate /*
1794*0Sstevel@tonic-gate  * Parses a module identity macro
1795*0Sstevel@tonic-gate  * Returns 0 on error.
1796*0Sstevel@tonic-gate  */
1797*0Sstevel@tonic-gate static struct node *
1798*0Sstevel@tonic-gate parse_moduleIdentity(fp, name)
1799*0Sstevel@tonic-gate     register FILE *fp;
1800*0Sstevel@tonic-gate     char *name;
1801*0Sstevel@tonic-gate {
1802*0Sstevel@tonic-gate     register int type;
1803*0Sstevel@tonic-gate     char token[MAXTOKEN];
1804*0Sstevel@tonic-gate     int count, length;
1805*0Sstevel@tonic-gate     struct subid oid[32];
1806*0Sstevel@tonic-gate     register struct node *np;
1807*0Sstevel@tonic-gate 
1808*0Sstevel@tonic-gate     np = (struct node *)Malloc(sizeof(struct node));
1809*0Sstevel@tonic-gate     np->type = 0;
1810*0Sstevel@tonic-gate     np->next = 0;
1811*0Sstevel@tonic-gate     np->enums = 0;
1812*0Sstevel@tonic-gate     np->description = NULL;        /* default to an empty description */
1813*0Sstevel@tonic-gate /*
1814*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
1815*0Sstevel@tonic-gate */
1816*0Sstevel@tonic-gate 	np->n_indexs = 0;
1817*0Sstevel@tonic-gate 	np->indexs = 0;
1818*0Sstevel@tonic-gate 	np->access = 0;
1819*0Sstevel@tonic-gate 
1820*0Sstevel@tonic-gate     type = get_token(fp, token);
1821*0Sstevel@tonic-gate     while (type != EQUALS) {
1822*0Sstevel@tonic-gate 	type = get_token(fp, token);
1823*0Sstevel@tonic-gate     }
1824*0Sstevel@tonic-gate     length = getoid(fp, oid, 32);
1825*0Sstevel@tonic-gate     if (length > 1 && length <= 32){
1826*0Sstevel@tonic-gate 	/* just take the last pair in the oid list */
1827*0Sstevel@tonic-gate 	if (oid[length - 2].label)
1828*0Sstevel@tonic-gate 	    strncpy(np->parent, oid[length - 2].label, MAXLABEL);
1829*0Sstevel@tonic-gate 	strcpy(np->label, name);
1830*0Sstevel@tonic-gate 	if (oid[length - 1].subid != -1)
1831*0Sstevel@tonic-gate 	    np->subid = oid[length - 1].subid;
1832*0Sstevel@tonic-gate 	else
1833*0Sstevel@tonic-gate 	    print_error("Warning: This entry is pretty silly", np->label, type);
1834*0Sstevel@tonic-gate     } else {
1835*0Sstevel@tonic-gate 	print_error("No end to oid", (char *)NULL, type);
1836*0Sstevel@tonic-gate 	free_node(np);
1837*0Sstevel@tonic-gate 	np = 0;
1838*0Sstevel@tonic-gate     }
1839*0Sstevel@tonic-gate     /* free oid array */
1840*0Sstevel@tonic-gate     for(count = 0; count < length; count++){
1841*0Sstevel@tonic-gate 	if (oid[count].label)
1842*0Sstevel@tonic-gate 	    free(oid[count].label);
1843*0Sstevel@tonic-gate 	oid[count].label = 0;
1844*0Sstevel@tonic-gate     }
1845*0Sstevel@tonic-gate     return np;
1846*0Sstevel@tonic-gate }
1847*0Sstevel@tonic-gate 
1848*0Sstevel@tonic-gate int parse_mib_header(fp, name)
1849*0Sstevel@tonic-gate     register FILE *fp;
1850*0Sstevel@tonic-gate     char *name;
1851*0Sstevel@tonic-gate {
1852*0Sstevel@tonic-gate     int type = DEFINITIONS;
1853*0Sstevel@tonic-gate     char token[MAXTOKEN];
1854*0Sstevel@tonic-gate 
1855*0Sstevel@tonic-gate #ifdef TRACE_PROC
1856*0Sstevel@tonic-gate printf("parse_mib_header() invoked\n");
1857*0Sstevel@tonic-gate #endif
1858*0Sstevel@tonic-gate 
1859*0Sstevel@tonic-gate     /* This probably isn't good enough.  If there is no
1860*0Sstevel@tonic-gate        imports clause we can't go around waiting (forever) for a semicolon.
1861*0Sstevel@tonic-gate        We need to check for semi following an EXPORTS clause or an IMPORTS
1862*0Sstevel@tonic-gate        clause of both.  Look for BEGIN; in my initial MIBs to see those
1863*0Sstevel@tonic-gate        that I needed to hack to get to parse because they didn't have
1864*0Sstevel@tonic-gate        an IMPORTS or and EXPORTS clause.
1865*0Sstevel@tonic-gate        */
1866*0Sstevel@tonic-gate     while(type != SEMI){
1867*0Sstevel@tonic-gate 	type = get_token(fp, token);
1868*0Sstevel@tonic-gate     }
1869*0Sstevel@tonic-gate     return 1;
1870*0Sstevel@tonic-gate }
1871*0Sstevel@tonic-gate 
1872*0Sstevel@tonic-gate 
1873*0Sstevel@tonic-gate /*
1874*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
1875*0Sstevel@tonic-gate */
1876*0Sstevel@tonic-gate void parse_init()
1877*0Sstevel@tonic-gate {
1878*0Sstevel@tonic-gate 	hash_init();
1879*0Sstevel@tonic-gate 	memset((void *) tclist, 0, 64 * sizeof(struct tc));
1880*0Sstevel@tonic-gate }
1881*0Sstevel@tonic-gate 
1882*0Sstevel@tonic-gate 
1883*0Sstevel@tonic-gate /*
1884*0Sstevel@tonic-gate  * Parses a mib file and returns a linked list of nodes found in the file.
1885*0Sstevel@tonic-gate  * Returns NULL on error.
1886*0Sstevel@tonic-gate  */
1887*0Sstevel@tonic-gate /*
1888*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
1889*0Sstevel@tonic-gate static struct node *
1890*0Sstevel@tonic-gate */
1891*0Sstevel@tonic-gate struct node *
1892*0Sstevel@tonic-gate parse(fp)
1893*0Sstevel@tonic-gate     FILE *fp;
1894*0Sstevel@tonic-gate {
1895*0Sstevel@tonic-gate     char token[MAXTOKEN];
1896*0Sstevel@tonic-gate     char name[MAXTOKEN];
1897*0Sstevel@tonic-gate     int	type = 1;
1898*0Sstevel@tonic-gate #define BETWEEN_MIBS  	      1
1899*0Sstevel@tonic-gate #define IN_MIB                2
1900*0Sstevel@tonic-gate     int state = BETWEEN_MIBS;
1901*0Sstevel@tonic-gate     struct node *np, *root = NULL;
1902*0Sstevel@tonic-gate 
1903*0Sstevel@tonic-gate #ifdef TRACE_PROC
1904*0Sstevel@tonic-gate printf("parse() invoked\n");
1905*0Sstevel@tonic-gate #endif
1906*0Sstevel@tonic-gate 
1907*0Sstevel@tonic-gate /*
1908*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
1909*0Sstevel@tonic-gate     hash_init();
1910*0Sstevel@tonic-gate */
1911*0Sstevel@tonic-gate     Line = 1;
1912*0Sstevel@tonic-gate 
1913*0Sstevel@tonic-gate     quoted_string_buffer = (char *)malloc(MAXQUOTESTR);  /* free this later */
1914*0Sstevel@tonic-gate     if (!quoted_string_buffer){
1915*0Sstevel@tonic-gate       fprintf(stderr, "malloc failed.  Exiting\n");
1916*0Sstevel@tonic-gate       exit(1);
1917*0Sstevel@tonic-gate     }
1918*0Sstevel@tonic-gate 
1919*0Sstevel@tonic-gate /*
1920*0Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
1921*0Sstevel@tonic-gate     bzero(tclist, 64 * sizeof(struct tc));
1922*0Sstevel@tonic-gate */
1923*0Sstevel@tonic-gate 
1924*0Sstevel@tonic-gate     while(type != ENDOFFILE){
1925*0Sstevel@tonic-gate 	type = get_token(fp, token);
1926*0Sstevel@tonic-gate skipget:
1927*0Sstevel@tonic-gate 	if (type == END){
1928*0Sstevel@tonic-gate 	    if (state != IN_MIB){
1929*0Sstevel@tonic-gate 		print_error("Error, end before start of MIB.", (char *)NULL, type);
1930*0Sstevel@tonic-gate 		return NULL;
1931*0Sstevel@tonic-gate 	    }
1932*0Sstevel@tonic-gate 	    state = BETWEEN_MIBS;
1933*0Sstevel@tonic-gate 	    continue;
1934*0Sstevel@tonic-gate 	} else if (type != LABEL){
1935*0Sstevel@tonic-gate 	    if (type == ENDOFFILE){
1936*0Sstevel@tonic-gate 		return root;
1937*0Sstevel@tonic-gate 	    }
1938*0Sstevel@tonic-gate 	    print_error(token, "is a reserved word", type);
1939*0Sstevel@tonic-gate 	    return NULL;
1940*0Sstevel@tonic-gate 	}
1941*0Sstevel@tonic-gate 	strncpy(name, token, MAXTOKEN);
1942*0Sstevel@tonic-gate 	type = get_token(fp, token);
1943*0Sstevel@tonic-gate 	if (type == DEFINITIONS){
1944*0Sstevel@tonic-gate 	    if (state != BETWEEN_MIBS){
1945*0Sstevel@tonic-gate 		print_error("Error, nested MIBS.", (char *)NULL, type);
1946*0Sstevel@tonic-gate 		return NULL;
1947*0Sstevel@tonic-gate 	    }
1948*0Sstevel@tonic-gate 	    state = IN_MIB;
1949*0Sstevel@tonic-gate 	    if (!parse_mib_header(fp, name)){
1950*0Sstevel@tonic-gate 		print_error("Bad parse of module header", (char *)NULL, type);
1951*0Sstevel@tonic-gate 		return NULL;
1952*0Sstevel@tonic-gate 	    }
1953*0Sstevel@tonic-gate        } else if (type == OBJTYPE){
1954*0Sstevel@tonic-gate 	    if (root == NULL){
1955*0Sstevel@tonic-gate 		/* first link in chain */
1956*0Sstevel@tonic-gate 		np = root = parse_objecttype(fp, name);
1957*0Sstevel@tonic-gate 		if (np == NULL){
1958*0Sstevel@tonic-gate 		    print_error("Bad parse of object type", (char *)NULL,
1959*0Sstevel@tonic-gate 				type);
1960*0Sstevel@tonic-gate 		    return NULL;
1961*0Sstevel@tonic-gate 		}
1962*0Sstevel@tonic-gate 	    } else {
1963*0Sstevel@tonic-gate 		np->next = parse_objecttype(fp, name);
1964*0Sstevel@tonic-gate 		if (np->next == NULL){
1965*0Sstevel@tonic-gate 		    print_error("Bad parse of objecttype", (char *)NULL,
1966*0Sstevel@tonic-gate 				type);
1967*0Sstevel@tonic-gate 		    return NULL;
1968*0Sstevel@tonic-gate 		}
1969*0Sstevel@tonic-gate 	    }
1970*0Sstevel@tonic-gate 	    /* now find end of chain */
1971*0Sstevel@tonic-gate 	    while(np->next)
1972*0Sstevel@tonic-gate 		np = np->next;
1973*0Sstevel@tonic-gate 	} else if (type == OBJGROUP){
1974*0Sstevel@tonic-gate 	    if (root == NULL){
1975*0Sstevel@tonic-gate 		/* first link in chain */
1976*0Sstevel@tonic-gate 		np = root = parse_objectgroup(fp, name);
1977*0Sstevel@tonic-gate 		if (np == NULL){
1978*0Sstevel@tonic-gate 		    print_error("Bad parse of object group", (char *)NULL,
1979*0Sstevel@tonic-gate 				type);
1980*0Sstevel@tonic-gate 		    return NULL;
1981*0Sstevel@tonic-gate 		}
1982*0Sstevel@tonic-gate 	    } else {
1983*0Sstevel@tonic-gate 		np->next = parse_objectgroup(fp, name);
1984*0Sstevel@tonic-gate 		if (np->next == NULL){
1985*0Sstevel@tonic-gate 		    print_error("Bad parse of objectgroup", (char *)NULL,
1986*0Sstevel@tonic-gate 				type);
1987*0Sstevel@tonic-gate 		    return NULL;
1988*0Sstevel@tonic-gate 		}
1989*0Sstevel@tonic-gate 	    }
1990*0Sstevel@tonic-gate 	    /* now find end of chain */
1991*0Sstevel@tonic-gate 	    while(np->next)
1992*0Sstevel@tonic-gate 		np = np->next;
1993*0Sstevel@tonic-gate 	} else if (type == NOTIFTYPE){
1994*0Sstevel@tonic-gate 	    if (root == NULL){
1995*0Sstevel@tonic-gate 		/* first link in chain */
1996*0Sstevel@tonic-gate 		np = root = parse_notificationDefinition(fp, name);
1997*0Sstevel@tonic-gate 		if (np == NULL){
1998*0Sstevel@tonic-gate 		    print_error("Bad parse of notification definition",
1999*0Sstevel@tonic-gate 				(char *)NULL, type);
2000*0Sstevel@tonic-gate 		    return NULL;
2001*0Sstevel@tonic-gate 		}
2002*0Sstevel@tonic-gate 	    } else {
2003*0Sstevel@tonic-gate 		np->next = parse_notificationDefinition(fp, name);
2004*0Sstevel@tonic-gate 		if (np->next == NULL){
2005*0Sstevel@tonic-gate 		    print_error("Bad parse of notification definition",
2006*0Sstevel@tonic-gate 				(char *)NULL, type);
2007*0Sstevel@tonic-gate 		    return NULL;
2008*0Sstevel@tonic-gate 		}
2009*0Sstevel@tonic-gate 	    }
2010*0Sstevel@tonic-gate 	    /* now find end of chain */
2011*0Sstevel@tonic-gate 	    while(np->next)
2012*0Sstevel@tonic-gate 		np = np->next;
2013*0Sstevel@tonic-gate 	} else if (type == COMPLIANCE){
2014*0Sstevel@tonic-gate 	    if (root == NULL){
2015*0Sstevel@tonic-gate 		/* first link in chain */
2016*0Sstevel@tonic-gate 		np = root = parse_compliance(fp, name);
2017*0Sstevel@tonic-gate 		if (np == NULL){
2018*0Sstevel@tonic-gate 		    print_error("Bad parse of module compliance", (char *)NULL,
2019*0Sstevel@tonic-gate 				type);
2020*0Sstevel@tonic-gate 		    return NULL;
2021*0Sstevel@tonic-gate 		}
2022*0Sstevel@tonic-gate 	    } else {
2023*0Sstevel@tonic-gate 		np->next = parse_compliance(fp, name);
2024*0Sstevel@tonic-gate 		if (np->next == NULL){
2025*0Sstevel@tonic-gate 		    print_error("Bad parse of module compliance", (char *)NULL,
2026*0Sstevel@tonic-gate 				type);
2027*0Sstevel@tonic-gate 		    return NULL;
2028*0Sstevel@tonic-gate 		}
2029*0Sstevel@tonic-gate 	    }
2030*0Sstevel@tonic-gate 	    /* now find end of chain */
2031*0Sstevel@tonic-gate 	    while(np->next)
2032*0Sstevel@tonic-gate 		np = np->next;
2033*0Sstevel@tonic-gate 	} else if (type == MODULEIDENTITY){
2034*0Sstevel@tonic-gate 	    if (root == NULL){
2035*0Sstevel@tonic-gate 		/* first link in chain */
2036*0Sstevel@tonic-gate 		np = root = parse_moduleIdentity(fp, name);
2037*0Sstevel@tonic-gate 		if (np == NULL){
2038*0Sstevel@tonic-gate 		    print_error("Bad parse of module identity", (char *)NULL,
2039*0Sstevel@tonic-gate 				type);
2040*0Sstevel@tonic-gate 		    return NULL;
2041*0Sstevel@tonic-gate 		}
2042*0Sstevel@tonic-gate 	    } else {
2043*0Sstevel@tonic-gate 		np->next = parse_moduleIdentity(fp, name);
2044*0Sstevel@tonic-gate 		if (np->next == NULL){
2045*0Sstevel@tonic-gate 		    print_error("Bad parse of module identity", (char *)NULL,
2046*0Sstevel@tonic-gate 				type);
2047*0Sstevel@tonic-gate 		    return NULL;
2048*0Sstevel@tonic-gate 		}
2049*0Sstevel@tonic-gate 	    }
2050*0Sstevel@tonic-gate 	    /* now find end of chain */
2051*0Sstevel@tonic-gate 	    while(np->next)
2052*0Sstevel@tonic-gate 		np = np->next;
2053*0Sstevel@tonic-gate 	} else if (type == PARSE_OBJID){
2054*0Sstevel@tonic-gate 	    if (root == NULL){
2055*0Sstevel@tonic-gate 		/* first link in chain */
2056*0Sstevel@tonic-gate 		np = root = parse_objectid(fp, name);
2057*0Sstevel@tonic-gate 		if (np == NULL){
2058*0Sstevel@tonic-gate 		    print_error("Bad parse of object id", (char *)NULL, type);
2059*0Sstevel@tonic-gate 		    return NULL;
2060*0Sstevel@tonic-gate 		}
2061*0Sstevel@tonic-gate 	    } else {
2062*0Sstevel@tonic-gate 		np->next = parse_objectid(fp, name);
2063*0Sstevel@tonic-gate 		if (np->next == NULL){
2064*0Sstevel@tonic-gate 		    print_error("Bad parse of object type", (char *)NULL,
2065*0Sstevel@tonic-gate 				type);
2066*0Sstevel@tonic-gate 		    return NULL;
2067*0Sstevel@tonic-gate 		}
2068*0Sstevel@tonic-gate 	    }
2069*0Sstevel@tonic-gate 	    /* now find end of chain */
2070*0Sstevel@tonic-gate 	    while(np->next)
2071*0Sstevel@tonic-gate 		np = np->next;
2072*0Sstevel@tonic-gate 	} else if (type == EQUALS){
2073*0Sstevel@tonic-gate 	    if (!parse_asntype(fp, name, &type, token)){
2074*0Sstevel@tonic-gate 		print_error("Bad parse of ASN type definition.", (char*)NULL, EQUALS);
2075*0Sstevel@tonic-gate 		return NULL;
2076*0Sstevel@tonic-gate 	    }
2077*0Sstevel@tonic-gate 	    goto skipget;
2078*0Sstevel@tonic-gate 	} else if (type == TRAPTYPE){ /* Jerry Yeung 6-6-96 */
2079*0Sstevel@tonic-gate 	    if(!parse_traptype(fp,name)){
2080*0Sstevel@tonic-gate 		 print_error("Bad parse of TRAP type",(char*)NULL,type);
2081*0Sstevel@tonic-gate 		 return NULL;
2082*0Sstevel@tonic-gate 	    }
2083*0Sstevel@tonic-gate 	} else if (type == ENDOFFILE){
2084*0Sstevel@tonic-gate 	    break;
2085*0Sstevel@tonic-gate 	} else {
2086*0Sstevel@tonic-gate 	    print_error("Bad operator", (char *)NULL, type);
2087*0Sstevel@tonic-gate 	    return NULL;
2088*0Sstevel@tonic-gate 	}
2089*0Sstevel@tonic-gate     }
2090*0Sstevel@tonic-gate #ifdef TEST
2091*0Sstevel@tonic-gate {
2092*0Sstevel@tonic-gate     struct enum_list *ep;
2093*0Sstevel@tonic-gate 
2094*0Sstevel@tonic-gate     for(np = root; np; np = np->next){
2095*0Sstevel@tonic-gate 	printf("%s ::= { %s %d } (%d)\n", np->label, np->parent, np->subid,
2096*0Sstevel@tonic-gate 		np->type);
2097*0Sstevel@tonic-gate 	if (np->enums){
2098*0Sstevel@tonic-gate 	    printf("Enums: \n");
2099*0Sstevel@tonic-gate 	    for(ep = np->enums; ep; ep = ep->next){
2100*0Sstevel@tonic-gate 		printf("%s(%d)\n", ep->label, ep->value);
2101*0Sstevel@tonic-gate 	    }
2102*0Sstevel@tonic-gate 	}
2103*0Sstevel@tonic-gate     }
2104*0Sstevel@tonic-gate }
2105*0Sstevel@tonic-gate #endif /* TEST */
2106*0Sstevel@tonic-gate     return root;
2107*0Sstevel@tonic-gate }
2108*0Sstevel@tonic-gate 
2109*0Sstevel@tonic-gate /*
2110*0Sstevel@tonic-gate  * Parses a token from the file.  The type of the token parsed is returned,
2111*0Sstevel@tonic-gate  * and the text is placed in the string pointed to by token.
2112*0Sstevel@tonic-gate  */
2113*0Sstevel@tonic-gate static int
2114*0Sstevel@tonic-gate get_token(fp, token)
2115*0Sstevel@tonic-gate     register FILE *fp;
2116*0Sstevel@tonic-gate     register char *token;
2117*0Sstevel@tonic-gate {
2118*0Sstevel@tonic-gate     static char last = ' ';
2119*0Sstevel@tonic-gate     register int ch;
2120*0Sstevel@tonic-gate     register char *cp = token;
2121*0Sstevel@tonic-gate     register int hash = 0;
2122*0Sstevel@tonic-gate     register struct tok *tp;
2123*0Sstevel@tonic-gate 
2124*0Sstevel@tonic-gate     *cp = 0;
2125*0Sstevel@tonic-gate     ch = last;
2126*0Sstevel@tonic-gate     /* skip all white space */
2127*0Sstevel@tonic-gate     while(isspace(ch) && ch != -1){
2128*0Sstevel@tonic-gate 	ch = getc(fp);
2129*0Sstevel@tonic-gate 	if (ch == '\n')
2130*0Sstevel@tonic-gate 	    Line++;
2131*0Sstevel@tonic-gate     }
2132*0Sstevel@tonic-gate     if (ch == -1) {
2133*0Sstevel@tonic-gate #ifdef TRACE_GET_TOKEN
2134*0Sstevel@tonic-gate print_error("TRACE", token, ENDOFFILE);
2135*0Sstevel@tonic-gate #endif
2136*0Sstevel@tonic-gate 	return ENDOFFILE;
2137*0Sstevel@tonic-gate     } else if (ch == '"') {
2138*0Sstevel@tonic-gate 	return parseQuoteString(fp, token);
2139*0Sstevel@tonic-gate     }
2140*0Sstevel@tonic-gate 
2141*0Sstevel@tonic-gate     /*
2142*0Sstevel@tonic-gate      * Accumulate characters until end of token is found.  Then attempt to
2143*0Sstevel@tonic-gate      * match this token as a reserved word.  If a match is found, return the
2144*0Sstevel@tonic-gate      * type.  Else it is a label.
2145*0Sstevel@tonic-gate      */
2146*0Sstevel@tonic-gate     do {
2147*0Sstevel@tonic-gate 	if (ch == '\n')
2148*0Sstevel@tonic-gate 	    Line++;
2149*0Sstevel@tonic-gate 	if (isspace(ch) || ch == '(' || ch == ')' || ch == '{' || ch == '}' ||
2150*0Sstevel@tonic-gate 	    ch == ',' || ch == ';'){
2151*0Sstevel@tonic-gate 	    if (!isspace(ch) && *token == 0){
2152*0Sstevel@tonic-gate 		hash += ch;
2153*0Sstevel@tonic-gate 		*cp++ = ch;
2154*0Sstevel@tonic-gate 		last = ' ';
2155*0Sstevel@tonic-gate 	    } else {
2156*0Sstevel@tonic-gate 		last = ch;
2157*0Sstevel@tonic-gate 	    }
2158*0Sstevel@tonic-gate 	    *cp = '\0';
2159*0Sstevel@tonic-gate 
2160*0Sstevel@tonic-gate 	    for (tp = buckets[BUCKET(hash)]; tp; tp = tp->next) {
2161*0Sstevel@tonic-gate 		if ((tp->hash == hash) && (strcmp(tp->name, token) == 0))
2162*0Sstevel@tonic-gate 			break;
2163*0Sstevel@tonic-gate 	    }
2164*0Sstevel@tonic-gate 	    if (tp){
2165*0Sstevel@tonic-gate 		if (tp->token == CONTINUE)
2166*0Sstevel@tonic-gate 		    continue;
2167*0Sstevel@tonic-gate #ifdef TRACE_GET_TOKEN
2168*0Sstevel@tonic-gate print_error("TRACE", token, tp->token);
2169*0Sstevel@tonic-gate #endif
2170*0Sstevel@tonic-gate 		return (tp->token);
2171*0Sstevel@tonic-gate 	    }
2172*0Sstevel@tonic-gate 
2173*0Sstevel@tonic-gate 	    if (token[0] == '-' && token[1] == '-'){
2174*0Sstevel@tonic-gate 		/* strip comment */
2175*0Sstevel@tonic-gate 		if (ch != '\n'){
2176*0Sstevel@tonic-gate 		    while ((ch = getc(fp)) != -1)
2177*0Sstevel@tonic-gate 			if (ch == '\n'){
2178*0Sstevel@tonic-gate 			    Line++;
2179*0Sstevel@tonic-gate 			    break;
2180*0Sstevel@tonic-gate 			}
2181*0Sstevel@tonic-gate 		}
2182*0Sstevel@tonic-gate 		if (ch == -1)
2183*0Sstevel@tonic-gate {
2184*0Sstevel@tonic-gate #ifdef TRACE_GET_TOKEN
2185*0Sstevel@tonic-gate print_error("TRACE", token, ENDOFFILE);
2186*0Sstevel@tonic-gate #endif
2187*0Sstevel@tonic-gate 		    return ENDOFFILE;
2188*0Sstevel@tonic-gate }
2189*0Sstevel@tonic-gate 		last = ch;
2190*0Sstevel@tonic-gate 		return get_token(fp, token);
2191*0Sstevel@tonic-gate 	    }
2192*0Sstevel@tonic-gate 	    for(cp = token; *cp; cp++)
2193*0Sstevel@tonic-gate 		if (!isdigit(*cp))
2194*0Sstevel@tonic-gate {
2195*0Sstevel@tonic-gate #ifdef TRACE_GET_TOKEN
2196*0Sstevel@tonic-gate print_error("TRACE", token, LABEL);
2197*0Sstevel@tonic-gate #endif
2198*0Sstevel@tonic-gate 		    return LABEL;
2199*0Sstevel@tonic-gate }
2200*0Sstevel@tonic-gate #ifdef TRACE_GET_TOKEN
2201*0Sstevel@tonic-gate print_error("TRACE", token, NUMBER);
2202*0Sstevel@tonic-gate #endif
2203*0Sstevel@tonic-gate             number_value = atoi(token);   /* octet string size */
2204*0Sstevel@tonic-gate 	    return NUMBER;
2205*0Sstevel@tonic-gate 	} else {
2206*0Sstevel@tonic-gate 	    hash += ch;
2207*0Sstevel@tonic-gate 	    *cp++ = ch;
2208*0Sstevel@tonic-gate 	    if (ch == '\n')
2209*0Sstevel@tonic-gate 		Line++;
2210*0Sstevel@tonic-gate 	}
2211*0Sstevel@tonic-gate 
2212*0Sstevel@tonic-gate     } while ((ch = getc(fp)) != -1);
2213*0Sstevel@tonic-gate #ifdef TRACE_GET_TOKEN
2214*0Sstevel@tonic-gate print_error("TRACE", token, ENDOFFILE);
2215*0Sstevel@tonic-gate #endif
2216*0Sstevel@tonic-gate     return ENDOFFILE;
2217*0Sstevel@tonic-gate }
2218*0Sstevel@tonic-gate 
2219*0Sstevel@tonic-gate struct tree *
2220*0Sstevel@tonic-gate read_mib(filename)
2221*0Sstevel@tonic-gate     char *filename;
2222*0Sstevel@tonic-gate {
2223*0Sstevel@tonic-gate     FILE *fp;
2224*0Sstevel@tonic-gate     struct node *nodes;
2225*0Sstevel@tonic-gate     struct tree *tree;
2226*0Sstevel@tonic-gate 
2227*0Sstevel@tonic-gate     fp = fopen(filename, "r");
2228*0Sstevel@tonic-gate     if (fp == NULL)
2229*0Sstevel@tonic-gate 	return NULL;
2230*0Sstevel@tonic-gate     nodes = parse(fp);
2231*0Sstevel@tonic-gate     if (!nodes){
2232*0Sstevel@tonic-gate 	fprintf(stderr, "Mib table is bad.  Exiting\n");
2233*0Sstevel@tonic-gate 	exit(1);
2234*0Sstevel@tonic-gate     }
2235*0Sstevel@tonic-gate     tree = build_tree(nodes);
2236*0Sstevel@tonic-gate     fclose(fp);
2237*0Sstevel@tonic-gate     return tree;
2238*0Sstevel@tonic-gate }
2239*0Sstevel@tonic-gate 
2240*0Sstevel@tonic-gate 
2241*0Sstevel@tonic-gate #ifdef TEST
2242*0Sstevel@tonic-gate main(argc, argv)
2243*0Sstevel@tonic-gate     int argc;
2244*0Sstevel@tonic-gate     char *argv[];
2245*0Sstevel@tonic-gate {
2246*0Sstevel@tonic-gate     FILE *fp;
2247*0Sstevel@tonic-gate     struct node *nodes;
2248*0Sstevel@tonic-gate     struct tree *tp;
2249*0Sstevel@tonic-gate 
2250*0Sstevel@tonic-gate     fp = fopen("mib.txt", "r");
2251*0Sstevel@tonic-gate     if (fp == NULL){
2252*0Sstevel@tonic-gate 	fprintf(stderr, "open failed\n");
2253*0Sstevel@tonic-gate 	return 1;
2254*0Sstevel@tonic-gate     }
2255*0Sstevel@tonic-gate     nodes = parse(fp);
2256*0Sstevel@tonic-gate     if (!nodes){
2257*0Sstevel@tonic-gate       fprintf(stderr, "Mib table is bad. \n");
2258*0Sstevel@tonic-gate       return (1);
2259*0Sstevel@tonic-gate     }
2260*0Sstevel@tonic-gate     tp = build_tree(nodes);
2261*0Sstevel@tonic-gate     print_subtree(tp, 0);
2262*0Sstevel@tonic-gate     fclose(fp);
2263*0Sstevel@tonic-gate }
2264*0Sstevel@tonic-gate 
2265*0Sstevel@tonic-gate #endif /* TEST */
2266*0Sstevel@tonic-gate 
2267*0Sstevel@tonic-gate static int
2268*0Sstevel@tonic-gate parseQuoteString(fp, token)
2269*0Sstevel@tonic-gate     register FILE *fp;
2270*0Sstevel@tonic-gate     register char *token;
2271*0Sstevel@tonic-gate {
2272*0Sstevel@tonic-gate     register int ch;
2273*0Sstevel@tonic-gate     register char *ptr, *ptr1;
2274*0Sstevel@tonic-gate     register int len = 0;
2275*0Sstevel@tonic-gate 
2276*0Sstevel@tonic-gate     ch = ' ';
2277*0Sstevel@tonic-gate     *token = '\0';                      /* make the token empty */
2278*0Sstevel@tonic-gate 
2279*0Sstevel@tonic-gate     ptr = quoted_string_buffer;
2280*0Sstevel@tonic-gate     if (ptr)
2281*0Sstevel@tonic-gate 	*ptr = 0;
2282*0Sstevel@tonic-gate 
2283*0Sstevel@tonic-gate 
2284*0Sstevel@tonic-gate     while(ch != -1) {
2285*0Sstevel@tonic-gate         ch = getc(fp);
2286*0Sstevel@tonic-gate 	if (ch != '"') {
2287*0Sstevel@tonic-gate 		if (ptr) {
2288*0Sstevel@tonic-gate 			* ptr ++ = ch;
2289*0Sstevel@tonic-gate 			len ++;
2290*0Sstevel@tonic-gate 			if (len % MAXQUOTESTR == 0) {
2291*0Sstevel@tonic-gate 				ptr1 = (char *) malloc (len + MAXQUOTESTR);
2292*0Sstevel@tonic-gate 				if (!ptr1){
2293*0Sstevel@tonic-gate 				  fprintf(stderr, "malloc failed.  Exiting\n");
2294*0Sstevel@tonic-gate 				  exit(1);
2295*0Sstevel@tonic-gate 				}
2296*0Sstevel@tonic-gate 				memcpy (ptr1, quoted_string_buffer, len);
2297*0Sstevel@tonic-gate 				free (quoted_string_buffer);
2298*0Sstevel@tonic-gate 				quoted_string_buffer = ptr1;
2299*0Sstevel@tonic-gate 				ptr = ptr1 + len;
2300*0Sstevel@tonic-gate 			}
2301*0Sstevel@tonic-gate 		}
2302*0Sstevel@tonic-gate 	} else {
2303*0Sstevel@tonic-gate 		if (ptr)
2304*0Sstevel@tonic-gate 			* ptr = 0;
2305*0Sstevel@tonic-gate 	}
2306*0Sstevel@tonic-gate 	if (ch == '\n')
2307*0Sstevel@tonic-gate 	    Line++;
2308*0Sstevel@tonic-gate 	else if (ch == '"') {
2309*0Sstevel@tonic-gate #ifdef TRACE_GET_TOKEN
2310*0Sstevel@tonic-gate print_error("TRACE", token, QUOTESTRING);
2311*0Sstevel@tonic-gate #endif
2312*0Sstevel@tonic-gate             return QUOTESTRING;
2313*0Sstevel@tonic-gate         }
2314*0Sstevel@tonic-gate 
2315*0Sstevel@tonic-gate     }
2316*0Sstevel@tonic-gate 
2317*0Sstevel@tonic-gate #ifdef TRACE_GET_TOKEN
2318*0Sstevel@tonic-gate print_error("TRACE", token, NULL);
2319*0Sstevel@tonic-gate #endif
2320*0Sstevel@tonic-gate     return NULL;
2321*0Sstevel@tonic-gate }
2322*0Sstevel@tonic-gate 
2323*0Sstevel@tonic-gate /*
2324*0Sstevel@tonic-gate  * This routine parses a string like  { blah blah blah } and returns PARSE_OBJID if
2325*0Sstevel@tonic-gate  * it is well formed, and NULL if not.
2326*0Sstevel@tonic-gate  */
2327*0Sstevel@tonic-gate static int
2328*0Sstevel@tonic-gate tossObjectIdentifier(fp)
2329*0Sstevel@tonic-gate     register FILE *fp;
2330*0Sstevel@tonic-gate {
2331*0Sstevel@tonic-gate     register int ch;
2332*0Sstevel@tonic-gate 
2333*0Sstevel@tonic-gate         ch = getc(fp);
2334*0Sstevel@tonic-gate /*    ch = last; = ' '? */
2335*0Sstevel@tonic-gate     /* skip all white space */
2336*0Sstevel@tonic-gate     while(isspace(ch) && ch != -1){
2337*0Sstevel@tonic-gate         ch = getc(fp);
2338*0Sstevel@tonic-gate         if (ch == '\n')
2339*0Sstevel@tonic-gate             Line++;
2340*0Sstevel@tonic-gate     }
2341*0Sstevel@tonic-gate     if (ch != '{')
2342*0Sstevel@tonic-gate         return NULL;
2343*0Sstevel@tonic-gate 
2344*0Sstevel@tonic-gate     while(ch != -1) {
2345*0Sstevel@tonic-gate         ch = getc(fp);
2346*0Sstevel@tonic-gate 
2347*0Sstevel@tonic-gate         if (ch == '\n')
2348*0Sstevel@tonic-gate             Line++;
2349*0Sstevel@tonic-gate         else if (ch == '}')
2350*0Sstevel@tonic-gate             return PARSE_OBJID;
2351*0Sstevel@tonic-gate     }
2352*0Sstevel@tonic-gate 
2353*0Sstevel@tonic-gate /*    last = ch;*/
2354*0Sstevel@tonic-gate     return NULL;
2355*0Sstevel@tonic-gate }
2356