xref: /onnv-gate/usr/src/cmd/agents/snmp/parser/parse.c (revision 3857:21b9b714e4ab)
1*3857Sstevel /*
2*3857Sstevel  * Copyright 1999 Sun Microsystems, Inc.  All rights reserved.
3*3857Sstevel  * Use is subject to license terms.
40Sstevel@tonic-gate  */
50Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
60Sstevel@tonic-gate 
70Sstevel@tonic-gate /******************************************************************
80Sstevel@tonic-gate 	Copyright 1989, 1991, 1992 by Carnegie Mellon University
90Sstevel@tonic-gate 
100Sstevel@tonic-gate                       All Rights Reserved
110Sstevel@tonic-gate 
120Sstevel@tonic-gate Permission to use, copy, modify, and distribute this software and its
130Sstevel@tonic-gate documentation for any purpose and without fee is hereby granted,
140Sstevel@tonic-gate provided that the above copyright notice appear in all copies and that
150Sstevel@tonic-gate both that copyright notice and this permission notice appear in
160Sstevel@tonic-gate supporting documentation, and that the name of CMU not be
170Sstevel@tonic-gate used in advertising or publicity pertaining to distribution of the
180Sstevel@tonic-gate software without specific, written prior permission.
190Sstevel@tonic-gate 
200Sstevel@tonic-gate CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
210Sstevel@tonic-gate ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
220Sstevel@tonic-gate CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
230Sstevel@tonic-gate ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
240Sstevel@tonic-gate WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
250Sstevel@tonic-gate ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
260Sstevel@tonic-gate SOFTWARE.
270Sstevel@tonic-gate ******************************************************************/
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  * parse.c
300Sstevel@tonic-gate  */
310Sstevel@tonic-gate 
320Sstevel@tonic-gate /* HISTORY
330Sstevel@tonic-gate  * Jerry Yeung	6-6-96
340Sstevel@tonic-gate  * Jerry Yeung	1-9-97	fix 4019317
350Sstevel@tonic-gate  */
360Sstevel@tonic-gate 
370Sstevel@tonic-gate #include <stdio.h>
380Sstevel@tonic-gate #include <ctype.h>
390Sstevel@tonic-gate #include <stdlib.h>
400Sstevel@tonic-gate #include <sys/types.h>
410Sstevel@tonic-gate #include "parse.h"
420Sstevel@tonic-gate 
430Sstevel@tonic-gate struct trap_item *trap_list = NULL;
440Sstevel@tonic-gate 
450Sstevel@tonic-gate /* A quoted string value-- too long for a general "token" */
460Sstevel@tonic-gate char *quoted_string_buffer;
470Sstevel@tonic-gate 
480Sstevel@tonic-gate /*
490Sstevel@tonic-gate  * This is one element of an object identifier with either an integer
500Sstevel@tonic-gate  * subidentifier, or a textual string label, or both.
510Sstevel@tonic-gate  * The subid is -1 if not present, and label is NULL if not present.
520Sstevel@tonic-gate  */
530Sstevel@tonic-gate struct subid {
540Sstevel@tonic-gate     int subid;
550Sstevel@tonic-gate     char *label;
560Sstevel@tonic-gate };
570Sstevel@tonic-gate 
580Sstevel@tonic-gate #define MAXTC	128
590Sstevel@tonic-gate struct tc {	/* textual conventions */
600Sstevel@tonic-gate     int type;
610Sstevel@tonic-gate     char descriptor[MAXTOKEN];
620Sstevel@tonic-gate     struct enum_list *enums;
630Sstevel@tonic-gate } tclist[MAXTC];
640Sstevel@tonic-gate 
650Sstevel@tonic-gate 
660Sstevel@tonic-gate 
670Sstevel@tonic-gate int Line = 1;
680Sstevel@tonic-gate 
690Sstevel@tonic-gate #define SYNTAX_MASK	0x80
700Sstevel@tonic-gate /* types of tokens
710Sstevel@tonic-gate  Tokens wiht the SYNTAX_MASK bit set are syntax tokens */
720Sstevel@tonic-gate #define	CONTINUE    -1
730Sstevel@tonic-gate #define ENDOFFILE   0
740Sstevel@tonic-gate #define LABEL	    1
750Sstevel@tonic-gate #define SUBTREE	    2
760Sstevel@tonic-gate #define SYNTAX	    3
770Sstevel@tonic-gate #define PARSE_OBJID	    (4 | SYNTAX_MASK)
780Sstevel@tonic-gate #define OCTETSTR    (5 | SYNTAX_MASK)
790Sstevel@tonic-gate #define PARSE_INTEGER	    (6 | SYNTAX_MASK)
800Sstevel@tonic-gate #define NETADDR	    (7 | SYNTAX_MASK)
810Sstevel@tonic-gate #define	IPADDR	    (8 | SYNTAX_MASK)
820Sstevel@tonic-gate #define PARSE_COUNTER	    (9 | SYNTAX_MASK)
830Sstevel@tonic-gate #define PARSE_GUAGE	    (10 | SYNTAX_MASK)
840Sstevel@tonic-gate #define PARSE_TIMETICKS   (11 | SYNTAX_MASK)
850Sstevel@tonic-gate #define PARSE_OPAQUE	    (12 | SYNTAX_MASK)
860Sstevel@tonic-gate #define NUL	    (13 | SYNTAX_MASK)
870Sstevel@tonic-gate #define SEQUENCE    14
880Sstevel@tonic-gate #define OF	    15	/* SEQUENCE OF */
890Sstevel@tonic-gate #define OBJTYPE	    16
900Sstevel@tonic-gate #define ACCESS	    17
910Sstevel@tonic-gate #define READONLY    18
920Sstevel@tonic-gate #define READWRITE   19
930Sstevel@tonic-gate #define	WRITEONLY   20
940Sstevel@tonic-gate #define NOACCESS    21
950Sstevel@tonic-gate #define STATUS	    22
960Sstevel@tonic-gate #define MANDATORY   23
970Sstevel@tonic-gate #define OPTIONAL    24
980Sstevel@tonic-gate #define OBSOLETE    25
990Sstevel@tonic-gate /* #define RECOMMENDED 26 */
1000Sstevel@tonic-gate #define PUNCT	    27
1010Sstevel@tonic-gate #define EQUALS	    28
1020Sstevel@tonic-gate #define NUMBER	    29
1030Sstevel@tonic-gate #define LEFTBRACKET 30
1040Sstevel@tonic-gate #define RIGHTBRACKET 31
1050Sstevel@tonic-gate #define	LEFTPAREN   32
1060Sstevel@tonic-gate #define RIGHTPAREN  33
1070Sstevel@tonic-gate #define COMMA	    34
1080Sstevel@tonic-gate #define DESCRIPTION 35
1090Sstevel@tonic-gate #define QUOTESTRING 36
1100Sstevel@tonic-gate #define INDEX       37
1110Sstevel@tonic-gate #define DEFVAL      38
1120Sstevel@tonic-gate #define DEPRECATED  39
1130Sstevel@tonic-gate #define SIZE        40
1140Sstevel@tonic-gate #define BITSTRING   (41 | SYNTAX_MASK)
1150Sstevel@tonic-gate #define NSAPADDRESS (42 | SYNTAX_MASK)
1160Sstevel@tonic-gate #define PARSE_COUNTER64   (43 | SYNTAX_MASK)
1170Sstevel@tonic-gate #define OBJGROUP    44
1180Sstevel@tonic-gate #define NOTIFTYPE   45
1190Sstevel@tonic-gate #define AUGMENTS    46
1200Sstevel@tonic-gate #define COMPLIANCE  47
1210Sstevel@tonic-gate #define READCREATE  48
1220Sstevel@tonic-gate #define UNITS       49
1230Sstevel@tonic-gate #define REFERENCE   50
1240Sstevel@tonic-gate #define NUM_ENTRIES 51
1250Sstevel@tonic-gate #define MODULEIDENTITY 52
1260Sstevel@tonic-gate #define LASTUPDATED 53
1270Sstevel@tonic-gate #define ORGANIZATION 54
1280Sstevel@tonic-gate #define CONTACTINFO 55
1290Sstevel@tonic-gate #define UINTEGER32 (56 | SYNTAX_MASK)
1300Sstevel@tonic-gate #define CURRENT	    57
1310Sstevel@tonic-gate #define DEFINITIONS 58
1320Sstevel@tonic-gate #define END         59
1330Sstevel@tonic-gate #define SEMI        60
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate /*
1360Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
1370Sstevel@tonic-gate */
1380Sstevel@tonic-gate #define PSEUDO_TOKEN_TABLE        61
1390Sstevel@tonic-gate #define PSEUDO_TOKEN_ENTRY        62
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate /* Jerry Yeung 6-6-96 (trap-support) */
1420Sstevel@tonic-gate #define TRAPTYPE 63
1430Sstevel@tonic-gate #define ENTERPRISE 64
1440Sstevel@tonic-gate #define VARIABLES 65
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate struct tok {
1470Sstevel@tonic-gate 	char *name;			/* token name */
1480Sstevel@tonic-gate 	int len;			/* length not counting nul */
1490Sstevel@tonic-gate 	int token;			/* value */
1500Sstevel@tonic-gate 	int hash;			/* hash of name */
1510Sstevel@tonic-gate 	struct tok *next;		/* pointer to next in hash table */
1520Sstevel@tonic-gate };
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate struct tok tokens[] = {
1560Sstevel@tonic-gate 	{ "obsolete", sizeof ("obsolete")-1, OBSOLETE },
1570Sstevel@tonic-gate 	{ "Opaque", sizeof ("Opaque")-1, PARSE_OPAQUE },
1580Sstevel@tonic-gate /*	{ "recommended", sizeof("recommended")-1, RECOMMENDED },  */
1590Sstevel@tonic-gate 	{ "optional", sizeof ("optional")-1, OPTIONAL },
1600Sstevel@tonic-gate 	{ "LAST-UPDATED", sizeof ("LAST-UPDATED")-1, LASTUPDATED },
1610Sstevel@tonic-gate 	{ "ORGANIZATION", sizeof ("ORGANIZATION")-1, ORGANIZATION },
1620Sstevel@tonic-gate 	{ "CONTACT-INFO", sizeof ("CONTACT-INFO")-1, CONTACTINFO },
1630Sstevel@tonic-gate 	{ "MODULE-IDENTITY", sizeof ("MODULE-IDENTITY")-1, MODULEIDENTITY },
1640Sstevel@tonic-gate 	{ "MODULE-COMPLIANCE", sizeof ("MODULE-COMPLIANCE")-1, COMPLIANCE },
1650Sstevel@tonic-gate         { "DEFINITIONS", sizeof("DEFINITIONS")-1, DEFINITIONS},
1660Sstevel@tonic-gate         { "END", sizeof("END")-1, END},
1670Sstevel@tonic-gate         { ";", sizeof(";")-1, SEMI},
1680Sstevel@tonic-gate 	{ "AUGMENTS", sizeof ("AUGMENTS")-1, AUGMENTS },
1690Sstevel@tonic-gate 	{ "not-accessible", sizeof ("not-accessible")-1, NOACCESS },
1700Sstevel@tonic-gate 	{ "write-only", sizeof ("write-only")-1, WRITEONLY },
1710Sstevel@tonic-gate 	{ "NsapAddress", sizeof("NsapAddress")-1, NSAPADDRESS},
1720Sstevel@tonic-gate 	{ "UNITS", sizeof("Units")-1, UNITS},
1730Sstevel@tonic-gate 	{ "REFERENCE", sizeof("REFERENCE")-1, REFERENCE},
1740Sstevel@tonic-gate 	{ "NUM-ENTRIES", sizeof("NUM-ENTRIES")-1, NUM_ENTRIES},
1750Sstevel@tonic-gate 	{ "BITSTRING", sizeof("BitString")-1, BITSTRING},
1760Sstevel@tonic-gate 	{ "BIT", sizeof("BIT")-1, CONTINUE},
1770Sstevel@tonic-gate 	{ "Counter64", sizeof("Counter64")-1, PARSE_COUNTER64},
1780Sstevel@tonic-gate 	{ "TimeTicks", sizeof ("TimeTicks")-1, PARSE_TIMETICKS },
1790Sstevel@tonic-gate 	{ "NOTIFICATION-TYPE", sizeof ("NOTIFICATION-TYPE")-1, NOTIFTYPE },
1800Sstevel@tonic-gate 	{ "OBJECT-GROUP", sizeof ("OBJECT-GROUP")-1, OBJGROUP },
1810Sstevel@tonic-gate 	{ "OBJECTIDENTIFIER", sizeof ("OBJECTIDENTIFIER")-1, PARSE_OBJID },
1820Sstevel@tonic-gate 	/*
1830Sstevel@tonic-gate 	 * This CONTINUE appends the next word onto OBJECT,
1840Sstevel@tonic-gate 	 * hopefully matching OBJECTIDENTIFIER above.
1850Sstevel@tonic-gate 	 */
1860Sstevel@tonic-gate 	{ "OBJECT", sizeof ("OBJECT")-1, CONTINUE },
1870Sstevel@tonic-gate 	{ "NetworkAddress", sizeof ("NetworkAddress")-1, NETADDR },
1880Sstevel@tonic-gate 	{ "Gauge", sizeof ("Gauge")-1, PARSE_GUAGE },
1890Sstevel@tonic-gate 	{ "read-write", sizeof ("read-write")-1, READWRITE },
1900Sstevel@tonic-gate 	{ "read-create", sizeof ("read-create")-1, READCREATE },
1910Sstevel@tonic-gate 	{ "OCTETSTRING", sizeof ("OCTETSTRING")-1, OCTETSTR },
1920Sstevel@tonic-gate 	{ "OCTET", sizeof ("OCTET")-1, -1 },
1930Sstevel@tonic-gate 	{ "OF", sizeof ("OF")-1, OF },
1940Sstevel@tonic-gate 	{ "SEQUENCE", sizeof ("SEQUENCE")-1, SEQUENCE },
1950Sstevel@tonic-gate 	{ "NULL", sizeof ("NULL")-1, NUL },
1960Sstevel@tonic-gate 	{ "IpAddress", sizeof ("IpAddress")-1, IPADDR },
1970Sstevel@tonic-gate 	{ "UInteger32", sizeof ("UInteger32")-1, UINTEGER32 },
1980Sstevel@tonic-gate 	{ "INTEGER", sizeof ("INTEGER")-1, PARSE_INTEGER },
1990Sstevel@tonic-gate 	{ "Counter", sizeof ("Counter")-1, PARSE_COUNTER },
2000Sstevel@tonic-gate 	{ "read-only", sizeof ("read-only")-1, READONLY },
2010Sstevel@tonic-gate         { "DESCRIPTION", sizeof ("DESCRIPTION")-1, DESCRIPTION },
2020Sstevel@tonic-gate         { "INDEX", sizeof ("INDEX")-1, INDEX },
2030Sstevel@tonic-gate         { "DEFVAL", sizeof ("DEFVAL")-1, DEFVAL },
2040Sstevel@tonic-gate         { "deprecated", sizeof ("deprecated")-1, DEPRECATED },
2050Sstevel@tonic-gate         { "SIZE", sizeof ("SIZE")-1, SIZE },
2060Sstevel@tonic-gate 	{ "MAX-ACCESS", sizeof ("MAX-ACCESS")-1, ACCESS },
2070Sstevel@tonic-gate 	{ "ACCESS", sizeof ("ACCESS")-1, ACCESS },
2080Sstevel@tonic-gate 	{ "mandatory", sizeof ("mandatory")-1, MANDATORY },
2090Sstevel@tonic-gate 	{ "current", sizeof ("current")-1, CURRENT },
2100Sstevel@tonic-gate 	{ "STATUS", sizeof ("STATUS")-1, STATUS },
2110Sstevel@tonic-gate 	{ "SYNTAX", sizeof ("SYNTAX")-1, SYNTAX },
2120Sstevel@tonic-gate 	{ "OBJECT-TYPE", sizeof ("OBJECT-TYPE")-1, OBJTYPE },
2130Sstevel@tonic-gate 	{ "{", sizeof ("{")-1, LEFTBRACKET },
2140Sstevel@tonic-gate 	{ "}", sizeof ("}")-1, RIGHTBRACKET },
2150Sstevel@tonic-gate 	{ "::=", sizeof ("::=")-1, EQUALS },
2160Sstevel@tonic-gate 	{ "(", sizeof ("(")-1, LEFTPAREN },
2170Sstevel@tonic-gate 	{ ")", sizeof (")")-1, RIGHTPAREN },
2180Sstevel@tonic-gate 	{ ",", sizeof (",")-1, COMMA },
2190Sstevel@tonic-gate 	{ "TRAP-TYPE", sizeof ("TRAP-TYPE")-1, TRAPTYPE },
2200Sstevel@tonic-gate 	{ "ENTERPRISE", sizeof ("ENTERPRISE")-1, ENTERPRISE },
2210Sstevel@tonic-gate 	{ "VARIABLES", sizeof ("VARIABLES")-1, VARIABLES },
2220Sstevel@tonic-gate 	{ NULL }
2230Sstevel@tonic-gate };
2240Sstevel@tonic-gate 
2250Sstevel@tonic-gate #define	HASHSIZE	32
2260Sstevel@tonic-gate #define	BUCKET(x)	(x & 0x01F)
2270Sstevel@tonic-gate 
2280Sstevel@tonic-gate struct tok	*buckets[HASHSIZE];
2290Sstevel@tonic-gate static void
2300Sstevel@tonic-gate do_subtree(struct tree *root, struct node **nodes);
2310Sstevel@tonic-gate static int
2320Sstevel@tonic-gate get_token(register FILE *fp, register char *token);
2330Sstevel@tonic-gate static int
2340Sstevel@tonic-gate parseQuoteString(register FILE *fp, register char *token);
2350Sstevel@tonic-gate static int
2360Sstevel@tonic-gate tossObjectIdentifier(register FILE *fp);
2370Sstevel@tonic-gate 
2380Sstevel@tonic-gate int number_value;
2390Sstevel@tonic-gate 
2400Sstevel@tonic-gate static void
hash_init()2410Sstevel@tonic-gate hash_init()
2420Sstevel@tonic-gate {
2430Sstevel@tonic-gate 	register struct tok	*tp;
2440Sstevel@tonic-gate 	register char	*cp;
2450Sstevel@tonic-gate 	register int	h;
2460Sstevel@tonic-gate 	register int	b;
2470Sstevel@tonic-gate 
2480Sstevel@tonic-gate /*
2490Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
2500Sstevel@tonic-gate 	bzero((char *)buckets, sizeof(buckets));
2510Sstevel@tonic-gate */
2520Sstevel@tonic-gate 	memset((void *) buckets, 0, sizeof(buckets));
2530Sstevel@tonic-gate 
2540Sstevel@tonic-gate 	for (tp = tokens; tp->name; tp++) {
2550Sstevel@tonic-gate 		for (h = 0, cp = tp->name; *cp; cp++)
2560Sstevel@tonic-gate 			h += *cp;
2570Sstevel@tonic-gate 		tp->hash = h;
2580Sstevel@tonic-gate 		b = BUCKET(h);
2590Sstevel@tonic-gate 		if (buckets[b])
2600Sstevel@tonic-gate 		    tp->next = buckets[b]; /* BUG ??? */
2610Sstevel@tonic-gate 		buckets[b] = tp;
2620Sstevel@tonic-gate 	}
2630Sstevel@tonic-gate }
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate #define NHASHSIZE    128
2660Sstevel@tonic-gate #define NBUCKET(x)   (x & 0x7F)
2670Sstevel@tonic-gate struct node *nbuckets[NHASHSIZE];
2680Sstevel@tonic-gate 
init_node_hash(nodes)2690Sstevel@tonic-gate void init_node_hash(nodes)
2700Sstevel@tonic-gate      struct node *nodes;
2710Sstevel@tonic-gate {
2720Sstevel@tonic-gate      register struct node *np, *nextp;
2730Sstevel@tonic-gate      register char *cp;
2740Sstevel@tonic-gate      register int hash;
2750Sstevel@tonic-gate 
2760Sstevel@tonic-gate /*
2770Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
2780Sstevel@tonic-gate      bzero((char *)nbuckets,sizeof(nbuckets));
2790Sstevel@tonic-gate */
2800Sstevel@tonic-gate      memset((void *) nbuckets, 0, sizeof(nbuckets));
2810Sstevel@tonic-gate 
2820Sstevel@tonic-gate      for(np = nodes; np;){
2830Sstevel@tonic-gate          nextp = np->next;
2840Sstevel@tonic-gate          hash = 0;
2850Sstevel@tonic-gate 	 for(cp = np->parent; *cp; cp++)
2860Sstevel@tonic-gate 	     hash += *cp;
2870Sstevel@tonic-gate 	 np->next = nbuckets[NBUCKET(hash)];
2880Sstevel@tonic-gate 	 nbuckets[NBUCKET(hash)] = np;
2890Sstevel@tonic-gate 	 np = nextp;
2900Sstevel@tonic-gate      }
2910Sstevel@tonic-gate }
2920Sstevel@tonic-gate 
2930Sstevel@tonic-gate static char *
Malloc(num)2940Sstevel@tonic-gate Malloc(num)
2950Sstevel@tonic-gate     unsigned num;
2960Sstevel@tonic-gate {
2970Sstevel@tonic-gate     char     *buf;
2980Sstevel@tonic-gate 
2990Sstevel@tonic-gate     /* this is to fix (what seems to be) a problem with the IBM RT C
3000Sstevel@tonic-gate library malloc */
3010Sstevel@tonic-gate     if (num < 16)
3020Sstevel@tonic-gate 	num = 16;
3030Sstevel@tonic-gate     buf = (char *)malloc (num);
3040Sstevel@tonic-gate     if (buf == NULL) {
3050Sstevel@tonic-gate       fprintf(stderr, "malloc failed.  Exiting\n");
3060Sstevel@tonic-gate       exit(1);
3070Sstevel@tonic-gate     }
3080Sstevel@tonic-gate     return (char *)buf;
3090Sstevel@tonic-gate }
3100Sstevel@tonic-gate 
3110Sstevel@tonic-gate static void
print_error(string,token,type)3120Sstevel@tonic-gate print_error(string, token, type)
3130Sstevel@tonic-gate     char *string;
3140Sstevel@tonic-gate     char *token;
3150Sstevel@tonic-gate     int type;
3160Sstevel@tonic-gate {
3170Sstevel@tonic-gate     if (type == ENDOFFILE)
3180Sstevel@tonic-gate 	fprintf(stderr, "%s(EOF): On or around line %d\n", string, Line);
3190Sstevel@tonic-gate     else if (token)
3200Sstevel@tonic-gate 	fprintf(stderr, "%s(%s): On or around line %d\n", string, token, Line);
3210Sstevel@tonic-gate     else
3220Sstevel@tonic-gate 	fprintf(stderr, "%s: On or around line %d\n", string, Line);
3230Sstevel@tonic-gate }
3240Sstevel@tonic-gate 
3250Sstevel@tonic-gate /*
3260Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
3270Sstevel@tonic-gate #ifdef TEST
3280Sstevel@tonic-gate print_subtree(tree, count)
3290Sstevel@tonic-gate */
print_subtree(tree,count)3300Sstevel@tonic-gate void print_subtree(tree, count)
3310Sstevel@tonic-gate     struct tree *tree;
3320Sstevel@tonic-gate     int count;
3330Sstevel@tonic-gate {
3340Sstevel@tonic-gate     struct tree *tp;
3350Sstevel@tonic-gate     int i;
3360Sstevel@tonic-gate 
3370Sstevel@tonic-gate     for(i = 0; i < count; i++)
3380Sstevel@tonic-gate 	printf("  ");
3390Sstevel@tonic-gate     printf("Children of %s:\n", tree->label);
3400Sstevel@tonic-gate     count++;
3410Sstevel@tonic-gate     for(tp = tree->child_list; tp; tp = tp->next_peer){
3420Sstevel@tonic-gate 	for(i = 0; i < count; i++)
3430Sstevel@tonic-gate 	    printf("  ");
3440Sstevel@tonic-gate 	printf("%s\n", tp->label);
3450Sstevel@tonic-gate     }
3460Sstevel@tonic-gate     for(tp = tree->child_list; tp; tp = tp->next_peer){
3470Sstevel@tonic-gate 	print_subtree(tp, count);
3480Sstevel@tonic-gate     }
3490Sstevel@tonic-gate }
3500Sstevel@tonic-gate /*
3510Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
3520Sstevel@tonic-gate #endif
3530Sstevel@tonic-gate */
3540Sstevel@tonic-gate 
3550Sstevel@tonic-gate int translation_table[256];
3560Sstevel@tonic-gate 
build_translation_table()3570Sstevel@tonic-gate void build_translation_table(){
3580Sstevel@tonic-gate     int count;
3590Sstevel@tonic-gate 
3600Sstevel@tonic-gate     for(count = 0; count < 256; count++){
3610Sstevel@tonic-gate 	switch(count){
3620Sstevel@tonic-gate 	    case PARSE_OBJID:
3630Sstevel@tonic-gate 		translation_table[count] = TYPE_OBJID;
3640Sstevel@tonic-gate 		break;
3650Sstevel@tonic-gate 	    case OCTETSTR:
3660Sstevel@tonic-gate 		translation_table[count] = TYPE_OCTETSTR;
3670Sstevel@tonic-gate 		break;
3680Sstevel@tonic-gate 	    case PARSE_INTEGER:
3690Sstevel@tonic-gate 		translation_table[count] = TYPE_INTEGER;
3700Sstevel@tonic-gate 		break;
3710Sstevel@tonic-gate 	    case NETADDR:
3720Sstevel@tonic-gate 		translation_table[count] = TYPE_IPADDR;
3730Sstevel@tonic-gate 		break;
3740Sstevel@tonic-gate 	    case IPADDR:
3750Sstevel@tonic-gate 		translation_table[count] = TYPE_IPADDR;
3760Sstevel@tonic-gate 		break;
3770Sstevel@tonic-gate 	    case PARSE_COUNTER:
3780Sstevel@tonic-gate 		translation_table[count] = TYPE_COUNTER;
3790Sstevel@tonic-gate 		break;
3800Sstevel@tonic-gate 	    case PARSE_GUAGE:
3810Sstevel@tonic-gate 		translation_table[count] = TYPE_GAUGE;
3820Sstevel@tonic-gate 		break;
3830Sstevel@tonic-gate 	    case PARSE_TIMETICKS:
3840Sstevel@tonic-gate 		translation_table[count] = TYPE_TIMETICKS;
3850Sstevel@tonic-gate 		break;
3860Sstevel@tonic-gate 	    case PARSE_OPAQUE:
3870Sstevel@tonic-gate 		translation_table[count] = TYPE_OPAQUE;
3880Sstevel@tonic-gate 		break;
3890Sstevel@tonic-gate 	    case NUL:
3900Sstevel@tonic-gate 		translation_table[count] = TYPE_NULL;
3910Sstevel@tonic-gate 		break;
3920Sstevel@tonic-gate 	    case PARSE_COUNTER64:
3930Sstevel@tonic-gate 		translation_table[count] = TYPE_COUNTER64;
3940Sstevel@tonic-gate 		break;
3950Sstevel@tonic-gate 	    case BITSTRING:
3960Sstevel@tonic-gate 		translation_table[count] = TYPE_BITSTRING;
3970Sstevel@tonic-gate 		break;
3980Sstevel@tonic-gate 	    case NSAPADDRESS:
3990Sstevel@tonic-gate 		translation_table[count] = TYPE_NSAPADDRESS;
4000Sstevel@tonic-gate 		break;
4010Sstevel@tonic-gate 	    case UINTEGER32:
4020Sstevel@tonic-gate 		translation_table[count] = TYPE_UINTEGER;
4030Sstevel@tonic-gate 		break;
4040Sstevel@tonic-gate 
4050Sstevel@tonic-gate /*
4060Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
4070Sstevel@tonic-gate */
4080Sstevel@tonic-gate 		case PSEUDO_TOKEN_TABLE:
4090Sstevel@tonic-gate 			translation_table[count] = TYPE_TABLE;
4100Sstevel@tonic-gate 			break;
4110Sstevel@tonic-gate 		case PSEUDO_TOKEN_ENTRY:
4120Sstevel@tonic-gate 			translation_table[count] = TYPE_ENTRY;
4130Sstevel@tonic-gate 			break;
4140Sstevel@tonic-gate 
4150Sstevel@tonic-gate 	    default:
4160Sstevel@tonic-gate 		translation_table[count] = TYPE_OTHER;
4170Sstevel@tonic-gate 		break;
4180Sstevel@tonic-gate 	}
4190Sstevel@tonic-gate     }
4200Sstevel@tonic-gate }
4210Sstevel@tonic-gate 
4220Sstevel@tonic-gate /*
4230Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
4240Sstevel@tonic-gate static struct tree *
4250Sstevel@tonic-gate */
4260Sstevel@tonic-gate struct tree *
build_tree(nodes)4270Sstevel@tonic-gate build_tree(nodes)
4280Sstevel@tonic-gate     struct node *nodes;
4290Sstevel@tonic-gate {
4300Sstevel@tonic-gate     struct node *np;
4310Sstevel@tonic-gate     struct tree *tp;
4320Sstevel@tonic-gate     int bucket, nodes_left = 0;
4330Sstevel@tonic-gate 
4340Sstevel@tonic-gate     build_translation_table();
4350Sstevel@tonic-gate     /* grow tree from this root node */
4360Sstevel@tonic-gate     init_node_hash(nodes);
4370Sstevel@tonic-gate 
4380Sstevel@tonic-gate /*
4390Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
4400Sstevel@tonic-gate      build root node
4410Sstevel@tonic-gate     tp = (struct tree *)Malloc(sizeof(struct tree));
4420Sstevel@tonic-gate     tp->parent = NULL;
4430Sstevel@tonic-gate     tp->next_peer = NULL;
4440Sstevel@tonic-gate     tp->child_list = NULL;
4450Sstevel@tonic-gate     tp->enums = NULL;
4460Sstevel@tonic-gate     strcpy(tp->label, "joint-iso-ccitt");
4470Sstevel@tonic-gate     tp->subid = 2;
4480Sstevel@tonic-gate     tp->type = 0;
4490Sstevel@tonic-gate     tp->description = 0;
4500Sstevel@tonic-gate      XXX nodes isn't needed in do_subtree() ???
4510Sstevel@tonic-gate     do_subtree(tp, &nodes);
4520Sstevel@tonic-gate     lasttp = tp;
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate      build root node
4550Sstevel@tonic-gate     tp = (struct tree *)Malloc(sizeof(struct tree));
4560Sstevel@tonic-gate     tp->parent = NULL;
4570Sstevel@tonic-gate     tp->next_peer = lasttp;
4580Sstevel@tonic-gate     tp->child_list = NULL;
4590Sstevel@tonic-gate     tp->enums = NULL;
4600Sstevel@tonic-gate     strcpy(tp->label, "ccitt");
4610Sstevel@tonic-gate     tp->subid = 0;
4620Sstevel@tonic-gate     tp->type = 0;
4630Sstevel@tonic-gate     tp->description = 0;
4640Sstevel@tonic-gate      XXX nodes isn't needed in do_subtree() ???
4650Sstevel@tonic-gate     do_subtree(tp, &nodes);
4660Sstevel@tonic-gate     lasttp = tp;
4670Sstevel@tonic-gate */
4680Sstevel@tonic-gate 
4690Sstevel@tonic-gate     /* build root node */
4700Sstevel@tonic-gate     tp = (struct tree *)Malloc(sizeof(struct tree));
4710Sstevel@tonic-gate     tp->parent = NULL;
4720Sstevel@tonic-gate /*
4730Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
4740Sstevel@tonic-gate     tp->next_peer = lasttp;
4750Sstevel@tonic-gate */
4760Sstevel@tonic-gate     tp->next_peer = NULL;
4770Sstevel@tonic-gate     tp->child_list = NULL;
4780Sstevel@tonic-gate     tp->enums = NULL;
4790Sstevel@tonic-gate     strcpy(tp->label, "iso");
4800Sstevel@tonic-gate     tp->subid = 1;
4810Sstevel@tonic-gate     tp->type = 0;
4820Sstevel@tonic-gate     tp->description = 0;
4830Sstevel@tonic-gate     /* XXX nodes isn't needed in do_subtree() ??? */
4840Sstevel@tonic-gate     do_subtree(tp, &nodes);
4850Sstevel@tonic-gate /*
4860Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
4870Sstevel@tonic-gate */
4880Sstevel@tonic-gate 	tp->access = 0;
4890Sstevel@tonic-gate 	tp->indexs = NULL;
4900Sstevel@tonic-gate 	tp->n_indexs = 0;
4910Sstevel@tonic-gate 
4920Sstevel@tonic-gate 
4930Sstevel@tonic-gate #ifdef TEST
4940Sstevel@tonic-gate     print_subtree(tp, 0);
4950Sstevel@tonic-gate #endif /* TEST */
4960Sstevel@tonic-gate     /* If any nodes are left, the tree is probably inconsistent */
4970Sstevel@tonic-gate     for(bucket = 0; bucket < NHASHSIZE; bucket++){
4980Sstevel@tonic-gate         if (nbuckets[bucket]){
4990Sstevel@tonic-gate 	    nodes_left = 1;
5000Sstevel@tonic-gate 	    break;
5010Sstevel@tonic-gate 	}
5020Sstevel@tonic-gate     }
5030Sstevel@tonic-gate     if (nodes_left){
5040Sstevel@tonic-gate 	fprintf(stderr, "The mib description doesn't seem to be consistent.\n");
5050Sstevel@tonic-gate 	fprintf(stderr, "Some nodes couldn't be linked under the \"iso\" tree.\n");
5060Sstevel@tonic-gate 	fprintf(stderr, "these nodes are left:\n");
5070Sstevel@tonic-gate 	for(bucket = 0; bucket < NHASHSIZE; bucket++){
5080Sstevel@tonic-gate 	    for(np = nbuckets[bucket]; np; np = np->next)
5090Sstevel@tonic-gate 	        fprintf(stderr, "%s ::= { %s %d } (%d)\n", np->label,
5100Sstevel@tonic-gate 			np->parent, np->subid, np->type);
5110Sstevel@tonic-gate 	}
5120Sstevel@tonic-gate     }
5130Sstevel@tonic-gate     return tp;
5140Sstevel@tonic-gate }
5150Sstevel@tonic-gate 
5160Sstevel@tonic-gate /*
5170Sstevel@tonic-gate  * Find all the children of root in the list of nodes.  Link them into the
5180Sstevel@tonic-gate  * tree and out of the nodes list.
5190Sstevel@tonic-gate  */
5200Sstevel@tonic-gate static void
do_subtree(root,nodes)5210Sstevel@tonic-gate do_subtree(root, nodes)
5220Sstevel@tonic-gate     struct tree *root;
5230Sstevel@tonic-gate     struct node **nodes;
5240Sstevel@tonic-gate {
5250Sstevel@tonic-gate     register struct tree *tp;
5260Sstevel@tonic-gate     register struct node *np, **headp;
5270Sstevel@tonic-gate     struct node *oldnp = NULL, *child_list = NULL, *childp = NULL;
5280Sstevel@tonic-gate     char *cp;
5290Sstevel@tonic-gate     int hash;
5300Sstevel@tonic-gate 
5310Sstevel@tonic-gate     tp = root;
5320Sstevel@tonic-gate     hash = 0;
5330Sstevel@tonic-gate     for(cp = tp->label; *cp; cp++)
5340Sstevel@tonic-gate         hash += *cp;
5350Sstevel@tonic-gate     headp = &nbuckets[NBUCKET(hash)];
5360Sstevel@tonic-gate     /*
5370Sstevel@tonic-gate      * Search each of the nodes for one whose parent is root, and
5380Sstevel@tonic-gate      * move each into a separate list.
5390Sstevel@tonic-gate      */
5400Sstevel@tonic-gate     for(np = *headp; np; np = np->next){
5410Sstevel@tonic-gate 	if ((*tp->label != *np->parent) || strcmp(tp->label, np->parent)){
5420Sstevel@tonic-gate 	    if ((*tp->label == *np->label) && !strcmp(tp->label, np->label)){
5430Sstevel@tonic-gate 		/* if there is another node with the same label, assume that
5440Sstevel@tonic-gate 		 * any children after this point in the list belong to the other node.
5450Sstevel@tonic-gate 		 * This adds some scoping to the table and allows vendors to
5460Sstevel@tonic-gate 		 * reuse names such as "ip".
5470Sstevel@tonic-gate 		 */
5480Sstevel@tonic-gate 		break;
5490Sstevel@tonic-gate 	    }
5500Sstevel@tonic-gate 	    oldnp = np;
5510Sstevel@tonic-gate 	} else {
5520Sstevel@tonic-gate 	    if (child_list == NULL){
5530Sstevel@tonic-gate 		child_list = childp = np;   /* first entry in child list */
5540Sstevel@tonic-gate 	    } else {
5550Sstevel@tonic-gate 		childp->next = np;
5560Sstevel@tonic-gate 		childp = np;
5570Sstevel@tonic-gate 	    }
5580Sstevel@tonic-gate 	    /* take this node out of the node list */
5590Sstevel@tonic-gate 	    if (oldnp == NULL){
5600Sstevel@tonic-gate 		*headp = np->next;  /* fix root of node list */
5610Sstevel@tonic-gate 	    } else {
5620Sstevel@tonic-gate 		oldnp->next = np->next;	/* link around this node */
5630Sstevel@tonic-gate 	    }
5640Sstevel@tonic-gate 	}
5650Sstevel@tonic-gate     }
5660Sstevel@tonic-gate     if (childp)
5670Sstevel@tonic-gate 	childp->next = 0;	/* re-terminate list */
5680Sstevel@tonic-gate     /*
5690Sstevel@tonic-gate      * Take each element in the child list and place it into the tree.
5700Sstevel@tonic-gate      */
5710Sstevel@tonic-gate     for(np = child_list; np; np = np->next){
5720Sstevel@tonic-gate 	tp = (struct tree *)Malloc(sizeof(struct tree));
5730Sstevel@tonic-gate 	tp->parent = root;
5740Sstevel@tonic-gate 	tp->next_peer = NULL;
5750Sstevel@tonic-gate 	tp->child_list = NULL;
5760Sstevel@tonic-gate 	strcpy(tp->label, np->label);
5770Sstevel@tonic-gate 	tp->subid = np->subid;
5780Sstevel@tonic-gate 	tp->type = translation_table[np->type];
5790Sstevel@tonic-gate         tp->oct_str_len = np->oct_str_len;
5800Sstevel@tonic-gate 	tp->enums = np->enums;
5810Sstevel@tonic-gate 	np->enums = NULL;	/* so we don't free them later */
5820Sstevel@tonic-gate 	tp->description = np->description; /* steals memory from np */
5830Sstevel@tonic-gate 	np->description = NULL; /* so we don't free it later */
5840Sstevel@tonic-gate /*
5850Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
5860Sstevel@tonic-gate */
5870Sstevel@tonic-gate 	tp->access = np->access;
5880Sstevel@tonic-gate 	tp->indexs = np->indexs;
5890Sstevel@tonic-gate 	np->indexs = NULL;
5900Sstevel@tonic-gate 	tp->n_indexs = np->n_indexs;
5910Sstevel@tonic-gate /*
5920Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
5930Sstevel@tonic-gate -- The goal of this modification is to order the
5940Sstevel@tonic-gate -- tree according to the subid
5950Sstevel@tonic-gate 
5960Sstevel@tonic-gate 	if (root->child_list == NULL){
5970Sstevel@tonic-gate 	    root->child_list = tp;
5980Sstevel@tonic-gate 	} else {
5990Sstevel@tonic-gate 	    peer->next_peer = tp;
6000Sstevel@tonic-gate 	}
6010Sstevel@tonic-gate 	peer = tp;
6020Sstevel@tonic-gate */
6030Sstevel@tonic-gate 	if(root->child_list == NULL)
6040Sstevel@tonic-gate 	{
6050Sstevel@tonic-gate 		root->child_list = tp;
6060Sstevel@tonic-gate 	}
6070Sstevel@tonic-gate 	else
6080Sstevel@tonic-gate 	{
6090Sstevel@tonic-gate 		struct tree *t = root->child_list;
6100Sstevel@tonic-gate 		struct tree *l = NULL;
6110Sstevel@tonic-gate 
6120Sstevel@tonic-gate 		while(t)
6130Sstevel@tonic-gate 		{
6140Sstevel@tonic-gate 			if(tp->subid < t->subid)
6150Sstevel@tonic-gate 			{
6160Sstevel@tonic-gate 				break;
6170Sstevel@tonic-gate 			}
6180Sstevel@tonic-gate 			l = t;
6190Sstevel@tonic-gate 			t = t->next_peer;
6200Sstevel@tonic-gate 		}
6210Sstevel@tonic-gate 		if(l == NULL)
6220Sstevel@tonic-gate 		{
6230Sstevel@tonic-gate 			tp->next_peer = root->child_list;
6240Sstevel@tonic-gate 			root->child_list = tp;
6250Sstevel@tonic-gate 		}
6260Sstevel@tonic-gate 		else
6270Sstevel@tonic-gate 		{
6280Sstevel@tonic-gate 			tp->next_peer = l->next_peer;
6290Sstevel@tonic-gate 			l->next_peer = tp;
6300Sstevel@tonic-gate 		}
6310Sstevel@tonic-gate 	}
6320Sstevel@tonic-gate 
6330Sstevel@tonic-gate /*	if (tp->type == TYPE_OTHER) */
6340Sstevel@tonic-gate 	    do_subtree(tp, nodes);	/* recurse on this child if it isn't
6350Sstevel@tonic-gate 					   an end node */
6360Sstevel@tonic-gate     }
6370Sstevel@tonic-gate     /* free all nodes that were copied into tree */
6380Sstevel@tonic-gate     oldnp = NULL;
6390Sstevel@tonic-gate     for(np = child_list; np; np = np->next){
6400Sstevel@tonic-gate 	if (oldnp)
6410Sstevel@tonic-gate 	    free(oldnp);
6420Sstevel@tonic-gate 	oldnp = np;
6430Sstevel@tonic-gate     }
6440Sstevel@tonic-gate     if (oldnp)
6450Sstevel@tonic-gate 	free(oldnp);
6460Sstevel@tonic-gate }
6470Sstevel@tonic-gate 
6480Sstevel@tonic-gate 
6490Sstevel@tonic-gate /*
6500Sstevel@tonic-gate  * Takes a list of the form:
6510Sstevel@tonic-gate  * { iso org(3) dod(6) 1 }
6520Sstevel@tonic-gate  * and creates several nodes, one for each parent-child pair.
6530Sstevel@tonic-gate  * Returns NULL on error.
6540Sstevel@tonic-gate  */
6550Sstevel@tonic-gate static int
getoid(fp,oid,length)6560Sstevel@tonic-gate getoid(fp, oid,  length)
6570Sstevel@tonic-gate     register FILE *fp;
6580Sstevel@tonic-gate     register struct subid *oid;	/* an array of subids */
6590Sstevel@tonic-gate     int length;	    /* the length of the array */
6600Sstevel@tonic-gate {
6610Sstevel@tonic-gate     register int count;
6620Sstevel@tonic-gate     int type;
6630Sstevel@tonic-gate     char token[MAXTOKEN];
6640Sstevel@tonic-gate     register char *cp;
6650Sstevel@tonic-gate 
6660Sstevel@tonic-gate #ifdef TRACE_PROC
6670Sstevel@tonic-gate printf("getoid() invoked\n");
6680Sstevel@tonic-gate #endif
6690Sstevel@tonic-gate 
6700Sstevel@tonic-gate     if ((type = get_token(fp, token)) != LEFTBRACKET){
6710Sstevel@tonic-gate 	print_error("Expected \"{\"", token, type);
6720Sstevel@tonic-gate 	return NULL;
6730Sstevel@tonic-gate     }
6740Sstevel@tonic-gate     type = get_token(fp, token);
6750Sstevel@tonic-gate     for(count = 0; count < length; count++, oid++){
6760Sstevel@tonic-gate 	oid->label = 0;
6770Sstevel@tonic-gate 	oid->subid = -1;
6780Sstevel@tonic-gate 	if (type == RIGHTBRACKET){
6790Sstevel@tonic-gate 	    return count;
6800Sstevel@tonic-gate 	} else if (type != LABEL && type != NUMBER){
6810Sstevel@tonic-gate 	    print_error("Not valid for object identifier", token, type);
6820Sstevel@tonic-gate 	    return NULL;
6830Sstevel@tonic-gate 	}
6840Sstevel@tonic-gate 	if (type == LABEL){
6850Sstevel@tonic-gate 	    /* this entry has a label */
6860Sstevel@tonic-gate 	    cp = (char *)Malloc((unsigned)strlen(token) + 1);
6870Sstevel@tonic-gate 	    strcpy(cp, token);
6880Sstevel@tonic-gate 	    oid->label = cp;
6890Sstevel@tonic-gate 	    type = get_token(fp, token);
6900Sstevel@tonic-gate 	    if (type == LEFTPAREN){
6910Sstevel@tonic-gate 		type = get_token(fp, token);
6920Sstevel@tonic-gate 		if (type == NUMBER){
6930Sstevel@tonic-gate 		    oid->subid = atoi(token);
6940Sstevel@tonic-gate 		    if ((type = get_token(fp, token)) != RIGHTPAREN){
6950Sstevel@tonic-gate 			print_error("Unexpected a closing parenthesis", token, type);
6960Sstevel@tonic-gate 			return NULL;
6970Sstevel@tonic-gate 		    }
6980Sstevel@tonic-gate 		} else {
6990Sstevel@tonic-gate 		    print_error("Expected a number", token, type);
7000Sstevel@tonic-gate 		    return NULL;
7010Sstevel@tonic-gate 		}
7020Sstevel@tonic-gate 	    } else {
7030Sstevel@tonic-gate 		continue;
7040Sstevel@tonic-gate 	    }
7050Sstevel@tonic-gate 	} else {
7060Sstevel@tonic-gate 	    /* this entry  has just an integer sub-identifier */
7070Sstevel@tonic-gate 	    oid->subid = atoi(token);
7080Sstevel@tonic-gate 	}
7090Sstevel@tonic-gate 	type = get_token(fp, token);
7100Sstevel@tonic-gate     }
7110Sstevel@tonic-gate     return count;
7120Sstevel@tonic-gate 
7130Sstevel@tonic-gate 
7140Sstevel@tonic-gate }
7150Sstevel@tonic-gate 
7160Sstevel@tonic-gate static void
free_node(np)7170Sstevel@tonic-gate free_node(np)
7180Sstevel@tonic-gate     struct node *np;
7190Sstevel@tonic-gate {
7200Sstevel@tonic-gate     struct enum_list *ep, *tep;
7210Sstevel@tonic-gate /*
7220Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
7230Sstevel@tonic-gate */
7240Sstevel@tonic-gate 	struct index_list *ip, *tip;
7250Sstevel@tonic-gate 
7260Sstevel@tonic-gate 	ip = np->indexs;
7270Sstevel@tonic-gate 	while(ip)
7280Sstevel@tonic-gate 	{
7290Sstevel@tonic-gate 		tip = ip;
7300Sstevel@tonic-gate 		ip = ip->next;
7310Sstevel@tonic-gate 		free((char *)tip);
7320Sstevel@tonic-gate 	}
7330Sstevel@tonic-gate 
7340Sstevel@tonic-gate 
7350Sstevel@tonic-gate     ep = np->enums;
7360Sstevel@tonic-gate     while(ep){
7370Sstevel@tonic-gate 	tep = ep;
7380Sstevel@tonic-gate 	ep = ep->next;
7390Sstevel@tonic-gate 	free((char *)tep);
7400Sstevel@tonic-gate     }
7410Sstevel@tonic-gate     free((char *)np);
7420Sstevel@tonic-gate }
7430Sstevel@tonic-gate 
parse_traptype(fp,name)7440Sstevel@tonic-gate int parse_traptype(fp,name)
7450Sstevel@tonic-gate FILE *fp;
7460Sstevel@tonic-gate char *name;
7470Sstevel@tonic-gate {
7480Sstevel@tonic-gate    int type;
7490Sstevel@tonic-gate    char token[MAXTOKEN];
7500Sstevel@tonic-gate    struct trap_item *ti;
7510Sstevel@tonic-gate    struct index_list *ip;
7520Sstevel@tonic-gate    static struct trap_item *last_trap_item=NULL;
7530Sstevel@tonic-gate 
7540Sstevel@tonic-gate #ifdef TRACE_PROC
7550Sstevel@tonic-gate printf("parse_traptype() invoked\n");
7560Sstevel@tonic-gate #endif
7570Sstevel@tonic-gate 
7580Sstevel@tonic-gate    type = get_token(fp,token);
7590Sstevel@tonic-gate    if( type == ENTERPRISE){
7600Sstevel@tonic-gate      if( (type = get_token(fp,token)) == LABEL){
7610Sstevel@tonic-gate 	/* create a trap item */
7620Sstevel@tonic-gate         ti = (struct trap_item*)calloc(1, sizeof(struct trap_item));
7630Sstevel@tonic-gate         if(ti==NULL){
7640Sstevel@tonic-gate 	 fprintf(stderr,"calloc failed\n");
7650Sstevel@tonic-gate 	 return 0;
7660Sstevel@tonic-gate         }
7670Sstevel@tonic-gate 	strcpy(ti->label,name);
7680Sstevel@tonic-gate 	strcpy(ti->enterprise_label,token);
7690Sstevel@tonic-gate 	ti->enterprise_subids[0] = (u_long)-1;
7700Sstevel@tonic-gate 
7710Sstevel@tonic-gate 	type = get_token(fp,token);
7720Sstevel@tonic-gate 	while(type != EQUALS){
7730Sstevel@tonic-gate 	  switch(type){
7740Sstevel@tonic-gate 	    case VARIABLES:
7750Sstevel@tonic-gate 		type = get_token(fp,token);
7760Sstevel@tonic-gate 		if(type != LEFTBRACKET){
7770Sstevel@tonic-gate 		  print_error("{ expected in VARIABLES clause",token,type);
7780Sstevel@tonic-gate 		  free(ti);
7790Sstevel@tonic-gate 		  return 0;
7800Sstevel@tonic-gate 		}
7810Sstevel@tonic-gate 		type = get_token(fp,token);
7820Sstevel@tonic-gate 		while(type != RIGHTBRACKET)
7830Sstevel@tonic-gate 		{
7840Sstevel@tonic-gate 			if(type != LABEL)
7850Sstevel@tonic-gate 			{
7860Sstevel@tonic-gate 				print_error("LABEL expected in VARIABLES1 clause",token,type);
7870Sstevel@tonic-gate 				free(ti);
7880Sstevel@tonic-gate 				return 0;
7890Sstevel@tonic-gate 			}
7900Sstevel@tonic-gate 
7910Sstevel@tonic-gate 
7920Sstevel@tonic-gate 			(ti->n_variables)++;
7930Sstevel@tonic-gate 		    	if(ti->var_list == NULL)
7940Sstevel@tonic-gate 			{
7950Sstevel@tonic-gate 				ip = ti->var_list = (struct index_list *)
7960Sstevel@tonic-gate 					Malloc(sizeof(struct index_list));
7970Sstevel@tonic-gate 			}
7980Sstevel@tonic-gate 			else
7990Sstevel@tonic-gate 			{
8000Sstevel@tonic-gate 				ip->next = (struct index_list *)
8010Sstevel@tonic-gate 					Malloc(sizeof(struct enum_list));
8020Sstevel@tonic-gate 				ip = ip->next;
8030Sstevel@tonic-gate 			}
8040Sstevel@tonic-gate 			ip->next = 0;
8050Sstevel@tonic-gate 			ip->tp = NULL;
8060Sstevel@tonic-gate 
8070Sstevel@tonic-gate 			ip->label =
8080Sstevel@tonic-gate 				(char *)Malloc((unsigned)strlen(token) + 1);
8090Sstevel@tonic-gate 			strcpy(ip->label, token);
8100Sstevel@tonic-gate 
8110Sstevel@tonic-gate 			type = get_token(fp, token);
8120Sstevel@tonic-gate 
8130Sstevel@tonic-gate 			switch(type)
8140Sstevel@tonic-gate 			{
8150Sstevel@tonic-gate 				case COMMA:
8160Sstevel@tonic-gate 					type = get_token(fp, token);
8170Sstevel@tonic-gate 					break;
8180Sstevel@tonic-gate 
8190Sstevel@tonic-gate 				case RIGHTBRACKET:
8200Sstevel@tonic-gate 					break;
8210Sstevel@tonic-gate 
8220Sstevel@tonic-gate 				default:
8230Sstevel@tonic-gate 					print_error(", or } expected in VARIABLES clause",token,type);
8240Sstevel@tonic-gate 					free(ti);
8250Sstevel@tonic-gate 					return 0;
8260Sstevel@tonic-gate 
8270Sstevel@tonic-gate 			}
8280Sstevel@tonic-gate 		}
8290Sstevel@tonic-gate 		break;
8300Sstevel@tonic-gate 
8310Sstevel@tonic-gate 	    case DESCRIPTION:
8320Sstevel@tonic-gate 		type = get_token(fp,token);
8330Sstevel@tonic-gate 		if(type != QUOTESTRING){
8340Sstevel@tonic-gate 		  print_error("Bad DESCRIPTION",token,type);
8350Sstevel@tonic-gate 		  free(ti);
8360Sstevel@tonic-gate 		  return 0;
8370Sstevel@tonic-gate 		}
8380Sstevel@tonic-gate 		ti->description = quoted_string_buffer;
8390Sstevel@tonic-gate 		quoted_string_buffer = (char*)malloc(MAXQUOTESTR);
8400Sstevel@tonic-gate 		if(quoted_string_buffer==NULL){
8410Sstevel@tonic-gate 		  fprintf(stderr,"malloc failed\n");
8420Sstevel@tonic-gate 		  return 0;
8430Sstevel@tonic-gate 		}
8440Sstevel@tonic-gate 		break;
8450Sstevel@tonic-gate 	    case REFERENCE:
8460Sstevel@tonic-gate 		type = get_token(fp,token);
8470Sstevel@tonic-gate 		if(type != QUOTESTRING){
8480Sstevel@tonic-gate 		  print_error("Bad DESCRIPTION",token,type);
8490Sstevel@tonic-gate 		  free(ti);
8500Sstevel@tonic-gate 		  return 0;
8510Sstevel@tonic-gate 		}
8520Sstevel@tonic-gate 		break;
8530Sstevel@tonic-gate 	    default:
8540Sstevel@tonic-gate 		/* NOTHING*/
8550Sstevel@tonic-gate 		break;
8560Sstevel@tonic-gate 	  }
8570Sstevel@tonic-gate 	  type = get_token(fp,token);
8580Sstevel@tonic-gate 	}
8590Sstevel@tonic-gate 	/* get the integer */
8600Sstevel@tonic-gate 	if( (type = get_token(fp,token)) == NUMBER){
8610Sstevel@tonic-gate 		ti->value = atoi(token);
8620Sstevel@tonic-gate 		/* attach the item to list */
8630Sstevel@tonic-gate 
8640Sstevel@tonic-gate 
8650Sstevel@tonic-gate 
8660Sstevel@tonic-gate 	}else{
8670Sstevel@tonic-gate         	print_error("Expected a number",token,type);
8680Sstevel@tonic-gate 		free(ti);
8690Sstevel@tonic-gate 		return 0;
8700Sstevel@tonic-gate 	}
8710Sstevel@tonic-gate      }else{
8720Sstevel@tonic-gate         print_error("Expected \"enterprise name\"",token,type);
8730Sstevel@tonic-gate         return 0;
8740Sstevel@tonic-gate      }
8750Sstevel@tonic-gate    }else{
8760Sstevel@tonic-gate      print_error("Expected \"ENTERPRISE\"",token,type);
8770Sstevel@tonic-gate      return 0;
8780Sstevel@tonic-gate    }
8790Sstevel@tonic-gate    if(trap_list == NULL){
8800Sstevel@tonic-gate 	last_trap_item = trap_list = ti;
8810Sstevel@tonic-gate    }else{
8820Sstevel@tonic-gate 	last_trap_item->next = ti;
8830Sstevel@tonic-gate 	last_trap_item = ti;
8840Sstevel@tonic-gate    }
8850Sstevel@tonic-gate    return 1;
8860Sstevel@tonic-gate }
8870Sstevel@tonic-gate 
8880Sstevel@tonic-gate /*
8890Sstevel@tonic-gate  * Parse an entry of the form:
8900Sstevel@tonic-gate  * label OBJECT IDENTIFIER ::= { parent 2 }
8910Sstevel@tonic-gate  * The "label OBJECT IDENTIFIER" portion has already been parsed.
8920Sstevel@tonic-gate  * Returns 0 on error.
8930Sstevel@tonic-gate  */
8940Sstevel@tonic-gate static struct node *
parse_objectid(fp,name)8950Sstevel@tonic-gate parse_objectid(fp, name)
8960Sstevel@tonic-gate     FILE *fp;
8970Sstevel@tonic-gate     char *name;
8980Sstevel@tonic-gate {
8990Sstevel@tonic-gate     int type;
9000Sstevel@tonic-gate     char token[MAXTOKEN];
9010Sstevel@tonic-gate     register int count;
9020Sstevel@tonic-gate     register struct subid *op, *nop;
9030Sstevel@tonic-gate     int length;
9040Sstevel@tonic-gate     struct subid oid[32];
9050Sstevel@tonic-gate     struct node *np, *root, *oldnp = NULL;
9060Sstevel@tonic-gate 
9070Sstevel@tonic-gate     type = get_token(fp, token);
9080Sstevel@tonic-gate     if (type != EQUALS){
9090Sstevel@tonic-gate 	print_error("Bad format", token, type);
9100Sstevel@tonic-gate 	return 0;
9110Sstevel@tonic-gate     }
9120Sstevel@tonic-gate     if ((length = getoid(fp, oid, 32)) != 0){
9130Sstevel@tonic-gate 	np = root = (struct node *)Malloc(sizeof(struct node));
9140Sstevel@tonic-gate 
9150Sstevel@tonic-gate /*
9160Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
9170Sstevel@tonic-gate 	bzero((char *)np, sizeof(struct node));
9180Sstevel@tonic-gate */
9190Sstevel@tonic-gate 	memset((void *) np, 0, sizeof(struct node));
9200Sstevel@tonic-gate 
9210Sstevel@tonic-gate 	/*
9220Sstevel@tonic-gate 	 * For each parent-child subid pair in the subid array,
9230Sstevel@tonic-gate 	 * create a node and link it into the node list.
9240Sstevel@tonic-gate 	 */
9250Sstevel@tonic-gate 	for(count = 0, op = oid, nop=oid+1; count < (length - 2); count++,
9260Sstevel@tonic-gate 	    op++, nop++){
9270Sstevel@tonic-gate 	    /* every node must have parent's name and child's name or number */
9280Sstevel@tonic-gate 	    if (op->label && (nop->label || (nop->subid != -1))){
9290Sstevel@tonic-gate 		strcpy(np->parent, op->label);
9300Sstevel@tonic-gate 		if (nop->label)
9310Sstevel@tonic-gate 		    strcpy(np->label, nop->label);
9320Sstevel@tonic-gate 		if (nop->subid != -1)
9330Sstevel@tonic-gate 		    np->subid = nop->subid;
9340Sstevel@tonic-gate 		np->type = 0;
9350Sstevel@tonic-gate 		np->enums = 0;
9360Sstevel@tonic-gate /*
9370Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
9380Sstevel@tonic-gate */
9390Sstevel@tonic-gate 		np->access = 0;
9400Sstevel@tonic-gate 		np->n_indexs = 0;
9410Sstevel@tonic-gate 		np->indexs = NULL;
9420Sstevel@tonic-gate 
9430Sstevel@tonic-gate 		/* set up next entry */
9440Sstevel@tonic-gate 		np->next = (struct node *)Malloc(sizeof(*np->next));
9450Sstevel@tonic-gate 
9460Sstevel@tonic-gate /*
9470Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
9480Sstevel@tonic-gate 		bzero((char *)np->next, sizeof(struct node));
9490Sstevel@tonic-gate */
9500Sstevel@tonic-gate 		memset((void *) np->next, 0, sizeof(struct node));
9510Sstevel@tonic-gate 
9520Sstevel@tonic-gate 		oldnp = np;
9530Sstevel@tonic-gate 		np = np->next;
9540Sstevel@tonic-gate 	    }
9550Sstevel@tonic-gate 	}
9560Sstevel@tonic-gate 	np->next = (struct node *)NULL;
9570Sstevel@tonic-gate 	/*
9580Sstevel@tonic-gate 	 * The above loop took care of all but the last pair.  This pair is taken
9590Sstevel@tonic-gate 	 * care of here.  The name for this node is taken from the label for this
9600Sstevel@tonic-gate 	 * entry.
9610Sstevel@tonic-gate 	 * np still points to an unused entry.
9620Sstevel@tonic-gate 	 */
9630Sstevel@tonic-gate 	if (count == (length - 2)){
9640Sstevel@tonic-gate 	    if (op->label){
9650Sstevel@tonic-gate 		strcpy(np->parent, op->label);
9660Sstevel@tonic-gate 		strcpy(np->label, name);
9670Sstevel@tonic-gate 		if (nop->subid != -1)
9680Sstevel@tonic-gate 		    np->subid = nop->subid;
9690Sstevel@tonic-gate 		else
9700Sstevel@tonic-gate 		    print_error("Warning: This entry is pretty silly",
9710Sstevel@tonic-gate 				np->label, type);
9720Sstevel@tonic-gate 	    } else {
9730Sstevel@tonic-gate 		free_node(np);
9740Sstevel@tonic-gate 		if (oldnp)
9750Sstevel@tonic-gate 		    oldnp->next = NULL;
9760Sstevel@tonic-gate 		else
9770Sstevel@tonic-gate 		    return NULL;
9780Sstevel@tonic-gate 	    }
9790Sstevel@tonic-gate 	} else {
9800Sstevel@tonic-gate 	    print_error("Missing end of oid", (char *)NULL, type);
9810Sstevel@tonic-gate 	    free_node(np);   /* the last node allocated wasn't used */
9820Sstevel@tonic-gate 	    if (oldnp)
9830Sstevel@tonic-gate 		oldnp->next = NULL;
9840Sstevel@tonic-gate 	    return NULL;
9850Sstevel@tonic-gate 	}
9860Sstevel@tonic-gate 	/* free the oid array */
9870Sstevel@tonic-gate 	for(count = 0, op = oid; count < length; count++, op++){
9880Sstevel@tonic-gate 	    if (op->label)
9890Sstevel@tonic-gate 		free(op->label);
9900Sstevel@tonic-gate 	    op->label = 0;
9910Sstevel@tonic-gate 	}
9920Sstevel@tonic-gate 	return root;
9930Sstevel@tonic-gate     } else {
9940Sstevel@tonic-gate 	print_error("Bad object identifier", (char *)NULL, type);
9950Sstevel@tonic-gate 	return 0;
9960Sstevel@tonic-gate     }
9970Sstevel@tonic-gate }
9980Sstevel@tonic-gate 
9990Sstevel@tonic-gate static int
get_tc(descriptor,ep)10000Sstevel@tonic-gate get_tc(descriptor, ep)
10010Sstevel@tonic-gate     char *descriptor;
10020Sstevel@tonic-gate     struct enum_list **ep;
10030Sstevel@tonic-gate {
10040Sstevel@tonic-gate     int i;
10050Sstevel@tonic-gate 
10060Sstevel@tonic-gate     for(i = 0; i < MAXTC; i++){
10070Sstevel@tonic-gate 	if (tclist[i].type == 0)
10080Sstevel@tonic-gate 	    break;
10090Sstevel@tonic-gate 	if (!strcmp(descriptor, tclist[i].descriptor)){
10100Sstevel@tonic-gate 	    *ep = tclist[i].enums;
10110Sstevel@tonic-gate 	    return tclist[i].type;
10120Sstevel@tonic-gate 	}
10130Sstevel@tonic-gate     }
10140Sstevel@tonic-gate     return LABEL;
10150Sstevel@tonic-gate }
10160Sstevel@tonic-gate 
10170Sstevel@tonic-gate /*
10180Sstevel@tonic-gate  * Parses an asn type.  Structures are ignored by this parser.
10190Sstevel@tonic-gate  * Returns NULL on error.
10200Sstevel@tonic-gate  */
10210Sstevel@tonic-gate static int
parse_asntype(fp,name,ntype,ntoken)10220Sstevel@tonic-gate parse_asntype(fp, name, ntype, ntoken)
10230Sstevel@tonic-gate     FILE *fp;
10240Sstevel@tonic-gate     char *name;
10250Sstevel@tonic-gate     int *ntype;
10260Sstevel@tonic-gate     char *ntoken;
10270Sstevel@tonic-gate {
10280Sstevel@tonic-gate     int type, i;
10290Sstevel@tonic-gate     char token[MAXTOKEN];
10300Sstevel@tonic-gate     struct enum_list *ep;
10310Sstevel@tonic-gate     struct tc *tcp;
10320Sstevel@tonic-gate     int level;
10330Sstevel@tonic-gate 
10340Sstevel@tonic-gate #ifdef TRACE_PROC
10350Sstevel@tonic-gate printf("parse_asntype() invoked\n");
10360Sstevel@tonic-gate #endif
10370Sstevel@tonic-gate 
10380Sstevel@tonic-gate     type = get_token(fp, token);
10390Sstevel@tonic-gate     if (type == SEQUENCE){
10400Sstevel@tonic-gate 	while((type = get_token(fp, token)) != ENDOFFILE){
10410Sstevel@tonic-gate 	    if (type == RIGHTBRACKET){
10420Sstevel@tonic-gate 		*ntype = get_token(fp, ntoken);
10430Sstevel@tonic-gate 		return 1;
10440Sstevel@tonic-gate 	    }
10450Sstevel@tonic-gate 	}
10460Sstevel@tonic-gate 	print_error("Expected \"}\"", token, type);
10470Sstevel@tonic-gate 	return 0;
10480Sstevel@tonic-gate     } else {
10490Sstevel@tonic-gate 	if (!strcmp(token, "TEXTUAL-CONVENTION")){
10500Sstevel@tonic-gate 	    while (type != SYNTAX)
10510Sstevel@tonic-gate 		type = get_token(fp, token);
10520Sstevel@tonic-gate 	    type = get_token(fp, token);
10530Sstevel@tonic-gate 	}
10540Sstevel@tonic-gate 	/* textual convention */
10550Sstevel@tonic-gate 	for(i = 0; i < MAXTC; i++){
10560Sstevel@tonic-gate 	    if (tclist[i].type == 0)
10570Sstevel@tonic-gate 		break;
10580Sstevel@tonic-gate 	}
10590Sstevel@tonic-gate 	if (i == MAXTC){
10600Sstevel@tonic-gate 	    print_error("No more textual conventions possible.", token, type);
10610Sstevel@tonic-gate 	    return 0;
10620Sstevel@tonic-gate 	}
10630Sstevel@tonic-gate 	tcp = &tclist[i];
10640Sstevel@tonic-gate 	strcpy(tcp->descriptor, name);
10650Sstevel@tonic-gate 	if (!(type & SYNTAX_MASK)){
10660Sstevel@tonic-gate 
10670Sstevel@tonic-gate /*
10680Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
10690Sstevel@tonic-gate 	    print_error("Textual convention doesn't map to real type.", token,
10700Sstevel@tonic-gate 			type);
10710Sstevel@tonic-gate 	    return 0;
10720Sstevel@tonic-gate 	}
10730Sstevel@tonic-gate */
10740Sstevel@tonic-gate 		int w;
10750Sstevel@tonic-gate 
10760Sstevel@tonic-gate 		w = get_tc(token, &ep);
10770Sstevel@tonic-gate 		if(!(w & SYNTAX_MASK))
10780Sstevel@tonic-gate 		{
10790Sstevel@tonic-gate 	    		print_error("Textual convention doesn't map to real type.", token, type);
10800Sstevel@tonic-gate 	    		return 0;
10810Sstevel@tonic-gate 		}
10820Sstevel@tonic-gate 		type = w;
10830Sstevel@tonic-gate 	}
10840Sstevel@tonic-gate 
10850Sstevel@tonic-gate 	tcp->type = type;
10860Sstevel@tonic-gate 	*ntype = get_token(fp, ntoken);
10870Sstevel@tonic-gate 	if (*ntype == LEFTPAREN){
10880Sstevel@tonic-gate 	    level = 1;
10890Sstevel@tonic-gate 	    /* don't record any constraints for now */
10900Sstevel@tonic-gate 	    while(level > 0){
10910Sstevel@tonic-gate 		*ntype = get_token(fp, ntoken);
10920Sstevel@tonic-gate 		if (*ntype == LEFTPAREN)
10930Sstevel@tonic-gate 		    level++;
10940Sstevel@tonic-gate 		if (*ntype == RIGHTPAREN)
10950Sstevel@tonic-gate 		    level--;
10960Sstevel@tonic-gate 	    }
10970Sstevel@tonic-gate 	    *ntype = get_token(fp, ntoken);
10980Sstevel@tonic-gate 	} else if (*ntype == LEFTBRACKET) {
10990Sstevel@tonic-gate 	    /* if there is an enumeration list, parse it */
11000Sstevel@tonic-gate 	    while((type = get_token(fp, token)) != ENDOFFILE){
11010Sstevel@tonic-gate 		if (type == RIGHTBRACKET)
11020Sstevel@tonic-gate 		    break;
11030Sstevel@tonic-gate 		if (type == LABEL){
11040Sstevel@tonic-gate 		    /* this is an enumerated label */
11050Sstevel@tonic-gate 		    if (tcp->enums == 0){
11060Sstevel@tonic-gate 			ep = tcp->enums = (struct enum_list *)
11070Sstevel@tonic-gate 			    Malloc(sizeof(struct enum_list));
11080Sstevel@tonic-gate 		    } else {
11090Sstevel@tonic-gate 			ep->next = (struct enum_list *)
11100Sstevel@tonic-gate 			    Malloc(sizeof(struct enum_list));
11110Sstevel@tonic-gate 			ep = ep->next;
11120Sstevel@tonic-gate 		    }
11130Sstevel@tonic-gate 		    ep->next = 0;
11140Sstevel@tonic-gate 		    /* a reasonable approximation for the length */
11150Sstevel@tonic-gate 		    ep->label =
11160Sstevel@tonic-gate 			(char *)Malloc((unsigned)strlen(token) + 1);
11170Sstevel@tonic-gate 		    strcpy(ep->label, token);
11180Sstevel@tonic-gate 		    type = get_token(fp, token);
11190Sstevel@tonic-gate 		    if (type != LEFTPAREN){
11200Sstevel@tonic-gate 			print_error("Expected \"(\"", token, type);
11210Sstevel@tonic-gate 			/* free_node(np); */
11220Sstevel@tonic-gate 			return 0;
11230Sstevel@tonic-gate 		    }
11240Sstevel@tonic-gate 		    type = get_token(fp, token);
11250Sstevel@tonic-gate 		    if (type != NUMBER){
11260Sstevel@tonic-gate 			print_error("Expected integer", token, type);
11270Sstevel@tonic-gate 			/* free_node(np); */
11280Sstevel@tonic-gate 			return 0;
11290Sstevel@tonic-gate 		    }
11300Sstevel@tonic-gate 		    ep->value = atoi(token);
11310Sstevel@tonic-gate 		    type = get_token(fp, token);
11320Sstevel@tonic-gate 		    if (type != RIGHTPAREN){
11330Sstevel@tonic-gate 			print_error("Expected \")\"", token, type);
11340Sstevel@tonic-gate 			/* free_node(np); */
11350Sstevel@tonic-gate 			return 0;
11360Sstevel@tonic-gate 		    }
11370Sstevel@tonic-gate 		}
11380Sstevel@tonic-gate 	    }
11390Sstevel@tonic-gate 	    if (type == ENDOFFILE){
11400Sstevel@tonic-gate 		print_error("Expected \"}\"", token, type);
11410Sstevel@tonic-gate 		/* free_node(np); */
11420Sstevel@tonic-gate 		return 0;
11430Sstevel@tonic-gate 	    }
11440Sstevel@tonic-gate 	    *ntype = get_token(fp, ntoken);
11450Sstevel@tonic-gate 	}
11460Sstevel@tonic-gate 	return 1;
11470Sstevel@tonic-gate     }
11480Sstevel@tonic-gate }
11490Sstevel@tonic-gate 
11500Sstevel@tonic-gate 
11510Sstevel@tonic-gate /*
11520Sstevel@tonic-gate  * Parses an OBJECT TYPE macro.
11530Sstevel@tonic-gate  * Returns 0 on error.
11540Sstevel@tonic-gate  */
11550Sstevel@tonic-gate static struct node *
parse_objecttype(fp,name)11560Sstevel@tonic-gate parse_objecttype(fp, name)
11570Sstevel@tonic-gate     register FILE *fp;
11580Sstevel@tonic-gate     char *name;
11590Sstevel@tonic-gate {
11600Sstevel@tonic-gate     register int type;
11610Sstevel@tonic-gate     char token[MAXTOKEN];
11620Sstevel@tonic-gate     int count, length;
11630Sstevel@tonic-gate     struct subid oid[32];
11640Sstevel@tonic-gate     char syntax[MAXTOKEN];
11650Sstevel@tonic-gate     int nexttype, tctype;
11660Sstevel@tonic-gate     char nexttoken[MAXTOKEN];
11670Sstevel@tonic-gate     register struct node *np;
11680Sstevel@tonic-gate     register struct enum_list *ep;
11690Sstevel@tonic-gate /*
11700Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
11710Sstevel@tonic-gate */
11720Sstevel@tonic-gate 	struct index_list *ip;
11730Sstevel@tonic-gate 
11740Sstevel@tonic-gate     type = get_token(fp, token);
11750Sstevel@tonic-gate     if (type != SYNTAX){
11760Sstevel@tonic-gate 	print_error("Bad format for OBJECT TYPE", token, type);
11770Sstevel@tonic-gate 	return 0;
11780Sstevel@tonic-gate     }
11790Sstevel@tonic-gate     np = (struct node *)Malloc(sizeof(struct node));
11800Sstevel@tonic-gate     np->next = 0;
11810Sstevel@tonic-gate     np->enums = 0;
11820Sstevel@tonic-gate     np->description = NULL;        /* default to an empty description */
11830Sstevel@tonic-gate /*
11840Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
11850Sstevel@tonic-gate */
11860Sstevel@tonic-gate 	np->access = 0;
11870Sstevel@tonic-gate 	np->n_indexs = 0;
11880Sstevel@tonic-gate 	np->indexs = 0;
11890Sstevel@tonic-gate 
11900Sstevel@tonic-gate     type = get_token(fp, token);
11910Sstevel@tonic-gate     if (type == LABEL){
11920Sstevel@tonic-gate 	tctype = get_tc(token, &(np->enums));
11930Sstevel@tonic-gate #if 0
11940Sstevel@tonic-gate 	if (tctype == LABEL){
11950Sstevel@tonic-gate 	    print_error("No known translation for type", token, type);
11960Sstevel@tonic-gate 	    return 0;
11970Sstevel@tonic-gate 	}
11980Sstevel@tonic-gate #endif
11990Sstevel@tonic-gate 	type = tctype;
12000Sstevel@tonic-gate     }
12010Sstevel@tonic-gate     np->type = type;
12020Sstevel@tonic-gate     np->oct_str_len = 0;
12030Sstevel@tonic-gate     nexttype = get_token(fp, nexttoken);
12040Sstevel@tonic-gate     switch(type){
12050Sstevel@tonic-gate 	case SEQUENCE:
12060Sstevel@tonic-gate 	    strcpy(syntax, token);
12070Sstevel@tonic-gate 	    if (nexttype == OF){
12080Sstevel@tonic-gate 		strcat(syntax, " ");
12090Sstevel@tonic-gate 		strcat(syntax, nexttoken);
12100Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
12110Sstevel@tonic-gate 		strcat(syntax, " ");
12120Sstevel@tonic-gate 		strcat(syntax, nexttoken);
12130Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
12140Sstevel@tonic-gate 
12150Sstevel@tonic-gate /*
12160Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
12170Sstevel@tonic-gate */
12180Sstevel@tonic-gate 		np->type = PSEUDO_TOKEN_TABLE;
12190Sstevel@tonic-gate 	    }
12200Sstevel@tonic-gate 
12210Sstevel@tonic-gate 	    break;
12220Sstevel@tonic-gate 	case PARSE_INTEGER:
12230Sstevel@tonic-gate 	case UINTEGER32:
12240Sstevel@tonic-gate 	    strcpy(syntax, token);
12250Sstevel@tonic-gate 	    if (nexttype == LEFTBRACKET) {
12260Sstevel@tonic-gate 		/* if there is an enumeration list, parse it */
12270Sstevel@tonic-gate 		while((type = get_token(fp, token)) != ENDOFFILE){
12280Sstevel@tonic-gate 		    if (type == RIGHTBRACKET)
12290Sstevel@tonic-gate 			break;
12300Sstevel@tonic-gate 		    if (type == LABEL){
12310Sstevel@tonic-gate 			/* this is an enumerated label */
12320Sstevel@tonic-gate 			if (np->enums == 0){
12330Sstevel@tonic-gate 			    ep = np->enums = (struct enum_list *)
12340Sstevel@tonic-gate 					Malloc(sizeof(struct enum_list));
12350Sstevel@tonic-gate 			} else {
12360Sstevel@tonic-gate 			    ep->next = (struct enum_list *)
12370Sstevel@tonic-gate 					Malloc(sizeof(struct enum_list));
12380Sstevel@tonic-gate 			    ep = ep->next;
12390Sstevel@tonic-gate 			}
12400Sstevel@tonic-gate 			ep->next = 0;
12410Sstevel@tonic-gate 			/* a reasonable approximation for the length */
12420Sstevel@tonic-gate 			ep->label =
12430Sstevel@tonic-gate 			    (char *)Malloc((unsigned)strlen(token) + 1);
12440Sstevel@tonic-gate 			strcpy(ep->label, token);
12450Sstevel@tonic-gate 			type = get_token(fp, token);
12460Sstevel@tonic-gate 			if (type != LEFTPAREN){
12470Sstevel@tonic-gate 			    print_error("Expected \"(\"", token, type);
12480Sstevel@tonic-gate 			    free_node(np);
12490Sstevel@tonic-gate 			    return 0;
12500Sstevel@tonic-gate 			}
12510Sstevel@tonic-gate 			type = get_token(fp, token);
12520Sstevel@tonic-gate 			if (type != NUMBER){
12530Sstevel@tonic-gate 			    print_error("Expected integer", token, type);
12540Sstevel@tonic-gate 			    free_node(np);
12550Sstevel@tonic-gate 			    return 0;
12560Sstevel@tonic-gate 			}
12570Sstevel@tonic-gate 			ep->value = atoi(token);
12580Sstevel@tonic-gate 			type = get_token(fp, token);
12590Sstevel@tonic-gate 			if (type != RIGHTPAREN){
12600Sstevel@tonic-gate 			    print_error("Expected \")\"", token, type);
12610Sstevel@tonic-gate 			    free_node(np);
12620Sstevel@tonic-gate 			    return 0;
12630Sstevel@tonic-gate 			}
12640Sstevel@tonic-gate 		    }
12650Sstevel@tonic-gate 		}
12660Sstevel@tonic-gate 		if (type == ENDOFFILE){
12670Sstevel@tonic-gate 		    print_error("Expected \"}\"", token, type);
12680Sstevel@tonic-gate 		    free_node(np);
12690Sstevel@tonic-gate 		    return 0;
12700Sstevel@tonic-gate 		}
12710Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
12720Sstevel@tonic-gate 	    } else if (nexttype == LEFTPAREN){
12730Sstevel@tonic-gate 		/* ignore the "constrained integer" for now */
12740Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
12750Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
12760Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
12770Sstevel@tonic-gate 	    }
12780Sstevel@tonic-gate 	    break;
12790Sstevel@tonic-gate 	case BITSTRING:
12800Sstevel@tonic-gate 	    strcpy(syntax, token);
12810Sstevel@tonic-gate 	    if (nexttype == LEFTBRACKET) {
12820Sstevel@tonic-gate 		/* if there is an enumeration list, parse it */
12830Sstevel@tonic-gate 		while((type = get_token(fp, token)) != ENDOFFILE){
12840Sstevel@tonic-gate 		    if (type == RIGHTBRACKET)
12850Sstevel@tonic-gate 			break;
12860Sstevel@tonic-gate 		    if (type == LABEL){
12870Sstevel@tonic-gate 			/* this is an enumerated label */
12880Sstevel@tonic-gate 			if (np->enums == 0){
12890Sstevel@tonic-gate 			    ep = np->enums = (struct enum_list *)
12900Sstevel@tonic-gate 					Malloc(sizeof(struct enum_list));
12910Sstevel@tonic-gate 			} else {
12920Sstevel@tonic-gate 			    ep->next = (struct enum_list *)
12930Sstevel@tonic-gate 					Malloc(sizeof(struct enum_list));
12940Sstevel@tonic-gate 			    ep = ep->next;
12950Sstevel@tonic-gate 			}
12960Sstevel@tonic-gate 			ep->next = 0;
12970Sstevel@tonic-gate 			/* a reasonable approximation for the length */
12980Sstevel@tonic-gate 			ep->label =
12990Sstevel@tonic-gate 			    (char *)Malloc((unsigned)strlen(token) + 1);
13000Sstevel@tonic-gate 			strcpy(ep->label, token);
13010Sstevel@tonic-gate 			type = get_token(fp, token);
13020Sstevel@tonic-gate 			if (type != LEFTPAREN){
13030Sstevel@tonic-gate 			    print_error("Expected \"(\"", token, type);
13040Sstevel@tonic-gate 			    free_node(np);
13050Sstevel@tonic-gate 			    return 0;
13060Sstevel@tonic-gate 			}
13070Sstevel@tonic-gate 			type = get_token(fp, token);
13080Sstevel@tonic-gate 			if (type != NUMBER){
13090Sstevel@tonic-gate 			    print_error("Expected integer", token, type);
13100Sstevel@tonic-gate 			    free_node(np);
13110Sstevel@tonic-gate 			    return 0;
13120Sstevel@tonic-gate 			}
13130Sstevel@tonic-gate 			ep->value = atoi(token);
13140Sstevel@tonic-gate 			type = get_token(fp, token);
13150Sstevel@tonic-gate 			if (type != RIGHTPAREN){
13160Sstevel@tonic-gate 			    print_error("Expected \")\"", token, type);
13170Sstevel@tonic-gate 			    free_node(np);
13180Sstevel@tonic-gate 			    return 0;
13190Sstevel@tonic-gate 			}
13200Sstevel@tonic-gate 		    }
13210Sstevel@tonic-gate 		}
13220Sstevel@tonic-gate 		if (type == ENDOFFILE){
13230Sstevel@tonic-gate 		    print_error("Expected \"}\"", token, type);
13240Sstevel@tonic-gate 		    free_node(np);
13250Sstevel@tonic-gate 		    return 0;
13260Sstevel@tonic-gate 		}
13270Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
13280Sstevel@tonic-gate 	    } else if (nexttype == LEFTPAREN){
13290Sstevel@tonic-gate 		/* ignore the "constrained integer" for now */
13300Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
13310Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
13320Sstevel@tonic-gate 		nexttype = get_token(fp, nexttoken);
13330Sstevel@tonic-gate 	    }
13340Sstevel@tonic-gate 	    break;
13350Sstevel@tonic-gate 	case OCTETSTR:
13360Sstevel@tonic-gate 	    strcpy(syntax, token);
13370Sstevel@tonic-gate             /* ignore the "constrained octet string" for now */
13380Sstevel@tonic-gate             if (nexttype == LEFTPAREN) {
13390Sstevel@tonic-gate                 nexttype = get_token(fp, nexttoken);
13400Sstevel@tonic-gate                 if (nexttype == SIZE) {
13410Sstevel@tonic-gate                     nexttype = get_token(fp, nexttoken);
13420Sstevel@tonic-gate                     if (nexttype == LEFTPAREN) {
13430Sstevel@tonic-gate                         nexttype = get_token(fp, nexttoken); /* 0..255 */
13440Sstevel@tonic-gate                         np->oct_str_len = number_value;
13450Sstevel@tonic-gate                         number_value = 0;
13460Sstevel@tonic-gate                         nexttype = get_token(fp, nexttoken); /* ) */
13470Sstevel@tonic-gate                         nexttype = get_token(fp, nexttoken); /* ) */
13480Sstevel@tonic-gate                         if (nexttype == RIGHTPAREN)
13490Sstevel@tonic-gate                         {
13500Sstevel@tonic-gate                             nexttype = get_token(fp, nexttoken);
13510Sstevel@tonic-gate                             break;
13520Sstevel@tonic-gate                         }
13530Sstevel@tonic-gate                     }
13540Sstevel@tonic-gate                 }
13550Sstevel@tonic-gate                 print_error("Bad syntax", token, type);
13560Sstevel@tonic-gate                 free_node(np);
13570Sstevel@tonic-gate                 return 0;
13580Sstevel@tonic-gate             }
13590Sstevel@tonic-gate 	    break;
13600Sstevel@tonic-gate 	case PARSE_OBJID:
13610Sstevel@tonic-gate 	case NETADDR:
13620Sstevel@tonic-gate 	case IPADDR:
13630Sstevel@tonic-gate 	case PARSE_COUNTER:
13640Sstevel@tonic-gate 	case PARSE_GUAGE:
13650Sstevel@tonic-gate 	case PARSE_TIMETICKS:
13660Sstevel@tonic-gate 	case PARSE_OPAQUE:
13670Sstevel@tonic-gate 	case NUL:
13680Sstevel@tonic-gate 	case LABEL:
13690Sstevel@tonic-gate 	case NSAPADDRESS:
13700Sstevel@tonic-gate 	case PARSE_COUNTER64:
13710Sstevel@tonic-gate 	    strcpy(syntax, token);
13720Sstevel@tonic-gate 	    break;
13730Sstevel@tonic-gate 	default:
13740Sstevel@tonic-gate 	    print_error("Bad syntax", token, type);
13750Sstevel@tonic-gate 	    free_node(np);
13760Sstevel@tonic-gate 	    return 0;
13770Sstevel@tonic-gate     }
13780Sstevel@tonic-gate     if (nexttype == UNITS){
13790Sstevel@tonic-gate 	type = get_token(fp, token);
13800Sstevel@tonic-gate 	if (type != QUOTESTRING) {
13810Sstevel@tonic-gate 	    print_error("Bad DESCRIPTION", token, type);
13820Sstevel@tonic-gate 	    free_node(np);
13830Sstevel@tonic-gate 	    return 0;
13840Sstevel@tonic-gate 	}
13850Sstevel@tonic-gate 	nexttype = get_token(fp, nexttoken);
13860Sstevel@tonic-gate     }
13870Sstevel@tonic-gate     if (nexttype != ACCESS){
13880Sstevel@tonic-gate 	print_error("Should be ACCESS", nexttoken, nexttype);
13890Sstevel@tonic-gate 	free_node(np);
13900Sstevel@tonic-gate 	return 0;
13910Sstevel@tonic-gate     }
13920Sstevel@tonic-gate     type = get_token(fp, token);
13930Sstevel@tonic-gate     if (type != READONLY && type != READWRITE && type != WRITEONLY
13940Sstevel@tonic-gate 	&& type != NOACCESS && type != READCREATE){
13950Sstevel@tonic-gate 	print_error("Bad access type", nexttoken, nexttype);
13960Sstevel@tonic-gate 	free_node(np);
13970Sstevel@tonic-gate 	return 0;
13980Sstevel@tonic-gate     }
13990Sstevel@tonic-gate 
14000Sstevel@tonic-gate /*
14010Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
14020Sstevel@tonic-gate */
14030Sstevel@tonic-gate 	switch(type)
14040Sstevel@tonic-gate 	{
14050Sstevel@tonic-gate 		case READONLY:
14060Sstevel@tonic-gate 			np->access = READ_FLAG;
14070Sstevel@tonic-gate 			break;
14080Sstevel@tonic-gate 
14090Sstevel@tonic-gate 		case READWRITE:
14100Sstevel@tonic-gate 			np->access = READ_FLAG | WRITE_FLAG;
14110Sstevel@tonic-gate 			break;
14120Sstevel@tonic-gate 
14130Sstevel@tonic-gate 		case WRITEONLY:
14140Sstevel@tonic-gate 			np->access = WRITE_FLAG;
14150Sstevel@tonic-gate 			break;
14160Sstevel@tonic-gate 
14170Sstevel@tonic-gate 		case NOACCESS:
14180Sstevel@tonic-gate 			np->access = 0;
14190Sstevel@tonic-gate 			break;
14200Sstevel@tonic-gate 
14210Sstevel@tonic-gate 		case READCREATE:
14220Sstevel@tonic-gate 			np->access = READ_FLAG | CREATE_FLAG;
14230Sstevel@tonic-gate 			break;
14240Sstevel@tonic-gate 	}
14250Sstevel@tonic-gate 
14260Sstevel@tonic-gate     type = get_token(fp, token);
14270Sstevel@tonic-gate     if (type != STATUS){
14280Sstevel@tonic-gate 	print_error("Should be STATUS", token, nexttype);
14290Sstevel@tonic-gate 	free_node(np);
14300Sstevel@tonic-gate 	return 0;
14310Sstevel@tonic-gate     }
14320Sstevel@tonic-gate     type = get_token(fp, token);
14330Sstevel@tonic-gate     if (type != MANDATORY && type != CURRENT && type != OPTIONAL && type != OBSOLETE && type != DEPRECATED){
14340Sstevel@tonic-gate 	print_error("Bad status", token, type);
14350Sstevel@tonic-gate 	free_node(np);
14360Sstevel@tonic-gate 	return 0;
14370Sstevel@tonic-gate     }
14380Sstevel@tonic-gate     /*
14390Sstevel@tonic-gate      * Optional parts of the OBJECT-TYPE macro
14400Sstevel@tonic-gate      */
14410Sstevel@tonic-gate     type = get_token(fp, token);
14420Sstevel@tonic-gate     while (type != EQUALS) {
14430Sstevel@tonic-gate       switch (type) {
14440Sstevel@tonic-gate         case DESCRIPTION:
14450Sstevel@tonic-gate           type = get_token(fp, token);
14460Sstevel@tonic-gate           if (type != QUOTESTRING) {
14470Sstevel@tonic-gate               print_error("Bad DESCRIPTION", token, type);
14480Sstevel@tonic-gate               free_node(np);
14490Sstevel@tonic-gate               return 0;
14500Sstevel@tonic-gate           }
14510Sstevel@tonic-gate #ifdef TEST
14520Sstevel@tonic-gate printf("Description== \"%.50s\"\n", quoted_string_buffer);
14530Sstevel@tonic-gate #endif
14540Sstevel@tonic-gate 	  np->description = quoted_string_buffer;
14550Sstevel@tonic-gate 	  quoted_string_buffer = (char *)malloc(MAXQUOTESTR);
14560Sstevel@tonic-gate 	  if (!quoted_string_buffer){
14570Sstevel@tonic-gate 	    fprintf(stderr, "malloc failed.  Exiting\n");
14580Sstevel@tonic-gate 	    exit(1);
14590Sstevel@tonic-gate 	  }
14600Sstevel@tonic-gate           break;
14610Sstevel@tonic-gate 
14620Sstevel@tonic-gate 	case REFERENCE:
14630Sstevel@tonic-gate 	  type = get_token(fp, token);
14640Sstevel@tonic-gate 	  if (type != QUOTESTRING) {
14650Sstevel@tonic-gate 	      print_error("Bad DESCRIPTION", token, type);
14660Sstevel@tonic-gate 	      free_node(np);
14670Sstevel@tonic-gate 	      return 0;
14680Sstevel@tonic-gate 	  }
14690Sstevel@tonic-gate 	  break;
14700Sstevel@tonic-gate /*
14710Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
14720Sstevel@tonic-gate */
14730Sstevel@tonic-gate        	case INDEX:
14740Sstevel@tonic-gate 		np->type = PSEUDO_TOKEN_ENTRY;
14750Sstevel@tonic-gate 
14760Sstevel@tonic-gate 		type = get_token(fp, token);
14770Sstevel@tonic-gate 		if(type != LEFTBRACKET)
14780Sstevel@tonic-gate 		{
14790Sstevel@tonic-gate 			print_error("{ expected in INDEX clause",token,type);
14800Sstevel@tonic-gate 			free_node(np);
14810Sstevel@tonic-gate 			return 0;
14820Sstevel@tonic-gate 		}
14830Sstevel@tonic-gate 		type = get_token(fp, token);
14840Sstevel@tonic-gate 		while(type != RIGHTBRACKET)
14850Sstevel@tonic-gate 		{
14860Sstevel@tonic-gate 			if(type != LABEL)
14870Sstevel@tonic-gate 			{
14880Sstevel@tonic-gate 				print_error("LABEL expected in INDEX clause",token,type);
14890Sstevel@tonic-gate 				free_node(np);
14900Sstevel@tonic-gate 				return 0;
14910Sstevel@tonic-gate 			}
14920Sstevel@tonic-gate 
14930Sstevel@tonic-gate 
14940Sstevel@tonic-gate 			(np->n_indexs)++;
14950Sstevel@tonic-gate 		    	if(np->indexs == NULL)
14960Sstevel@tonic-gate 			{
14970Sstevel@tonic-gate 				ip = np->indexs = (struct index_list *)
14980Sstevel@tonic-gate 					Malloc(sizeof(struct index_list));
14990Sstevel@tonic-gate 			}
15000Sstevel@tonic-gate 			else
15010Sstevel@tonic-gate 			{
15020Sstevel@tonic-gate 				ip->next = (struct index_list *)
15030Sstevel@tonic-gate 					Malloc(sizeof(struct enum_list));
15040Sstevel@tonic-gate 				ip = ip->next;
15050Sstevel@tonic-gate 			}
15060Sstevel@tonic-gate 			ip->next = 0;
15070Sstevel@tonic-gate 			ip->tp = NULL;
15080Sstevel@tonic-gate 
15090Sstevel@tonic-gate 			ip->label =
15100Sstevel@tonic-gate 				(char *)Malloc((unsigned)strlen(token) + 1);
15110Sstevel@tonic-gate 			strcpy(ip->label, token);
15120Sstevel@tonic-gate 
15130Sstevel@tonic-gate 			type = get_token(fp, token);
15140Sstevel@tonic-gate 
15150Sstevel@tonic-gate 			switch(type)
15160Sstevel@tonic-gate 			{
15170Sstevel@tonic-gate 				case COMMA:
15180Sstevel@tonic-gate 					type = get_token(fp, token);
15190Sstevel@tonic-gate 					break;
15200Sstevel@tonic-gate 
15210Sstevel@tonic-gate 				case RIGHTBRACKET:
15220Sstevel@tonic-gate 					break;
15230Sstevel@tonic-gate 
15240Sstevel@tonic-gate 				default:
15250Sstevel@tonic-gate 					print_error(", or } expected in INDEX clause",token,type);
15260Sstevel@tonic-gate 					free_node(np);
15270Sstevel@tonic-gate 					return 0;
15280Sstevel@tonic-gate 
15290Sstevel@tonic-gate 			}
15300Sstevel@tonic-gate 		}
15310Sstevel@tonic-gate 		break;
15320Sstevel@tonic-gate 
15330Sstevel@tonic-gate         case DEFVAL:
15340Sstevel@tonic-gate 	case AUGMENTS:
15350Sstevel@tonic-gate 	case NUM_ENTRIES:
15360Sstevel@tonic-gate           if (tossObjectIdentifier(fp) != PARSE_OBJID) {
15370Sstevel@tonic-gate               print_error("Bad Object Identifier", token, type);
15380Sstevel@tonic-gate               free_node(np);
15390Sstevel@tonic-gate               return 0;
15400Sstevel@tonic-gate           }
15410Sstevel@tonic-gate           break;
15420Sstevel@tonic-gate 
15430Sstevel@tonic-gate         default:
15440Sstevel@tonic-gate           print_error("Bad format of optional clauses", token,type);
15450Sstevel@tonic-gate           free_node(np);
15460Sstevel@tonic-gate           return 0;
15470Sstevel@tonic-gate 
15480Sstevel@tonic-gate       }
15490Sstevel@tonic-gate       type = get_token(fp, token);
15500Sstevel@tonic-gate     }
15510Sstevel@tonic-gate     if (type != EQUALS){
15520Sstevel@tonic-gate 	print_error("Bad format", token, type);
15530Sstevel@tonic-gate 	free_node(np);
15540Sstevel@tonic-gate 	return 0;
15550Sstevel@tonic-gate     }
15560Sstevel@tonic-gate     length = getoid(fp, oid, 32);
15570Sstevel@tonic-gate     if (length > 1 && length <= 32){
15580Sstevel@tonic-gate 	/* just take the last pair in the oid list */
15590Sstevel@tonic-gate 	if (oid[length - 2].label)
15600Sstevel@tonic-gate 	    strncpy(np->parent, oid[length - 2].label, MAXLABEL);
15610Sstevel@tonic-gate 	strcpy(np->label, name);
15620Sstevel@tonic-gate 	if (oid[length - 1].subid != -1)
15630Sstevel@tonic-gate 	    np->subid = oid[length - 1].subid;
15640Sstevel@tonic-gate 	else
15650Sstevel@tonic-gate 	    print_error("Warning: This entry is pretty silly", np->label, type);
15660Sstevel@tonic-gate     } else {
15670Sstevel@tonic-gate 	print_error("No end to oid", (char *)NULL, type);
15680Sstevel@tonic-gate 	free_node(np);
15690Sstevel@tonic-gate 	np = 0;
15700Sstevel@tonic-gate     }
15710Sstevel@tonic-gate     /* free oid array */
15720Sstevel@tonic-gate     for(count = 0; count < length; count++){
15730Sstevel@tonic-gate 	if (oid[count].label)
15740Sstevel@tonic-gate 	    free(oid[count].label);
15750Sstevel@tonic-gate 	oid[count].label = 0;
15760Sstevel@tonic-gate     }
15770Sstevel@tonic-gate     return np;
15780Sstevel@tonic-gate }
15790Sstevel@tonic-gate 
15800Sstevel@tonic-gate 
15810Sstevel@tonic-gate /*
15820Sstevel@tonic-gate  * Parses an OBJECT GROUP macro.
15830Sstevel@tonic-gate  * Returns 0 on error.
15840Sstevel@tonic-gate  */
15850Sstevel@tonic-gate static struct node *
parse_objectgroup(fp,name)15860Sstevel@tonic-gate parse_objectgroup(fp, name)
15870Sstevel@tonic-gate     register FILE *fp;
15880Sstevel@tonic-gate     char *name;
15890Sstevel@tonic-gate {
15900Sstevel@tonic-gate     register int type;
15910Sstevel@tonic-gate     char token[MAXTOKEN];
15920Sstevel@tonic-gate     int count, length;
15930Sstevel@tonic-gate     struct subid oid[32];
15940Sstevel@tonic-gate     register struct node *np;
15950Sstevel@tonic-gate 
15960Sstevel@tonic-gate     np = (struct node *)Malloc(sizeof(struct node));
15970Sstevel@tonic-gate     np->type = 0;
15980Sstevel@tonic-gate     np->next = 0;
15990Sstevel@tonic-gate     np->enums = 0;
16000Sstevel@tonic-gate     np->description = NULL;        /* default to an empty description */
16010Sstevel@tonic-gate 
16020Sstevel@tonic-gate /*
16030Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
16040Sstevel@tonic-gate */
16050Sstevel@tonic-gate 	np->access = 0;
16060Sstevel@tonic-gate 	np->n_indexs = 0;
16070Sstevel@tonic-gate 	np->indexs = 0;
16080Sstevel@tonic-gate 
16090Sstevel@tonic-gate     type = get_token(fp, token);
16100Sstevel@tonic-gate     while (type != EQUALS) {
16110Sstevel@tonic-gate       switch (type) {
16120Sstevel@tonic-gate         case DESCRIPTION:
16130Sstevel@tonic-gate           type = get_token(fp, token);
16140Sstevel@tonic-gate           if (type != QUOTESTRING) {
16150Sstevel@tonic-gate               print_error("Bad DESCRIPTION", token, type);
16160Sstevel@tonic-gate               free_node(np);
16170Sstevel@tonic-gate               return 0;
16180Sstevel@tonic-gate           }
16190Sstevel@tonic-gate #ifdef TEST
16200Sstevel@tonic-gate printf("Description== \"%.50s\"\n", quoted_string_buffer);
16210Sstevel@tonic-gate #endif
16220Sstevel@tonic-gate 	  np->description = quoted_string_buffer;
16230Sstevel@tonic-gate 	  quoted_string_buffer = (char *)malloc(MAXQUOTESTR);
16240Sstevel@tonic-gate 	  if (!quoted_string_buffer){
16250Sstevel@tonic-gate 	    fprintf(stderr, "malloc failed.  Exiting\n");
16260Sstevel@tonic-gate 	    exit(1);
16270Sstevel@tonic-gate 	  }
16280Sstevel@tonic-gate           break;
16290Sstevel@tonic-gate 
16300Sstevel@tonic-gate         default:
16310Sstevel@tonic-gate 	  /* NOTHING */
16320Sstevel@tonic-gate 	  break;
16330Sstevel@tonic-gate       }
16340Sstevel@tonic-gate       type = get_token(fp, token);
16350Sstevel@tonic-gate     }
16360Sstevel@tonic-gate     length = getoid(fp, oid, 32);
16370Sstevel@tonic-gate     if (length > 1 && length <= 32){
16380Sstevel@tonic-gate 	/* just take the last pair in the oid list */
16390Sstevel@tonic-gate 	if (oid[length - 2].label)
16400Sstevel@tonic-gate 	    strncpy(np->parent, oid[length - 2].label, MAXLABEL);
16410Sstevel@tonic-gate 	strcpy(np->label, name);
16420Sstevel@tonic-gate 	if (oid[length - 1].subid != -1)
16430Sstevel@tonic-gate 	    np->subid = oid[length - 1].subid;
16440Sstevel@tonic-gate 	else
16450Sstevel@tonic-gate 	    print_error("Warning: This entry is pretty silly", np->label, type);
16460Sstevel@tonic-gate     } else {
16470Sstevel@tonic-gate 	print_error("No end to oid", (char *)NULL, type);
16480Sstevel@tonic-gate 	free_node(np);
16490Sstevel@tonic-gate 	np = 0;
16500Sstevel@tonic-gate     }
16510Sstevel@tonic-gate     /* free oid array */
16520Sstevel@tonic-gate     for(count = 0; count < length; count++){
16530Sstevel@tonic-gate 	if (oid[count].label)
16540Sstevel@tonic-gate 	    free(oid[count].label);
16550Sstevel@tonic-gate 	oid[count].label = 0;
16560Sstevel@tonic-gate     }
16570Sstevel@tonic-gate     return np;
16580Sstevel@tonic-gate }
16590Sstevel@tonic-gate 
16600Sstevel@tonic-gate /*
16610Sstevel@tonic-gate  * Parses a NOTIFICATION-TYPE macro.
16620Sstevel@tonic-gate  * Returns 0 on error.
16630Sstevel@tonic-gate  */
16640Sstevel@tonic-gate static struct node *
parse_notificationDefinition(fp,name)16650Sstevel@tonic-gate parse_notificationDefinition(fp, name)
16660Sstevel@tonic-gate     register FILE *fp;
16670Sstevel@tonic-gate     char *name;
16680Sstevel@tonic-gate {
16690Sstevel@tonic-gate     register int type;
16700Sstevel@tonic-gate     char token[MAXTOKEN];
16710Sstevel@tonic-gate     int count, length;
16720Sstevel@tonic-gate     struct subid oid[32];
16730Sstevel@tonic-gate     register struct node *np;
16740Sstevel@tonic-gate 
16750Sstevel@tonic-gate     np = (struct node *)Malloc(sizeof(struct node));
16760Sstevel@tonic-gate     np->type = 0;
16770Sstevel@tonic-gate     np->next = 0;
16780Sstevel@tonic-gate     np->enums = 0;
16790Sstevel@tonic-gate     np->description = NULL;        /* default to an empty description */
16800Sstevel@tonic-gate /*
16810Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
16820Sstevel@tonic-gate */
16830Sstevel@tonic-gate 	np->access = 0;
16840Sstevel@tonic-gate 	np->n_indexs = 0;
16850Sstevel@tonic-gate 	np->indexs = 0;
16860Sstevel@tonic-gate 
16870Sstevel@tonic-gate     type = get_token(fp, token);
16880Sstevel@tonic-gate     while (type != EQUALS) {
16890Sstevel@tonic-gate       switch (type) {
16900Sstevel@tonic-gate         case DESCRIPTION:
16910Sstevel@tonic-gate           type = get_token(fp, token);
16920Sstevel@tonic-gate           if (type != QUOTESTRING) {
16930Sstevel@tonic-gate               print_error("Bad DESCRIPTION", token, type);
16940Sstevel@tonic-gate               free_node(np);
16950Sstevel@tonic-gate               return 0;
16960Sstevel@tonic-gate           }
16970Sstevel@tonic-gate #ifdef TEST
16980Sstevel@tonic-gate printf("Description== \"%.50s\"\n", quoted_string_buffer);
16990Sstevel@tonic-gate #endif
17000Sstevel@tonic-gate 	  np->description = quoted_string_buffer;
17010Sstevel@tonic-gate 	  quoted_string_buffer = (char *)malloc(MAXQUOTESTR);
17020Sstevel@tonic-gate 	  if (!quoted_string_buffer){
17030Sstevel@tonic-gate 	    fprintf(stderr, "malloc failed.  Exiting\n");
17040Sstevel@tonic-gate 	    exit(1);
17050Sstevel@tonic-gate 	  }
17060Sstevel@tonic-gate           break;
17070Sstevel@tonic-gate 
17080Sstevel@tonic-gate         default:
17090Sstevel@tonic-gate 	  /* NOTHING */
17100Sstevel@tonic-gate 	  break;
17110Sstevel@tonic-gate       }
17120Sstevel@tonic-gate       type = get_token(fp, token);
17130Sstevel@tonic-gate     }
17140Sstevel@tonic-gate     length = getoid(fp, oid, 32);
17150Sstevel@tonic-gate     if (length > 1 && length <= 32){
17160Sstevel@tonic-gate 	/* just take the last pair in the oid list */
17170Sstevel@tonic-gate 	if (oid[length - 2].label)
17180Sstevel@tonic-gate 	    strncpy(np->parent, oid[length - 2].label, MAXLABEL);
17190Sstevel@tonic-gate 	strcpy(np->label, name);
17200Sstevel@tonic-gate 	if (oid[length - 1].subid != -1)
17210Sstevel@tonic-gate 	    np->subid = oid[length - 1].subid;
17220Sstevel@tonic-gate 	else
17230Sstevel@tonic-gate 	    print_error("Warning: This entry is pretty silly", np->label, type);
17240Sstevel@tonic-gate     } else {
17250Sstevel@tonic-gate 	print_error("No end to oid", (char *)NULL, type);
17260Sstevel@tonic-gate 	free_node(np);
17270Sstevel@tonic-gate 	np = 0;
17280Sstevel@tonic-gate     }
17290Sstevel@tonic-gate     /* free oid array */
17300Sstevel@tonic-gate     for(count = 0; count < length; count++){
17310Sstevel@tonic-gate 	if (oid[count].label)
17320Sstevel@tonic-gate 	    free(oid[count].label);
17330Sstevel@tonic-gate 	oid[count].label = 0;
17340Sstevel@tonic-gate     }
17350Sstevel@tonic-gate     return np;
17360Sstevel@tonic-gate }
17370Sstevel@tonic-gate 
17380Sstevel@tonic-gate /*
17390Sstevel@tonic-gate  * Parses a compliance macro
17400Sstevel@tonic-gate  * Returns 0 on error.
17410Sstevel@tonic-gate  */
17420Sstevel@tonic-gate static struct node *
parse_compliance(fp,name)17430Sstevel@tonic-gate parse_compliance(fp, name)
17440Sstevel@tonic-gate     register FILE *fp;
17450Sstevel@tonic-gate     char *name;
17460Sstevel@tonic-gate {
17470Sstevel@tonic-gate     register int type;
17480Sstevel@tonic-gate     char token[MAXTOKEN];
17490Sstevel@tonic-gate     int count, length;
17500Sstevel@tonic-gate     struct subid oid[32];
17510Sstevel@tonic-gate     register struct node *np;
17520Sstevel@tonic-gate 
17530Sstevel@tonic-gate     np = (struct node *)Malloc(sizeof(struct node));
17540Sstevel@tonic-gate     np->type = 0;
17550Sstevel@tonic-gate     np->next = 0;
17560Sstevel@tonic-gate     np->enums = 0;
17570Sstevel@tonic-gate     np->description = NULL;        /* default to an empty description */
17580Sstevel@tonic-gate /*
17590Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
17600Sstevel@tonic-gate */
17610Sstevel@tonic-gate 	np->access = 0;
17620Sstevel@tonic-gate 	np->n_indexs = 0;
17630Sstevel@tonic-gate 	np->indexs = 0;
17640Sstevel@tonic-gate 
17650Sstevel@tonic-gate     type = get_token(fp, token);
17660Sstevel@tonic-gate     while (type != EQUALS) {
17670Sstevel@tonic-gate 	type = get_token(fp, token);
17680Sstevel@tonic-gate     }
17690Sstevel@tonic-gate     length = getoid(fp, oid, 32);
17700Sstevel@tonic-gate     if (length > 1 && length <= 32){
17710Sstevel@tonic-gate 	/* just take the last pair in the oid list */
17720Sstevel@tonic-gate 	if (oid[length - 2].label)
17730Sstevel@tonic-gate 	    strncpy(np->parent, oid[length - 2].label, MAXLABEL);
17740Sstevel@tonic-gate 	strcpy(np->label, name);
17750Sstevel@tonic-gate 	if (oid[length - 1].subid != -1)
17760Sstevel@tonic-gate 	    np->subid = oid[length - 1].subid;
17770Sstevel@tonic-gate 	else
17780Sstevel@tonic-gate 	    print_error("Warning: This entry is pretty silly", np->label, type);
17790Sstevel@tonic-gate     } else {
17800Sstevel@tonic-gate 	print_error("No end to oid", (char *)NULL, type);
17810Sstevel@tonic-gate 	free_node(np);
17820Sstevel@tonic-gate 	np = 0;
17830Sstevel@tonic-gate     }
17840Sstevel@tonic-gate     /* free oid array */
17850Sstevel@tonic-gate     for(count = 0; count < length; count++){
17860Sstevel@tonic-gate 	if (oid[count].label)
17870Sstevel@tonic-gate 	    free(oid[count].label);
17880Sstevel@tonic-gate 	oid[count].label = 0;
17890Sstevel@tonic-gate     }
17900Sstevel@tonic-gate     return np;
17910Sstevel@tonic-gate }
17920Sstevel@tonic-gate 
17930Sstevel@tonic-gate 
17940Sstevel@tonic-gate 
17950Sstevel@tonic-gate /*
17960Sstevel@tonic-gate  * Parses a module identity macro
17970Sstevel@tonic-gate  * Returns 0 on error.
17980Sstevel@tonic-gate  */
17990Sstevel@tonic-gate static struct node *
parse_moduleIdentity(fp,name)18000Sstevel@tonic-gate parse_moduleIdentity(fp, name)
18010Sstevel@tonic-gate     register FILE *fp;
18020Sstevel@tonic-gate     char *name;
18030Sstevel@tonic-gate {
18040Sstevel@tonic-gate     register int type;
18050Sstevel@tonic-gate     char token[MAXTOKEN];
18060Sstevel@tonic-gate     int count, length;
18070Sstevel@tonic-gate     struct subid oid[32];
18080Sstevel@tonic-gate     register struct node *np;
18090Sstevel@tonic-gate 
18100Sstevel@tonic-gate     np = (struct node *)Malloc(sizeof(struct node));
18110Sstevel@tonic-gate     np->type = 0;
18120Sstevel@tonic-gate     np->next = 0;
18130Sstevel@tonic-gate     np->enums = 0;
18140Sstevel@tonic-gate     np->description = NULL;        /* default to an empty description */
18150Sstevel@tonic-gate /*
18160Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
18170Sstevel@tonic-gate */
18180Sstevel@tonic-gate 	np->n_indexs = 0;
18190Sstevel@tonic-gate 	np->indexs = 0;
18200Sstevel@tonic-gate 	np->access = 0;
18210Sstevel@tonic-gate 
18220Sstevel@tonic-gate     type = get_token(fp, token);
18230Sstevel@tonic-gate     while (type != EQUALS) {
18240Sstevel@tonic-gate 	type = get_token(fp, token);
18250Sstevel@tonic-gate     }
18260Sstevel@tonic-gate     length = getoid(fp, oid, 32);
18270Sstevel@tonic-gate     if (length > 1 && length <= 32){
18280Sstevel@tonic-gate 	/* just take the last pair in the oid list */
18290Sstevel@tonic-gate 	if (oid[length - 2].label)
18300Sstevel@tonic-gate 	    strncpy(np->parent, oid[length - 2].label, MAXLABEL);
18310Sstevel@tonic-gate 	strcpy(np->label, name);
18320Sstevel@tonic-gate 	if (oid[length - 1].subid != -1)
18330Sstevel@tonic-gate 	    np->subid = oid[length - 1].subid;
18340Sstevel@tonic-gate 	else
18350Sstevel@tonic-gate 	    print_error("Warning: This entry is pretty silly", np->label, type);
18360Sstevel@tonic-gate     } else {
18370Sstevel@tonic-gate 	print_error("No end to oid", (char *)NULL, type);
18380Sstevel@tonic-gate 	free_node(np);
18390Sstevel@tonic-gate 	np = 0;
18400Sstevel@tonic-gate     }
18410Sstevel@tonic-gate     /* free oid array */
18420Sstevel@tonic-gate     for(count = 0; count < length; count++){
18430Sstevel@tonic-gate 	if (oid[count].label)
18440Sstevel@tonic-gate 	    free(oid[count].label);
18450Sstevel@tonic-gate 	oid[count].label = 0;
18460Sstevel@tonic-gate     }
18470Sstevel@tonic-gate     return np;
18480Sstevel@tonic-gate }
18490Sstevel@tonic-gate 
parse_mib_header(fp,name)18500Sstevel@tonic-gate int parse_mib_header(fp, name)
18510Sstevel@tonic-gate     register FILE *fp;
18520Sstevel@tonic-gate     char *name;
18530Sstevel@tonic-gate {
18540Sstevel@tonic-gate     int type = DEFINITIONS;
18550Sstevel@tonic-gate     char token[MAXTOKEN];
18560Sstevel@tonic-gate 
18570Sstevel@tonic-gate #ifdef TRACE_PROC
18580Sstevel@tonic-gate printf("parse_mib_header() invoked\n");
18590Sstevel@tonic-gate #endif
18600Sstevel@tonic-gate 
18610Sstevel@tonic-gate     /* This probably isn't good enough.  If there is no
18620Sstevel@tonic-gate        imports clause we can't go around waiting (forever) for a semicolon.
18630Sstevel@tonic-gate        We need to check for semi following an EXPORTS clause or an IMPORTS
18640Sstevel@tonic-gate        clause of both.  Look for BEGIN; in my initial MIBs to see those
18650Sstevel@tonic-gate        that I needed to hack to get to parse because they didn't have
18660Sstevel@tonic-gate        an IMPORTS or and EXPORTS clause.
18670Sstevel@tonic-gate        */
18680Sstevel@tonic-gate     while(type != SEMI){
18690Sstevel@tonic-gate 	type = get_token(fp, token);
18700Sstevel@tonic-gate     }
18710Sstevel@tonic-gate     return 1;
18720Sstevel@tonic-gate }
18730Sstevel@tonic-gate 
18740Sstevel@tonic-gate 
18750Sstevel@tonic-gate /*
18760Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
18770Sstevel@tonic-gate */
parse_init()18780Sstevel@tonic-gate void parse_init()
18790Sstevel@tonic-gate {
18800Sstevel@tonic-gate 	hash_init();
18810Sstevel@tonic-gate 	memset((void *) tclist, 0, 64 * sizeof(struct tc));
18820Sstevel@tonic-gate }
18830Sstevel@tonic-gate 
18840Sstevel@tonic-gate 
18850Sstevel@tonic-gate /*
18860Sstevel@tonic-gate  * Parses a mib file and returns a linked list of nodes found in the file.
18870Sstevel@tonic-gate  * Returns NULL on error.
18880Sstevel@tonic-gate  */
18890Sstevel@tonic-gate /*
18900Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
18910Sstevel@tonic-gate static struct node *
18920Sstevel@tonic-gate */
18930Sstevel@tonic-gate struct node *
parse(fp)18940Sstevel@tonic-gate parse(fp)
18950Sstevel@tonic-gate     FILE *fp;
18960Sstevel@tonic-gate {
18970Sstevel@tonic-gate     char token[MAXTOKEN];
18980Sstevel@tonic-gate     char name[MAXTOKEN];
18990Sstevel@tonic-gate     int	type = 1;
19000Sstevel@tonic-gate #define BETWEEN_MIBS  	      1
19010Sstevel@tonic-gate #define IN_MIB                2
19020Sstevel@tonic-gate     int state = BETWEEN_MIBS;
19030Sstevel@tonic-gate     struct node *np, *root = NULL;
19040Sstevel@tonic-gate 
19050Sstevel@tonic-gate #ifdef TRACE_PROC
19060Sstevel@tonic-gate printf("parse() invoked\n");
19070Sstevel@tonic-gate #endif
19080Sstevel@tonic-gate 
19090Sstevel@tonic-gate /*
19100Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
19110Sstevel@tonic-gate     hash_init();
19120Sstevel@tonic-gate */
19130Sstevel@tonic-gate     Line = 1;
19140Sstevel@tonic-gate 
19150Sstevel@tonic-gate     quoted_string_buffer = (char *)malloc(MAXQUOTESTR);  /* free this later */
19160Sstevel@tonic-gate     if (!quoted_string_buffer){
19170Sstevel@tonic-gate       fprintf(stderr, "malloc failed.  Exiting\n");
19180Sstevel@tonic-gate       exit(1);
19190Sstevel@tonic-gate     }
19200Sstevel@tonic-gate 
19210Sstevel@tonic-gate /*
19220Sstevel@tonic-gate -- Olivier Reisacher 95/2/14
19230Sstevel@tonic-gate     bzero(tclist, 64 * sizeof(struct tc));
19240Sstevel@tonic-gate */
19250Sstevel@tonic-gate 
19260Sstevel@tonic-gate     while(type != ENDOFFILE){
19270Sstevel@tonic-gate 	type = get_token(fp, token);
19280Sstevel@tonic-gate skipget:
19290Sstevel@tonic-gate 	if (type == END){
19300Sstevel@tonic-gate 	    if (state != IN_MIB){
19310Sstevel@tonic-gate 		print_error("Error, end before start of MIB.", (char *)NULL, type);
19320Sstevel@tonic-gate 		return NULL;
19330Sstevel@tonic-gate 	    }
19340Sstevel@tonic-gate 	    state = BETWEEN_MIBS;
19350Sstevel@tonic-gate 	    continue;
19360Sstevel@tonic-gate 	} else if (type != LABEL){
19370Sstevel@tonic-gate 	    if (type == ENDOFFILE){
19380Sstevel@tonic-gate 		return root;
19390Sstevel@tonic-gate 	    }
19400Sstevel@tonic-gate 	    print_error(token, "is a reserved word", type);
19410Sstevel@tonic-gate 	    return NULL;
19420Sstevel@tonic-gate 	}
19430Sstevel@tonic-gate 	strncpy(name, token, MAXTOKEN);
19440Sstevel@tonic-gate 	type = get_token(fp, token);
19450Sstevel@tonic-gate 	if (type == DEFINITIONS){
19460Sstevel@tonic-gate 	    if (state != BETWEEN_MIBS){
19470Sstevel@tonic-gate 		print_error("Error, nested MIBS.", (char *)NULL, type);
19480Sstevel@tonic-gate 		return NULL;
19490Sstevel@tonic-gate 	    }
19500Sstevel@tonic-gate 	    state = IN_MIB;
19510Sstevel@tonic-gate 	    if (!parse_mib_header(fp, name)){
19520Sstevel@tonic-gate 		print_error("Bad parse of module header", (char *)NULL, type);
19530Sstevel@tonic-gate 		return NULL;
19540Sstevel@tonic-gate 	    }
19550Sstevel@tonic-gate        } else if (type == OBJTYPE){
19560Sstevel@tonic-gate 	    if (root == NULL){
19570Sstevel@tonic-gate 		/* first link in chain */
19580Sstevel@tonic-gate 		np = root = parse_objecttype(fp, name);
19590Sstevel@tonic-gate 		if (np == NULL){
19600Sstevel@tonic-gate 		    print_error("Bad parse of object type", (char *)NULL,
19610Sstevel@tonic-gate 				type);
19620Sstevel@tonic-gate 		    return NULL;
19630Sstevel@tonic-gate 		}
19640Sstevel@tonic-gate 	    } else {
19650Sstevel@tonic-gate 		np->next = parse_objecttype(fp, name);
19660Sstevel@tonic-gate 		if (np->next == NULL){
19670Sstevel@tonic-gate 		    print_error("Bad parse of objecttype", (char *)NULL,
19680Sstevel@tonic-gate 				type);
19690Sstevel@tonic-gate 		    return NULL;
19700Sstevel@tonic-gate 		}
19710Sstevel@tonic-gate 	    }
19720Sstevel@tonic-gate 	    /* now find end of chain */
19730Sstevel@tonic-gate 	    while(np->next)
19740Sstevel@tonic-gate 		np = np->next;
19750Sstevel@tonic-gate 	} else if (type == OBJGROUP){
19760Sstevel@tonic-gate 	    if (root == NULL){
19770Sstevel@tonic-gate 		/* first link in chain */
19780Sstevel@tonic-gate 		np = root = parse_objectgroup(fp, name);
19790Sstevel@tonic-gate 		if (np == NULL){
19800Sstevel@tonic-gate 		    print_error("Bad parse of object group", (char *)NULL,
19810Sstevel@tonic-gate 				type);
19820Sstevel@tonic-gate 		    return NULL;
19830Sstevel@tonic-gate 		}
19840Sstevel@tonic-gate 	    } else {
19850Sstevel@tonic-gate 		np->next = parse_objectgroup(fp, name);
19860Sstevel@tonic-gate 		if (np->next == NULL){
19870Sstevel@tonic-gate 		    print_error("Bad parse of objectgroup", (char *)NULL,
19880Sstevel@tonic-gate 				type);
19890Sstevel@tonic-gate 		    return NULL;
19900Sstevel@tonic-gate 		}
19910Sstevel@tonic-gate 	    }
19920Sstevel@tonic-gate 	    /* now find end of chain */
19930Sstevel@tonic-gate 	    while(np->next)
19940Sstevel@tonic-gate 		np = np->next;
19950Sstevel@tonic-gate 	} else if (type == NOTIFTYPE){
19960Sstevel@tonic-gate 	    if (root == NULL){
19970Sstevel@tonic-gate 		/* first link in chain */
19980Sstevel@tonic-gate 		np = root = parse_notificationDefinition(fp, name);
19990Sstevel@tonic-gate 		if (np == NULL){
20000Sstevel@tonic-gate 		    print_error("Bad parse of notification definition",
20010Sstevel@tonic-gate 				(char *)NULL, type);
20020Sstevel@tonic-gate 		    return NULL;
20030Sstevel@tonic-gate 		}
20040Sstevel@tonic-gate 	    } else {
20050Sstevel@tonic-gate 		np->next = parse_notificationDefinition(fp, name);
20060Sstevel@tonic-gate 		if (np->next == NULL){
20070Sstevel@tonic-gate 		    print_error("Bad parse of notification definition",
20080Sstevel@tonic-gate 				(char *)NULL, type);
20090Sstevel@tonic-gate 		    return NULL;
20100Sstevel@tonic-gate 		}
20110Sstevel@tonic-gate 	    }
20120Sstevel@tonic-gate 	    /* now find end of chain */
20130Sstevel@tonic-gate 	    while(np->next)
20140Sstevel@tonic-gate 		np = np->next;
20150Sstevel@tonic-gate 	} else if (type == COMPLIANCE){
20160Sstevel@tonic-gate 	    if (root == NULL){
20170Sstevel@tonic-gate 		/* first link in chain */
20180Sstevel@tonic-gate 		np = root = parse_compliance(fp, name);
20190Sstevel@tonic-gate 		if (np == NULL){
20200Sstevel@tonic-gate 		    print_error("Bad parse of module compliance", (char *)NULL,
20210Sstevel@tonic-gate 				type);
20220Sstevel@tonic-gate 		    return NULL;
20230Sstevel@tonic-gate 		}
20240Sstevel@tonic-gate 	    } else {
20250Sstevel@tonic-gate 		np->next = parse_compliance(fp, name);
20260Sstevel@tonic-gate 		if (np->next == NULL){
20270Sstevel@tonic-gate 		    print_error("Bad parse of module compliance", (char *)NULL,
20280Sstevel@tonic-gate 				type);
20290Sstevel@tonic-gate 		    return NULL;
20300Sstevel@tonic-gate 		}
20310Sstevel@tonic-gate 	    }
20320Sstevel@tonic-gate 	    /* now find end of chain */
20330Sstevel@tonic-gate 	    while(np->next)
20340Sstevel@tonic-gate 		np = np->next;
20350Sstevel@tonic-gate 	} else if (type == MODULEIDENTITY){
20360Sstevel@tonic-gate 	    if (root == NULL){
20370Sstevel@tonic-gate 		/* first link in chain */
20380Sstevel@tonic-gate 		np = root = parse_moduleIdentity(fp, name);
20390Sstevel@tonic-gate 		if (np == NULL){
20400Sstevel@tonic-gate 		    print_error("Bad parse of module identity", (char *)NULL,
20410Sstevel@tonic-gate 				type);
20420Sstevel@tonic-gate 		    return NULL;
20430Sstevel@tonic-gate 		}
20440Sstevel@tonic-gate 	    } else {
20450Sstevel@tonic-gate 		np->next = parse_moduleIdentity(fp, name);
20460Sstevel@tonic-gate 		if (np->next == NULL){
20470Sstevel@tonic-gate 		    print_error("Bad parse of module identity", (char *)NULL,
20480Sstevel@tonic-gate 				type);
20490Sstevel@tonic-gate 		    return NULL;
20500Sstevel@tonic-gate 		}
20510Sstevel@tonic-gate 	    }
20520Sstevel@tonic-gate 	    /* now find end of chain */
20530Sstevel@tonic-gate 	    while(np->next)
20540Sstevel@tonic-gate 		np = np->next;
20550Sstevel@tonic-gate 	} else if (type == PARSE_OBJID){
20560Sstevel@tonic-gate 	    if (root == NULL){
20570Sstevel@tonic-gate 		/* first link in chain */
20580Sstevel@tonic-gate 		np = root = parse_objectid(fp, name);
20590Sstevel@tonic-gate 		if (np == NULL){
20600Sstevel@tonic-gate 		    print_error("Bad parse of object id", (char *)NULL, type);
20610Sstevel@tonic-gate 		    return NULL;
20620Sstevel@tonic-gate 		}
20630Sstevel@tonic-gate 	    } else {
20640Sstevel@tonic-gate 		np->next = parse_objectid(fp, name);
20650Sstevel@tonic-gate 		if (np->next == NULL){
20660Sstevel@tonic-gate 		    print_error("Bad parse of object type", (char *)NULL,
20670Sstevel@tonic-gate 				type);
20680Sstevel@tonic-gate 		    return NULL;
20690Sstevel@tonic-gate 		}
20700Sstevel@tonic-gate 	    }
20710Sstevel@tonic-gate 	    /* now find end of chain */
20720Sstevel@tonic-gate 	    while(np->next)
20730Sstevel@tonic-gate 		np = np->next;
20740Sstevel@tonic-gate 	} else if (type == EQUALS){
20750Sstevel@tonic-gate 	    if (!parse_asntype(fp, name, &type, token)){
20760Sstevel@tonic-gate 		print_error("Bad parse of ASN type definition.", (char*)NULL, EQUALS);
20770Sstevel@tonic-gate 		return NULL;
20780Sstevel@tonic-gate 	    }
20790Sstevel@tonic-gate 	    goto skipget;
20800Sstevel@tonic-gate 	} else if (type == TRAPTYPE){ /* Jerry Yeung 6-6-96 */
20810Sstevel@tonic-gate 	    if(!parse_traptype(fp,name)){
20820Sstevel@tonic-gate 		 print_error("Bad parse of TRAP type",(char*)NULL,type);
20830Sstevel@tonic-gate 		 return NULL;
20840Sstevel@tonic-gate 	    }
20850Sstevel@tonic-gate 	} else if (type == ENDOFFILE){
20860Sstevel@tonic-gate 	    break;
20870Sstevel@tonic-gate 	} else {
20880Sstevel@tonic-gate 	    print_error("Bad operator", (char *)NULL, type);
20890Sstevel@tonic-gate 	    return NULL;
20900Sstevel@tonic-gate 	}
20910Sstevel@tonic-gate     }
20920Sstevel@tonic-gate #ifdef TEST
20930Sstevel@tonic-gate {
20940Sstevel@tonic-gate     struct enum_list *ep;
20950Sstevel@tonic-gate 
20960Sstevel@tonic-gate     for(np = root; np; np = np->next){
20970Sstevel@tonic-gate 	printf("%s ::= { %s %d } (%d)\n", np->label, np->parent, np->subid,
20980Sstevel@tonic-gate 		np->type);
20990Sstevel@tonic-gate 	if (np->enums){
21000Sstevel@tonic-gate 	    printf("Enums: \n");
21010Sstevel@tonic-gate 	    for(ep = np->enums; ep; ep = ep->next){
21020Sstevel@tonic-gate 		printf("%s(%d)\n", ep->label, ep->value);
21030Sstevel@tonic-gate 	    }
21040Sstevel@tonic-gate 	}
21050Sstevel@tonic-gate     }
21060Sstevel@tonic-gate }
21070Sstevel@tonic-gate #endif /* TEST */
21080Sstevel@tonic-gate     return root;
21090Sstevel@tonic-gate }
21100Sstevel@tonic-gate 
21110Sstevel@tonic-gate /*
21120Sstevel@tonic-gate  * Parses a token from the file.  The type of the token parsed is returned,
21130Sstevel@tonic-gate  * and the text is placed in the string pointed to by token.
21140Sstevel@tonic-gate  */
21150Sstevel@tonic-gate static int
get_token(fp,token)21160Sstevel@tonic-gate get_token(fp, token)
21170Sstevel@tonic-gate     register FILE *fp;
21180Sstevel@tonic-gate     register char *token;
21190Sstevel@tonic-gate {
21200Sstevel@tonic-gate     static char last = ' ';
21210Sstevel@tonic-gate     register int ch;
21220Sstevel@tonic-gate     register char *cp = token;
21230Sstevel@tonic-gate     register int hash = 0;
21240Sstevel@tonic-gate     register struct tok *tp;
21250Sstevel@tonic-gate 
21260Sstevel@tonic-gate     *cp = 0;
21270Sstevel@tonic-gate     ch = last;
21280Sstevel@tonic-gate     /* skip all white space */
21290Sstevel@tonic-gate     while(isspace(ch) && ch != -1){
21300Sstevel@tonic-gate 	ch = getc(fp);
21310Sstevel@tonic-gate 	if (ch == '\n')
21320Sstevel@tonic-gate 	    Line++;
21330Sstevel@tonic-gate     }
21340Sstevel@tonic-gate     if (ch == -1) {
21350Sstevel@tonic-gate #ifdef TRACE_GET_TOKEN
21360Sstevel@tonic-gate print_error("TRACE", token, ENDOFFILE);
21370Sstevel@tonic-gate #endif
21380Sstevel@tonic-gate 	return ENDOFFILE;
21390Sstevel@tonic-gate     } else if (ch == '"') {
21400Sstevel@tonic-gate 	return parseQuoteString(fp, token);
21410Sstevel@tonic-gate     }
21420Sstevel@tonic-gate 
21430Sstevel@tonic-gate     /*
21440Sstevel@tonic-gate      * Accumulate characters until end of token is found.  Then attempt to
21450Sstevel@tonic-gate      * match this token as a reserved word.  If a match is found, return the
21460Sstevel@tonic-gate      * type.  Else it is a label.
21470Sstevel@tonic-gate      */
21480Sstevel@tonic-gate     do {
21490Sstevel@tonic-gate 	if (ch == '\n')
21500Sstevel@tonic-gate 	    Line++;
21510Sstevel@tonic-gate 	if (isspace(ch) || ch == '(' || ch == ')' || ch == '{' || ch == '}' ||
21520Sstevel@tonic-gate 	    ch == ',' || ch == ';'){
21530Sstevel@tonic-gate 	    if (!isspace(ch) && *token == 0){
21540Sstevel@tonic-gate 		hash += ch;
21550Sstevel@tonic-gate 		*cp++ = ch;
21560Sstevel@tonic-gate 		last = ' ';
21570Sstevel@tonic-gate 	    } else {
21580Sstevel@tonic-gate 		last = ch;
21590Sstevel@tonic-gate 	    }
21600Sstevel@tonic-gate 	    *cp = '\0';
21610Sstevel@tonic-gate 
21620Sstevel@tonic-gate 	    for (tp = buckets[BUCKET(hash)]; tp; tp = tp->next) {
21630Sstevel@tonic-gate 		if ((tp->hash == hash) && (strcmp(tp->name, token) == 0))
21640Sstevel@tonic-gate 			break;
21650Sstevel@tonic-gate 	    }
21660Sstevel@tonic-gate 	    if (tp){
21670Sstevel@tonic-gate 		if (tp->token == CONTINUE)
21680Sstevel@tonic-gate 		    continue;
21690Sstevel@tonic-gate #ifdef TRACE_GET_TOKEN
21700Sstevel@tonic-gate print_error("TRACE", token, tp->token);
21710Sstevel@tonic-gate #endif
21720Sstevel@tonic-gate 		return (tp->token);
21730Sstevel@tonic-gate 	    }
21740Sstevel@tonic-gate 
21750Sstevel@tonic-gate 	    if (token[0] == '-' && token[1] == '-'){
21760Sstevel@tonic-gate 		/* strip comment */
21770Sstevel@tonic-gate 		if (ch != '\n'){
21780Sstevel@tonic-gate 		    while ((ch = getc(fp)) != -1)
21790Sstevel@tonic-gate 			if (ch == '\n'){
21800Sstevel@tonic-gate 			    Line++;
21810Sstevel@tonic-gate 			    break;
21820Sstevel@tonic-gate 			}
21830Sstevel@tonic-gate 		}
21840Sstevel@tonic-gate 		if (ch == -1)
21850Sstevel@tonic-gate {
21860Sstevel@tonic-gate #ifdef TRACE_GET_TOKEN
21870Sstevel@tonic-gate print_error("TRACE", token, ENDOFFILE);
21880Sstevel@tonic-gate #endif
21890Sstevel@tonic-gate 		    return ENDOFFILE;
21900Sstevel@tonic-gate }
21910Sstevel@tonic-gate 		last = ch;
21920Sstevel@tonic-gate 		return get_token(fp, token);
21930Sstevel@tonic-gate 	    }
21940Sstevel@tonic-gate 	    for(cp = token; *cp; cp++)
21950Sstevel@tonic-gate 		if (!isdigit(*cp))
21960Sstevel@tonic-gate {
21970Sstevel@tonic-gate #ifdef TRACE_GET_TOKEN
21980Sstevel@tonic-gate print_error("TRACE", token, LABEL);
21990Sstevel@tonic-gate #endif
22000Sstevel@tonic-gate 		    return LABEL;
22010Sstevel@tonic-gate }
22020Sstevel@tonic-gate #ifdef TRACE_GET_TOKEN
22030Sstevel@tonic-gate print_error("TRACE", token, NUMBER);
22040Sstevel@tonic-gate #endif
22050Sstevel@tonic-gate             number_value = atoi(token);   /* octet string size */
22060Sstevel@tonic-gate 	    return NUMBER;
22070Sstevel@tonic-gate 	} else {
22080Sstevel@tonic-gate 	    hash += ch;
22090Sstevel@tonic-gate 	    *cp++ = ch;
22100Sstevel@tonic-gate 	    if (ch == '\n')
22110Sstevel@tonic-gate 		Line++;
22120Sstevel@tonic-gate 	}
22130Sstevel@tonic-gate 
22140Sstevel@tonic-gate     } while ((ch = getc(fp)) != -1);
22150Sstevel@tonic-gate #ifdef TRACE_GET_TOKEN
22160Sstevel@tonic-gate print_error("TRACE", token, ENDOFFILE);
22170Sstevel@tonic-gate #endif
22180Sstevel@tonic-gate     return ENDOFFILE;
22190Sstevel@tonic-gate }
22200Sstevel@tonic-gate 
22210Sstevel@tonic-gate struct tree *
read_mib(filename)22220Sstevel@tonic-gate read_mib(filename)
22230Sstevel@tonic-gate     char *filename;
22240Sstevel@tonic-gate {
22250Sstevel@tonic-gate     FILE *fp;
22260Sstevel@tonic-gate     struct node *nodes;
22270Sstevel@tonic-gate     struct tree *tree;
22280Sstevel@tonic-gate 
22290Sstevel@tonic-gate     fp = fopen(filename, "r");
22300Sstevel@tonic-gate     if (fp == NULL)
22310Sstevel@tonic-gate 	return NULL;
22320Sstevel@tonic-gate     nodes = parse(fp);
22330Sstevel@tonic-gate     if (!nodes){
22340Sstevel@tonic-gate 	fprintf(stderr, "Mib table is bad.  Exiting\n");
22350Sstevel@tonic-gate 	exit(1);
22360Sstevel@tonic-gate     }
22370Sstevel@tonic-gate     tree = build_tree(nodes);
22380Sstevel@tonic-gate     fclose(fp);
22390Sstevel@tonic-gate     return tree;
22400Sstevel@tonic-gate }
22410Sstevel@tonic-gate 
22420Sstevel@tonic-gate 
22430Sstevel@tonic-gate #ifdef TEST
main(argc,argv)22440Sstevel@tonic-gate main(argc, argv)
22450Sstevel@tonic-gate     int argc;
22460Sstevel@tonic-gate     char *argv[];
22470Sstevel@tonic-gate {
22480Sstevel@tonic-gate     FILE *fp;
22490Sstevel@tonic-gate     struct node *nodes;
22500Sstevel@tonic-gate     struct tree *tp;
22510Sstevel@tonic-gate 
22520Sstevel@tonic-gate     fp = fopen("mib.txt", "r");
22530Sstevel@tonic-gate     if (fp == NULL){
22540Sstevel@tonic-gate 	fprintf(stderr, "open failed\n");
22550Sstevel@tonic-gate 	return 1;
22560Sstevel@tonic-gate     }
22570Sstevel@tonic-gate     nodes = parse(fp);
22580Sstevel@tonic-gate     if (!nodes){
22590Sstevel@tonic-gate       fprintf(stderr, "Mib table is bad. \n");
22600Sstevel@tonic-gate       return (1);
22610Sstevel@tonic-gate     }
22620Sstevel@tonic-gate     tp = build_tree(nodes);
22630Sstevel@tonic-gate     print_subtree(tp, 0);
22640Sstevel@tonic-gate     fclose(fp);
22650Sstevel@tonic-gate }
22660Sstevel@tonic-gate 
22670Sstevel@tonic-gate #endif /* TEST */
22680Sstevel@tonic-gate 
22690Sstevel@tonic-gate static int
parseQuoteString(fp,token)22700Sstevel@tonic-gate parseQuoteString(fp, token)
22710Sstevel@tonic-gate     register FILE *fp;
22720Sstevel@tonic-gate     register char *token;
22730Sstevel@tonic-gate {
22740Sstevel@tonic-gate     register int ch;
22750Sstevel@tonic-gate     register char *ptr, *ptr1;
22760Sstevel@tonic-gate     register int len = 0;
22770Sstevel@tonic-gate 
22780Sstevel@tonic-gate     ch = ' ';
22790Sstevel@tonic-gate     *token = '\0';                      /* make the token empty */
22800Sstevel@tonic-gate 
22810Sstevel@tonic-gate     ptr = quoted_string_buffer;
22820Sstevel@tonic-gate     if (ptr)
22830Sstevel@tonic-gate 	*ptr = 0;
22840Sstevel@tonic-gate 
22850Sstevel@tonic-gate 
22860Sstevel@tonic-gate     while(ch != -1) {
22870Sstevel@tonic-gate         ch = getc(fp);
22880Sstevel@tonic-gate 	if (ch != '"') {
22890Sstevel@tonic-gate 		if (ptr) {
22900Sstevel@tonic-gate 			* ptr ++ = ch;
22910Sstevel@tonic-gate 			len ++;
22920Sstevel@tonic-gate 			if (len % MAXQUOTESTR == 0) {
22930Sstevel@tonic-gate 				ptr1 = (char *) malloc (len + MAXQUOTESTR);
22940Sstevel@tonic-gate 				if (!ptr1){
22950Sstevel@tonic-gate 				  fprintf(stderr, "malloc failed.  Exiting\n");
22960Sstevel@tonic-gate 				  exit(1);
22970Sstevel@tonic-gate 				}
22980Sstevel@tonic-gate 				memcpy (ptr1, quoted_string_buffer, len);
22990Sstevel@tonic-gate 				free (quoted_string_buffer);
23000Sstevel@tonic-gate 				quoted_string_buffer = ptr1;
23010Sstevel@tonic-gate 				ptr = ptr1 + len;
23020Sstevel@tonic-gate 			}
23030Sstevel@tonic-gate 		}
23040Sstevel@tonic-gate 	} else {
23050Sstevel@tonic-gate 		if (ptr)
23060Sstevel@tonic-gate 			* ptr = 0;
23070Sstevel@tonic-gate 	}
23080Sstevel@tonic-gate 	if (ch == '\n')
23090Sstevel@tonic-gate 	    Line++;
23100Sstevel@tonic-gate 	else if (ch == '"') {
23110Sstevel@tonic-gate #ifdef TRACE_GET_TOKEN
23120Sstevel@tonic-gate print_error("TRACE", token, QUOTESTRING);
23130Sstevel@tonic-gate #endif
23140Sstevel@tonic-gate             return QUOTESTRING;
23150Sstevel@tonic-gate         }
23160Sstevel@tonic-gate 
23170Sstevel@tonic-gate     }
23180Sstevel@tonic-gate 
23190Sstevel@tonic-gate #ifdef TRACE_GET_TOKEN
23200Sstevel@tonic-gate print_error("TRACE", token, NULL);
23210Sstevel@tonic-gate #endif
23220Sstevel@tonic-gate     return NULL;
23230Sstevel@tonic-gate }
23240Sstevel@tonic-gate 
23250Sstevel@tonic-gate /*
23260Sstevel@tonic-gate  * This routine parses a string like  { blah blah blah } and returns PARSE_OBJID if
23270Sstevel@tonic-gate  * it is well formed, and NULL if not.
23280Sstevel@tonic-gate  */
23290Sstevel@tonic-gate static int
tossObjectIdentifier(fp)23300Sstevel@tonic-gate tossObjectIdentifier(fp)
23310Sstevel@tonic-gate     register FILE *fp;
23320Sstevel@tonic-gate {
23330Sstevel@tonic-gate     register int ch;
23340Sstevel@tonic-gate 
23350Sstevel@tonic-gate         ch = getc(fp);
23360Sstevel@tonic-gate /*    ch = last; = ' '? */
23370Sstevel@tonic-gate     /* skip all white space */
23380Sstevel@tonic-gate     while(isspace(ch) && ch != -1){
23390Sstevel@tonic-gate         ch = getc(fp);
23400Sstevel@tonic-gate         if (ch == '\n')
23410Sstevel@tonic-gate             Line++;
23420Sstevel@tonic-gate     }
23430Sstevel@tonic-gate     if (ch != '{')
23440Sstevel@tonic-gate         return NULL;
23450Sstevel@tonic-gate 
23460Sstevel@tonic-gate     while(ch != -1) {
23470Sstevel@tonic-gate         ch = getc(fp);
23480Sstevel@tonic-gate 
23490Sstevel@tonic-gate         if (ch == '\n')
23500Sstevel@tonic-gate             Line++;
23510Sstevel@tonic-gate         else if (ch == '}')
23520Sstevel@tonic-gate             return PARSE_OBJID;
23530Sstevel@tonic-gate     }
23540Sstevel@tonic-gate 
23550Sstevel@tonic-gate /*    last = ch;*/
23560Sstevel@tonic-gate     return NULL;
23570Sstevel@tonic-gate }
2358