1 /*
2  * data.c --
3  *
4  *      Operations on the main data structures.
5  *
6  * Copyright (c) 1999-2002 Frank Strauss, Technical University of Braunschweig.
7  *
8  * See the file "COPYING" for information on usage and redistribution
9  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10  *
11  * @(#) $Id: data.c 7822 2008-03-01 13:22:42Z schoenw $
12  */
13 
14 #include <config.h>
15 
16 #include <string.h>
17 #include <errno.h>
18 #include <ctype.h>
19 #include <sys/types.h>
20 #if !defined(_MSC_VER) && !defined(__MINGW32__)
21 #include <sys/wait.h>
22 #endif
23 #ifdef HAVE_UNISTD_H
24 #include <unistd.h>
25 #endif
26 #ifdef HAVE_WIN_H
27 #include "win.h"
28 #endif
29 
30 #include "error.h"
31 #include "util.h"
32 #include "data.h"
33 #include "smi.h"
34 
35 #ifdef HAVE_DMALLOC_H
36 #include <dmalloc.h>
37 #endif
38 
39 
40 
41 #ifdef BACKEND_SMI
42 #include "scanner-smi.h"
43 extern int smiparse();
44 #endif
45 
46 #ifdef BACKEND_SMING
47 #include "scanner-sming.h"
48 extern int smingparse();
49 #endif
50 
51 #define stringKind(kind) ( \
52 	(kind == KIND_ANY)                 ? "ANY" : \
53 	(kind == KIND_MODULE)              ? "MODULE" : \
54 	(kind == KIND_MACRO)               ? "MACRO" : \
55 	(kind == KIND_TYPE)                ? "TYPE" : \
56 	(kind == KIND_OBJECT)              ? "OBJECT" : \
57 	(kind == KIND_IMPORT)              ? "IMPORT" : \
58 					     "unknown" )
59 
60 
61 int		smiDepth = 0;
62 static Handle   *firstHandlePtr = NULL;
63 static Handle   *lastHandlePtr  = NULL;
64 
65 
66 /*
67  *----------------------------------------------------------------------
68  *
69  * addHandle --
70  *
71  *      Adds a libsmi handle with a given name.
72  *
73  * Results:
74  *      0 on success or -1 on an error.
75  *
76  * Side effects:
77  *      None.
78  *
79  *----------------------------------------------------------------------
80  */
81 
addHandle(const char * name)82 Handle *addHandle(const char *name)
83 {
84     Handle *handlePtr;
85 
86     handlePtr = (Handle *) smiMalloc(sizeof(Handle));
87 
88     handlePtr->name    = smiStrdup(name);
89 
90     handlePtr->nextPtr = NULL;
91     handlePtr->prevPtr = lastHandlePtr;
92     if (!firstHandlePtr) firstHandlePtr = handlePtr;
93     if (lastHandlePtr) lastHandlePtr->nextPtr = handlePtr;
94     lastHandlePtr = handlePtr;
95 
96     return (handlePtr);
97 }
98 
99 
100 
101 /*
102  *----------------------------------------------------------------------
103  *
104  * removeHandle --
105  *
106  *      Removes a given libsmi handle.
107  *
108  * Results:
109  *      None.
110  *
111  * Side effects:
112  *      None.
113  *
114  *----------------------------------------------------------------------
115  */
116 
removeHandle(Handle * handlePtr)117 void removeHandle(Handle *handlePtr)
118 {
119     if (handlePtr->prevPtr) {
120 	handlePtr->prevPtr->nextPtr = handlePtr->nextPtr;
121     } else {
122 	firstHandlePtr = handlePtr->nextPtr;
123     }
124     if (handlePtr->nextPtr) {
125 	handlePtr->nextPtr->prevPtr = handlePtr->prevPtr;
126     } else {
127 	lastHandlePtr = handlePtr->prevPtr;
128     }
129 
130     smiFree(handlePtr->name);
131     smiFree(handlePtr);
132 }
133 
134 
135 
136 /*
137  *----------------------------------------------------------------------
138  *
139  * findHandleByName --
140  *
141  *      Lookup an libsmi handle by its name.
142  *
143  * Results:
144  *      A pointer to the Handle structure or
145  *	NULL if it is not found.
146  *
147  * Side effects:
148  *      None.
149  *
150  *----------------------------------------------------------------------
151  */
152 
findHandleByName(const char * name)153 Handle *findHandleByName(const char *name)
154 {
155     Handle *handlePtr;
156 
157     if (!name)
158 	return NULL;
159 
160     for (handlePtr = firstHandlePtr; handlePtr;
161 	 handlePtr = handlePtr->nextPtr) {
162 	if (!strcmp(handlePtr->name, name)) {
163 		return (handlePtr);
164 	}
165     }
166 
167     return NULL;
168 
169 }
170 
171 
172 
173 /*
174  *----------------------------------------------------------------------
175  *
176  * addView --
177  *
178  *      Add a module to the `view' (the list of modules, seen by the user).
179  *
180  * Results:
181  *      A pointer to the new View structure or
182  *	NULL if terminated due to an error.
183  *
184  * Side effects:
185  *      None.
186  *
187  *----------------------------------------------------------------------
188  */
189 
addView(const char * modulename)190 View *addView(const char *modulename)
191 {
192     View	      *viewPtr;
193 
194     viewPtr = (View *) smiMalloc(sizeof(View));
195 
196     viewPtr->name				= smiStrdup(modulename);
197     viewPtr->nextPtr				= NULL;
198     viewPtr->prevPtr				= smiHandle->lastViewPtr;
199     if (!smiHandle->firstViewPtr) smiHandle->firstViewPtr		= viewPtr;
200     if (smiHandle->lastViewPtr) smiHandle->lastViewPtr->nextPtr	= viewPtr;
201     smiHandle->lastViewPtr	     				= viewPtr;
202 
203     return (viewPtr);
204 }
205 
206 
207 
208 /*
209  *----------------------------------------------------------------------
210  *
211  * isInView --
212  *
213  *      Check, whether a given module is in the current view.
214  *
215  * Results:
216  *      != 0 if in view, 0 otherwise.
217  *
218  * Side effects:
219  *      None.
220  *
221  *----------------------------------------------------------------------
222  */
223 
isInView(const char * modulename)224 int isInView(const char *modulename)
225 {
226     View	      *viewPtr;
227 
228 #if 0
229     if (smiHandle->flags & SMI_FLAG_VIEWALL) {
230 	return 1;
231     }
232 #endif
233 
234     for (viewPtr = smiHandle->firstViewPtr; viewPtr; viewPtr = viewPtr->nextPtr) {
235 	if (!strcmp(modulename, viewPtr->name)) {
236 	    return 1;
237 	}
238     }
239     return 0;
240 }
241 
242 
243 /*
244  *----------------------------------------------------------------------
245  *
246  * addModule --
247  *
248  *      Create a new MIB module.
249  *
250  * Results:
251  *      A pointer to the new Module structure or
252  *	NULL if terminated due to an error.
253  *
254  * Side effects:
255  *      None.
256  *
257  *----------------------------------------------------------------------
258  */
259 
addModule(char * modulename,char * path,ModuleFlags flags,Parser * parserPtr)260 Module *addModule(char *modulename, char *path, ModuleFlags flags,
261 		  Parser *parserPtr)
262 {
263     Module	      *modulePtr;
264 
265     modulePtr = (Module *) smiMalloc(sizeof(Module));
266 
267     modulePtr->export.name			= modulename;
268     modulePtr->export.path			= path;
269     modulePtr->export.language			= SMI_LANGUAGE_UNKNOWN;
270     modulePtr->export.organization		= NULL;
271     modulePtr->export.contactinfo		= NULL;
272     modulePtr->export.description		= NULL;
273     modulePtr->export.reference			= NULL;
274     modulePtr->export.conformance               = 0;
275 
276     modulePtr->lastUpdated			= 0;
277     modulePtr->flags				= flags;
278     modulePtr->objectPtr			= NULL;
279 
280     modulePtr->prefixNodePtr                    = NULL;
281     modulePtr->firstObjectPtr			= NULL;
282     modulePtr->lastObjectPtr			= NULL;
283     modulePtr->firstTypePtr			= NULL;
284     modulePtr->lastTypePtr			= NULL;
285     modulePtr->firstMacroPtr			= NULL;
286     modulePtr->lastMacroPtr			= NULL;
287     modulePtr->firstImportPtr			= NULL;
288     modulePtr->lastImportPtr			= NULL;
289     modulePtr->firstRevisionPtr			= NULL;
290     modulePtr->lastRevisionPtr			= NULL;
291 
292     modulePtr->numImportedIdentifiers		= 0;
293     modulePtr->numStatements			= 0;
294     modulePtr->numModuleIdentities		= 0;
295 
296     modulePtr->nextPtr				= NULL;
297     modulePtr->prevPtr				= smiHandle->lastModulePtr;
298     if (!smiHandle->firstModulePtr) smiHandle->firstModulePtr		= modulePtr;
299     if (smiHandle->lastModulePtr) smiHandle->lastModulePtr->nextPtr	= modulePtr;
300     smiHandle->lastModulePtr				= modulePtr;
301 
302     return (modulePtr);
303 }
304 
305 
306 
307 /*
308  *----------------------------------------------------------------------
309  *
310  * setModuleIdentityObject --
311  *
312  *      Set the objectPtr of a given Module to the OBJECT-IDENTITY object.
313  *
314  * Results:
315  *	None.
316  *
317  * Side effects:
318  *      None.
319  *
320  *----------------------------------------------------------------------
321  */
322 
setModuleIdentityObject(Module * modulePtr,Object * objectPtr)323 void setModuleIdentityObject(Module *modulePtr, Object *objectPtr)
324 {
325     modulePtr->objectPtr = objectPtr;
326 }
327 
328 
329 
330 /*
331  *----------------------------------------------------------------------
332  *
333  * setModuleLastUpdated --
334  *
335  *      Set the lastUpdated time_t value of a given Module.
336  *
337  * Results:
338  *	None.
339  *
340  * Side effects:
341  *      None.
342  *
343  *----------------------------------------------------------------------
344  */
345 
setModuleLastUpdated(Module * modulePtr,time_t lastUpdated)346 void setModuleLastUpdated(Module *modulePtr, time_t lastUpdated)
347 {
348     modulePtr->lastUpdated = lastUpdated;
349 }
350 
351 
352 
353 /*
354  *----------------------------------------------------------------------
355  *
356  * setModuleOrganization --
357  *
358  *      Set the organization string of a given Module.
359  *
360  * Results:
361  *	None.
362  *
363  * Side effects:
364  *      None.
365  *
366  *----------------------------------------------------------------------
367  */
368 
setModuleOrganization(Module * modulePtr,char * organization)369 void setModuleOrganization(Module *modulePtr, char *organization)
370 {
371     modulePtr->export.organization = organization;
372     while (strlen(organization) && organization[strlen(organization)-1] == '\n') {
373 	    organization[strlen(organization) - 1] = 0;
374     }
375 }
376 
377 
378 
379 /*
380  *----------------------------------------------------------------------
381  *
382  * setModuleContactInfo --
383  *
384  *      Set the contactInfo string of a given Module.
385  *
386  * Results:
387  *	None.
388  *
389  * Side effects:
390  *      None.
391  *
392  *----------------------------------------------------------------------
393  */
394 
setModuleContactInfo(Module * modulePtr,char * contactinfo)395 void setModuleContactInfo(Module *modulePtr, char *contactinfo)
396 {
397     modulePtr->export.contactinfo = contactinfo;
398 }
399 
400 
401 
402 /*
403  *----------------------------------------------------------------------
404  *
405  * setModuleDescription --
406  *
407  *      Set the description string of a given Module.
408  *
409  * Results:
410  *	None.
411  *
412  * Side effects:
413  *      None.
414  *
415  *----------------------------------------------------------------------
416  */
417 
setModuleDescription(Module * modulePtr,char * description,Parser * parserPtr)418 void setModuleDescription(Module *modulePtr, char *description,
419 			  Parser *parserPtr)
420 {
421     if (modulePtr->export.description)
422 	smiFree(modulePtr->export.description);
423     if (parserPtr->flags & SMI_FLAG_NODESCR) {
424 	smiFree(description);
425 	modulePtr->export.description = NULL;
426     } else {
427 	modulePtr->export.description = description;
428     }
429 }
430 
431 
432 
433 /*
434  *----------------------------------------------------------------------
435  *
436  * setModuleReference --
437  *
438  *      Set the reference string of a given Module.
439  *
440  * Results:
441  *	None.
442  *
443  * Side effects:
444  *      None.
445  *
446  *----------------------------------------------------------------------
447  */
448 
setModuleReference(Module * modulePtr,char * reference,Parser * parserPtr)449 void setModuleReference(Module *modulePtr, char *reference, Parser *parserPtr)
450 {
451     if (modulePtr->export.reference)
452 	smiFree(modulePtr->export.reference);
453     if (parserPtr->flags & SMI_FLAG_NODESCR) {
454 	smiFree(reference);
455 	modulePtr->export.reference = NULL;
456     } else {
457 	modulePtr->export.reference = reference;
458     }
459 }
460 
461 
462 
463 /*
464  *----------------------------------------------------------------------
465  *
466  * findModuleByName --
467  *
468  *      Lookup a Module by a given name.
469  *
470  * Results:
471  *      A pointer to the Module structure or
472  *	NULL if it is not found.
473  *
474  * Side effects:
475  *      None.
476  *
477  *----------------------------------------------------------------------
478  */
479 
findModuleByName(const char * modulename)480 Module *findModuleByName(const char *modulename)
481 {
482     Module	*modulePtr;
483 
484     for (modulePtr = smiHandle->firstModulePtr; modulePtr;
485 	 modulePtr = modulePtr->nextPtr) {
486 	if ((modulePtr->export.name) &&
487 	    !strcmp(modulePtr->export.name, modulename)) {
488 	    return (modulePtr);
489 	}
490     }
491 
492     return (NULL);
493 }
494 
495 
496 
497 /*
498  *----------------------------------------------------------------------
499  *
500  * addRevision --
501  *
502  *      Adds a revision entry for the given module.
503  *
504  * Results:
505  *      0 on success or -1 on an error.
506  *
507  * Side effects:
508  *      None.
509  *
510  *----------------------------------------------------------------------
511  */
512 
addRevision(time_t date,char * description,Parser * parserPtr)513 Revision *addRevision(time_t date, char *description, Parser *parserPtr)
514 {
515     Revision	  *revisionPtr, *r;
516     Module	  *modulePtr;
517 
518     revisionPtr = (Revision *) smiMalloc(sizeof(Revision));
519 
520     modulePtr = parserPtr->modulePtr;
521 
522     revisionPtr->modulePtr		 = modulePtr;
523     revisionPtr->export.date	       	 = date;
524     if (parserPtr->flags & SMI_FLAG_NODESCR) {
525 	smiFree(description);
526 	revisionPtr->export.description	 = NULL;
527     } else {
528 	revisionPtr->export.description	 = description;
529     }
530     revisionPtr->line			 = parserPtr ? parserPtr->line : -1;
531 
532     for (r = modulePtr->lastRevisionPtr; r; r = r->prevPtr) {
533 	if (r->export.date > date) break;
534     }
535     if (r) {
536 	revisionPtr->nextPtr = r->nextPtr;
537 	revisionPtr->prevPtr = r;
538 	if (r->nextPtr) {
539 	    r->nextPtr->prevPtr = revisionPtr;
540 	} else {
541 	    modulePtr->lastRevisionPtr = revisionPtr;
542 	}
543 	r->nextPtr = revisionPtr;
544     } else {
545 	revisionPtr->prevPtr = NULL;
546 	if (modulePtr->firstRevisionPtr) {
547 	    modulePtr->firstRevisionPtr->prevPtr = revisionPtr;
548 	    revisionPtr->nextPtr = modulePtr->firstRevisionPtr;
549 	} else {
550 	    modulePtr->lastRevisionPtr = revisionPtr;
551 	    revisionPtr->nextPtr = NULL;
552 	}
553 	modulePtr->firstRevisionPtr = revisionPtr;
554     }
555 
556     return (revisionPtr);
557 }
558 
559 
560 
561 /*
562  *----------------------------------------------------------------------
563  *
564  * setRevisionLine --
565  *
566  *      Set the line of definition of a given Revision.
567  *
568  * Results:
569  *	None.
570  *
571  * Side effects:
572  *      None.
573  *
574  *----------------------------------------------------------------------
575  */
576 
setRevisionLine(Revision * revisionPtr,int line,Parser * parserPtr)577 void setRevisionLine(Revision *revisionPtr, int line, Parser *parserPtr)
578 {
579     if (line) {
580 	revisionPtr->line = line;
581     } else {
582 	revisionPtr->line = parserPtr ? parserPtr->line : -1;
583     }
584 }
585 
586 
587 
588 /*
589  *----------------------------------------------------------------------
590  *
591  * addImport --
592  *
593  *      Adds a descriptor to the actual module's list of imported
594  *      descriptors. This list may be checked by checkImports()
595  *	afterwards.
596  *
597  * Results:
598  *      0 on success or -1 on an error.
599  *
600  * Side effects:
601  *      None.
602  *
603  *----------------------------------------------------------------------
604  */
605 
addImport(char * name,Parser * parserPtr)606 Import *addImport(char *name, Parser *parserPtr)
607 {
608     Import        *importPtr;
609     Module	  *modulePtr;
610 
611     importPtr = (Import *) smiMalloc(sizeof(Import));
612 
613     modulePtr = parserPtr->modulePtr;
614 
615     importPtr->modulePtr		 = modulePtr;
616     importPtr->export.name       	 = name;
617     importPtr->export.module		 = NULL; /* not yet known */
618     importPtr->kind			 = KIND_UNKNOWN; /* not yet known */
619     importPtr->use			 = 0;
620     importPtr->flags			 = 0;
621     importPtr->line			 = parserPtr ? parserPtr->line : -1;
622 
623     importPtr->nextPtr			 = NULL;
624     importPtr->prevPtr			 = modulePtr->lastImportPtr;
625     if (!modulePtr->firstImportPtr)
626 	modulePtr->firstImportPtr	 = importPtr;
627     if (modulePtr->lastImportPtr)
628 	modulePtr->lastImportPtr->nextPtr = importPtr;
629     modulePtr->lastImportPtr		 = importPtr;
630 
631     return (importPtr);
632 }
633 
634 
635 
636 /*
637  *----------------------------------------------------------------------
638  *
639  * addImportFlags --
640  *
641  *      Add flags to the flags of a given Import struct.
642  *
643  * Results:
644  *	None.
645  *
646  * Side effects:
647  *      None.
648  *
649  *----------------------------------------------------------------------
650  */
651 
addImportFlags(Import * importPtr,ImportFlags flags)652 void addImportFlags(Import *importPtr, ImportFlags flags)
653 {
654     importPtr->flags |= flags;
655 }
656 
657 
658 
659 /*
660  *----------------------------------------------------------------------
661  *
662  * setImportModulename --
663  *
664  *      Set the modulename part of a given Import struct.
665  *
666  * Results:
667  *	None.
668  *
669  * Side effects:
670  *      None.
671  *
672  *----------------------------------------------------------------------
673  */
674 
setImportModulename(Import * importPtr,char * modulename)675 void setImportModulename(Import *importPtr, char *modulename)
676 {
677     if (importPtr->export.module) {
678 	smiFree(importPtr->export.module);
679     }
680     importPtr->export.module = modulename;
681 }
682 
683 
684 
685 /*
686  *----------------------------------------------------------------------
687  *
688  * checkImports --
689  *
690  *      Check wheather all descriptors in the actual module's list
691  *	are imported by a given Module. Implicitly set all Imports'
692  *	module names.
693  *
694  * Results:
695  *      0 on success or -1 on an error or number of descriptors not found.
696  *
697  * Side effects:
698  *      None.
699  *
700  *----------------------------------------------------------------------
701  */
702 
checkImports(Module * modulePtr,Parser * parserPtr)703 int checkImports(Module *modulePtr, Parser *parserPtr)
704 {
705     int         n = 0;
706     Import      *importPtr;
707     SmiNode	*smiNode;
708     SmiType	*smiType;
709     SmiMacro	*smiMacro;
710 
711     for (importPtr = parserPtr->modulePtr->firstImportPtr;
712 	 importPtr; importPtr = importPtr->nextPtr) {
713 
714 	if (importPtr->kind == KIND_UNKNOWN) {
715 	    if (modulePtr) {
716 		if ((smiNode = smiGetNode(&modulePtr->export,
717 					  importPtr->export.name))) {
718 		    importPtr->export.module =
719 			smiStrdup(modulePtr->export.name);
720 		    importPtr->kind	= KIND_OBJECT;
721 		} else if ((smiType = smiGetType(&modulePtr->export,
722 						 importPtr->export.name))) {
723 		    importPtr->export.module =
724 			smiStrdup(modulePtr->export.name);
725 		    importPtr->kind	= KIND_TYPE;
726 		} else if ((smiMacro = smiGetMacro(&modulePtr->export,
727 						   importPtr->export.name))) {
728 		    importPtr->export.module =
729 			smiStrdup(modulePtr->export.name);
730 		    importPtr->kind = KIND_MACRO;
731 		} else {
732 		    n++;
733 		    importPtr->export.module =
734 			smiStrdup(modulePtr->export.name);
735 		    smiPrintError(parserPtr, ERR_IDENTIFIER_NOT_IN_MODULE,
736 				  importPtr->export.name,
737 				  modulePtr->export.name);
738 		    importPtr->kind   = KIND_NOTFOUND;
739 		}
740 	    } else {
741 		    n++;
742 		    importPtr->export.module = smiStrdup("");
743 		    importPtr->kind   = KIND_NOTFOUND;
744 	    }
745 	}
746     }
747 
748     return (n);
749 }
750 
751 
752 
753 /*
754  *----------------------------------------------------------------------
755  *
756  * findImportByName --
757  *
758  *      Lookup an import descriptor by its name and the module to look in.
759  *
760  * Results:
761  *      A pointer to the Import structure or
762  *	NULL if it is not found.
763  *
764  * Side effects:
765  *      None.
766  *
767  *----------------------------------------------------------------------
768  */
769 
findImportByName(const char * name,Module * modulePtr)770 Import *findImportByName(const char *name, Module *modulePtr)
771 {
772     Import           *importPtr;
773 
774     if (!name)
775 	return NULL;
776 
777     for (importPtr = modulePtr->firstImportPtr; importPtr;
778 	 importPtr = importPtr->nextPtr) {
779 	if ((!strcmp(importPtr->export.name, name)) &&
780 	    (!(importPtr->flags & FLAG_INCOMPLIANCE))) {
781 		return (importPtr);
782 	}
783     }
784 
785     return NULL;
786 
787 }
788 
789 
790 
791 /*
792  *----------------------------------------------------------------------
793  *
794  * findImportByModulenameAndName --
795  *
796  *      Lookup an import descriptor by its name and the modulename
797  *	it is imported from and the module to look in.
798  *
799  * Results:
800  *      A pointer to the Import structure or
801  *	NULL if it is not found.
802  *
803  * Side effects:
804  *      None.
805  *
806  *----------------------------------------------------------------------
807  */
808 
findImportByModulenameAndName(const char * modulename,const char * name,Module * modulePtr)809 Import *findImportByModulenameAndName(const char *modulename,
810 				      const char *name, Module *modulePtr)
811 {
812     Import           *importPtr;
813 
814     for (importPtr = modulePtr->firstImportPtr; importPtr;
815 	 importPtr = importPtr->nextPtr) {
816 	if ((!strcmp(importPtr->export.name, name)) &&
817 	    (!strcmp(importPtr->export.module, modulename))) {
818 	    return (importPtr);
819 	}
820     }
821 
822     return (NULL);
823 }
824 
825 
826 
827 /*
828  *----------------------------------------------------------------------
829  *
830  * addObject --
831  *
832  *      Create a new Object and Node or update an existing one.
833  *	Also updates other Objects and Nodes according
834  *	to the PendingNode information.
835  *
836  * Results:
837  *      A pointer to the new Object structure or
838  *	NULL if terminated due to an error.
839  *
840  * Side effects:
841  *      None.
842  *
843  *----------------------------------------------------------------------
844  */
845 
addObject(char * objectname,Node * parentNodePtr,SmiSubid subid,ObjectFlags flags,Parser * parserPtr)846 Object *addObject(char *objectname, Node *parentNodePtr, SmiSubid subid,
847 		  ObjectFlags flags, Parser *parserPtr)
848 {
849     Object	     *objectPtr;
850     Node	     *nodePtr;
851     Module	     *modulePtr;
852 
853 
854     objectPtr = (Object *) smiMalloc(sizeof(Object));
855 
856     modulePtr = parserPtr ? parserPtr->modulePtr : NULL;
857 
858     objectPtr->export.name		= objectname;
859     objectPtr->export.decl		= SMI_DECL_UNKNOWN;
860     objectPtr->export.access		= SMI_ACCESS_UNKNOWN;
861     objectPtr->export.status		= SMI_STATUS_UNKNOWN;
862     objectPtr->export.format		= NULL;
863     objectPtr->export.value.basetype	= SMI_BASETYPE_UNKNOWN;
864     objectPtr->export.units		= NULL;
865     objectPtr->export.description	= NULL;
866     objectPtr->export.reference		= NULL;
867     objectPtr->export.indexkind		= SMI_INDEX_UNKNOWN;
868     objectPtr->export.implied		= 0;
869     objectPtr->export.create		= 0;
870     objectPtr->export.nodekind		= SMI_NODEKIND_UNKNOWN;
871 
872     objectPtr->modulePtr		= modulePtr;
873     objectPtr->nodePtr			= NULL;
874     objectPtr->prevSameNodePtr		= NULL;
875     objectPtr->nextSameNodePtr		= NULL;
876     objectPtr->typePtr			= NULL;
877     objectPtr->listPtr			= NULL;
878     objectPtr->flags			= flags;
879     objectPtr->line			= parserPtr ? parserPtr->line : -1;
880 
881     objectPtr->uniquenessPtr            = NULL;
882 
883     objectPtr->export.oidlen            = 0;     /* filled in by  */
884     objectPtr->export.oid               = NULL;  /* second pass.  */
885 
886     objectPtr->nextPtr				= NULL;
887     if (modulePtr) {
888         objectPtr->prevPtr			= modulePtr->lastObjectPtr;
889 	if (!modulePtr->firstObjectPtr)
890 	    modulePtr->firstObjectPtr		= objectPtr;
891 	if (modulePtr->lastObjectPtr)
892 	    modulePtr->lastObjectPtr->nextPtr	= objectPtr;
893 	modulePtr->lastObjectPtr		= objectPtr;
894     } else {
895 	objectPtr->prevPtr			= NULL;
896     }
897 
898     /*
899      * Link it into the tree.
900      */
901     nodePtr = findNodeByParentAndSubid(parentNodePtr, subid);
902     if ((parentNodePtr == parserPtr->pendingNodePtr) || (!nodePtr)) {
903 
904 	/* a new Node has to be created for this Object */
905 	nodePtr = addNode(parentNodePtr, subid, flags, parserPtr);
906 	nodePtr->firstObjectPtr			      = objectPtr;
907 	nodePtr->lastObjectPtr			      = objectPtr;
908     } else {
909 
910         objectPtr->prevSameNodePtr		      = nodePtr->lastObjectPtr;
911 	if (!nodePtr->firstObjectPtr)
912 	    nodePtr->firstObjectPtr	              = objectPtr;
913 	if (nodePtr->lastObjectPtr)
914 	    nodePtr->lastObjectPtr->nextSameNodePtr   = objectPtr;
915 	nodePtr->lastObjectPtr			      = objectPtr;
916     }
917     objectPtr->nodePtr				      = nodePtr;
918 
919     return (objectPtr);
920 }
921 
922 
923 
924 /*
925  *----------------------------------------------------------------------
926  *
927  * duplicateObject --
928  *
929  *      Create a new Object as a duplicate of a given one but with
930  *      an affiliation to another module with new flags and with
931  *	uninitialzied values.
932  *
933  * Results:
934  *      A pointer to the new Object structure or
935  *	NULL if terminated due to an error.
936  *
937  * Side effects:
938  *      None.
939  *
940  *----------------------------------------------------------------------
941  */
942 
duplicateObject(Object * templatePtr,ObjectFlags flags,Parser * parserPtr)943 Object *duplicateObject(Object *templatePtr, ObjectFlags flags,
944 			Parser *parserPtr)
945 {
946     Object		  *objectPtr;
947     Node		  *nodePtr;
948     Module		  *modulePtr;
949 
950     objectPtr = (Object *) smiMalloc(sizeof(Object));
951 
952     modulePtr = parserPtr->modulePtr;
953     nodePtr   = templatePtr->nodePtr;
954 
955     objectPtr->export.name			= NULL;
956     objectPtr->export.decl			= SMI_DECL_UNKNOWN;
957     objectPtr->export.access			= SMI_ACCESS_UNKNOWN;
958     objectPtr->export.status			= SMI_STATUS_UNKNOWN;
959     objectPtr->export.format			= NULL;
960     objectPtr->export.value.basetype		= SMI_BASETYPE_UNKNOWN;
961     objectPtr->export.units			= NULL;
962     objectPtr->export.description		= NULL;
963     objectPtr->export.reference			= NULL;
964     objectPtr->export.indexkind			= SMI_INDEX_UNKNOWN;
965     objectPtr->export.implied			= 0;
966     objectPtr->export.create			= 0;
967     objectPtr->export.nodekind			= SMI_NODEKIND_UNKNOWN;
968 
969     objectPtr->modulePtr		        = modulePtr;
970     objectPtr->nodePtr				= nodePtr;
971     objectPtr->prevSameNodePtr			= NULL;
972     objectPtr->nextSameNodePtr			= NULL;
973     objectPtr->typePtr				= NULL;
974     objectPtr->listPtr				= NULL;
975     objectPtr->flags				= flags;
976     objectPtr->line				= parserPtr ? parserPtr->line : -1;
977 
978     objectPtr->export.oidlen                    = 0;     /* filled in by  */
979     objectPtr->export.oid                       = NULL;  /* second pass.  */
980 
981     objectPtr->nextPtr				= NULL;
982     if (modulePtr) {
983         objectPtr->prevPtr			= modulePtr->lastObjectPtr;
984 	if (!modulePtr->firstObjectPtr)
985 	    modulePtr->firstObjectPtr		= objectPtr;
986 	if (modulePtr->lastObjectPtr)
987 	    modulePtr->lastObjectPtr->nextPtr	= objectPtr;
988 	modulePtr->lastObjectPtr		= objectPtr;
989     } else {
990 	objectPtr->prevPtr			= NULL;
991     }
992 
993     objectPtr->prevSameNodePtr			      = nodePtr->lastObjectPtr;
994     if (!nodePtr->firstObjectPtr)
995 	nodePtr->firstObjectPtr			      = objectPtr;
996     if (nodePtr->lastObjectPtr)
997 	nodePtr->lastObjectPtr->nextSameNodePtr       = objectPtr;
998     nodePtr->lastObjectPtr			      = objectPtr;
999     objectPtr->nodePtr				      = nodePtr;
1000 
1001     return (objectPtr);
1002 }
1003 
1004 
1005 
1006 /*
1007  *----------------------------------------------------------------------
1008  *
1009  * addNode --
1010  *
1011  *      Create a new Node by a given parent Node and subid.
1012  *
1013  * Results:
1014  *      A pointer to the new Node structure or
1015  *	NULL if terminated due to an error.
1016  *
1017  * Side effects:
1018  *      None.
1019  *
1020  *----------------------------------------------------------------------
1021  */
1022 
addNode(Node * parentNodePtr,SmiSubid subid,NodeFlags flags,Parser * parserPtr)1023 Node *addNode (Node *parentNodePtr, SmiSubid subid, NodeFlags flags,
1024 	       Parser *parserPtr)
1025 {
1026     Node	    *nodePtr;
1027     Node	    *c;
1028 
1029     nodePtr = (Node *) smiMalloc(sizeof(Node));
1030 
1031     nodePtr->flags				= flags;
1032     nodePtr->subid				= subid;
1033     nodePtr->parentPtr				= parentNodePtr;
1034     nodePtr->firstChildPtr			= NULL;
1035     nodePtr->lastChildPtr			= NULL;
1036     nodePtr->firstObjectPtr			= NULL;
1037     nodePtr->lastObjectPtr			= NULL;
1038 
1039     /*
1040      * this cannot be set in all situations (pending sub trees).
1041      * we delay it to the second pass.
1042      */
1043     nodePtr->oidlen                             = 0;
1044     nodePtr->oid				= NULL;
1045 
1046     if (parentNodePtr) {
1047 	if (parentNodePtr->firstChildPtr) {
1048 	    for (c = parentNodePtr->firstChildPtr;
1049 		 c && (c->subid < subid);
1050 		 c = c->nextPtr);
1051 	    if (c) {
1052 		if (c != parentNodePtr->firstChildPtr) {
1053 		    c->prevPtr->nextPtr = nodePtr;
1054 		    nodePtr->prevPtr = c->prevPtr;
1055 		    c->prevPtr = nodePtr;
1056 		    nodePtr->nextPtr = c;
1057 		} else {
1058 		    c->prevPtr = nodePtr;
1059 		    nodePtr->nextPtr = c;
1060 		    nodePtr->prevPtr = NULL;
1061 		    parentNodePtr->firstChildPtr = nodePtr;
1062 		}
1063 	    } else {
1064 		nodePtr->nextPtr = NULL;
1065 		nodePtr->prevPtr = parentNodePtr->lastChildPtr;
1066 		parentNodePtr->lastChildPtr->nextPtr = nodePtr;
1067 		parentNodePtr->lastChildPtr = nodePtr;
1068 	    }
1069 	} else {
1070 	    parentNodePtr->firstChildPtr = nodePtr;
1071 	    parentNodePtr->lastChildPtr = nodePtr;
1072 	    nodePtr->nextPtr = NULL;
1073 	    nodePtr->prevPtr = NULL;
1074 	}
1075     }
1076 
1077     return nodePtr;
1078 }
1079 
1080 
1081 
1082 /*
1083  *----------------------------------------------------------------------
1084  *
1085  * createNodes --
1086  *
1087  *      Create all missing Nodes down the tree along all subids of
1088  *	a given Oid.
1089  *
1090  * Results:
1091  *      A pointer to the leaf Node structure or
1092  *	NULL if terminated due to an error.
1093  *
1094  * Side effects:
1095  *      None.
1096  *
1097  *----------------------------------------------------------------------
1098  */
1099 
createNodes(unsigned int oidlen,SmiSubid * oid)1100 Node *createNodes(unsigned int oidlen, SmiSubid *oid)
1101 {
1102     Node	 *parentNodePtr, *nodePtr;
1103     unsigned int i;
1104 
1105     parentNodePtr = smiHandle->rootNodePtr;
1106 
1107     for(i = 0; i < oidlen; i++) {
1108 	if (!(nodePtr = findNodeByParentAndSubid(parentNodePtr, oid[i]))) {
1109 	    nodePtr = addNode(parentNodePtr, oid[i], 0, NULL);
1110 	}
1111 	parentNodePtr = nodePtr;
1112     }
1113 
1114     return parentNodePtr;
1115 }
1116 
1117 
1118 
1119 /*
1120  *----------------------------------------------------------------------
1121  *
1122  * createNodesByOidString --
1123  *
1124  *      Create all missing Nodes down the tree along all subids of
1125  *	a given Oid.
1126  *
1127  * Results:
1128  *      A pointer to the leaf Node structure or
1129  *	NULL if terminated due to an error.
1130  *
1131  * Side effects:
1132  *      None.
1133  *
1134  *----------------------------------------------------------------------
1135  */
1136 
createNodesByOidString(const char * oid)1137 Node *createNodesByOidString(const char *oid)
1138 {
1139     char		*p, *elements;
1140     Node		*parentNodePtr, *nodePtr;
1141     SmiSubid		subid;
1142 
1143     parentNodePtr = smiHandle->rootNodePtr;
1144     elements = smiStrdup(oid);
1145 
1146     p = strtok(elements, ".");
1147     do {
1148 	subid = (unsigned int)strtoul(p, NULL, 0);
1149 	if (!(nodePtr = findNodeByParentAndSubid(parentNodePtr,
1150 						 subid))) {
1151 	    nodePtr = addNode(parentNodePtr, subid, 0, NULL);
1152 	}
1153 	parentNodePtr = nodePtr;
1154     } while ((p = strtok(NULL, ".")));
1155 
1156     smiFree(elements);
1157 
1158     return parentNodePtr;
1159 }
1160 
1161 
1162 
1163 /*
1164  *----------------------------------------------------------------------
1165  *
1166  * getParentNode --
1167  *
1168  *      Return the parent of a given Node.
1169  *
1170  * Results:
1171  *      A pointer to the parent Node structure.
1172  *
1173  * Side effects:
1174  *      None.
1175  *
1176  *----------------------------------------------------------------------
1177  */
1178 
getParentNode(Node * nodePtr)1179 Node *getParentNode(Node *nodePtr)
1180 {
1181     return nodePtr->parentPtr;
1182 }
1183 
1184 
1185 
1186 /*
1187  *----------------------------------------------------------------------
1188  *
1189  * mergeNodeTrees --
1190  *
1191  *      Merge the subtree rooted at `from' into the `to' tree recursively
1192  *      and release the `from' tree.
1193  *
1194  * Results:
1195  *	None.
1196  *
1197  * Side effects:
1198  *      None.
1199  *
1200  *----------------------------------------------------------------------
1201  */
1202 
mergeNodeTrees(Node * toNodePtr,Node * fromNodePtr,Parser * parserPtr)1203 static void mergeNodeTrees(Node *toNodePtr, Node *fromNodePtr,
1204 			   Parser *parserPtr)
1205 {
1206     Node	      *nodePtr, *toChildPtr, *nextPtr;
1207     Object	      *objectPtr;
1208 
1209     /* (1) merge lists of Objects for this node */
1210     if (fromNodePtr->firstObjectPtr) {
1211 	if (!toNodePtr->firstObjectPtr) {
1212 	    toNodePtr->firstObjectPtr = fromNodePtr->firstObjectPtr;
1213 	    toNodePtr->lastObjectPtr = fromNodePtr->lastObjectPtr;
1214 	} else {
1215 	    fromNodePtr->firstObjectPtr->prevSameNodePtr =
1216 		toNodePtr->lastObjectPtr;
1217 	    toNodePtr->lastObjectPtr->nextSameNodePtr =
1218 		fromNodePtr->firstObjectPtr;
1219 	    toNodePtr->lastObjectPtr = fromNodePtr->lastObjectPtr;
1220 	}
1221     }
1222     for (objectPtr = fromNodePtr->firstObjectPtr;
1223 	 objectPtr; objectPtr = objectPtr->nextSameNodePtr) {
1224 	objectPtr->nodePtr = toNodePtr;
1225 
1226     }
1227 
1228     /* (2) loop: merge all first-level `from' sub-trees to `to' */
1229     /* adjust all `from' sub-nodes' parentPtrs */
1230     for (nodePtr = fromNodePtr->firstChildPtr; nodePtr;
1231 	 nodePtr = nodePtr->nextPtr) {
1232 	nodePtr->parentPtr = toNodePtr;
1233     }
1234     if (!toNodePtr->firstChildPtr) {
1235 	/*
1236 	 * if `to' has no sub-nodes, just move the `from' sub-nodes.
1237 	 */
1238 	toNodePtr->firstChildPtr = fromNodePtr->firstChildPtr;
1239 	toNodePtr->lastChildPtr = fromNodePtr->lastChildPtr;
1240     } else {
1241 	/*
1242 	 * otherwise, we really have to merge both trees...
1243 	 */
1244 	for (nodePtr = fromNodePtr->firstChildPtr; nodePtr; ) {
1245 	    nextPtr = nodePtr->nextPtr;
1246 	    if ((toChildPtr = findNodeByParentAndSubid(toNodePtr,
1247 						       nodePtr->subid))) {
1248 		/*
1249 		 * if a sub-node with the same subid is already present
1250 		 * in `to', merge them recursively.
1251 		 */
1252 		mergeNodeTrees(toChildPtr, nodePtr, parserPtr);
1253 	    } else {
1254 		/*
1255 		 * otherwise, move the sub-tree from `from' to `to'.
1256 		 */
1257 		if (nodePtr->subid < toNodePtr->firstChildPtr->subid) {
1258 		    /* move to the head. */
1259 		    nodePtr->nextPtr = toNodePtr->firstChildPtr;
1260 		    toNodePtr->firstChildPtr = nodePtr;
1261 		} else if (nodePtr->subid > toNodePtr->lastChildPtr->subid) {
1262 		    /* move to the end. */
1263 		    nodePtr->prevPtr = toNodePtr->lastChildPtr;
1264 		    toNodePtr->lastChildPtr->nextPtr = nodePtr;
1265 		    toNodePtr->lastChildPtr = nodePtr;
1266 		} else {
1267 		    /* move to the appropriate place in the `to' list. */
1268 		    for (toChildPtr = toNodePtr->firstChildPtr;
1269 			 toChildPtr->nextPtr->subid < nodePtr->subid;
1270 			 toChildPtr = toChildPtr->nextPtr);
1271 		    toChildPtr->nextPtr->prevPtr = nodePtr;
1272 		    nodePtr->nextPtr = toChildPtr->nextPtr;
1273 		    nodePtr->prevPtr = toChildPtr;
1274 		    toChildPtr->nextPtr = nodePtr;
1275 		}
1276 	    }
1277 	    nodePtr = nextPtr;
1278 	}
1279     }
1280 
1281     smiFree(fromNodePtr);
1282 }
1283 
1284 
1285 
1286 /*
1287  *----------------------------------------------------------------------
1288  *
1289  * setObjectName --
1290  *
1291  *      Set the name of a given Object. Combine two Objects if the name
1292  *	already exists.
1293  *
1294  * Results:
1295  *	(Object *) of the potentially combined object.
1296  *
1297  * Side effects:
1298  *      None.
1299  *
1300  *----------------------------------------------------------------------
1301  */
1302 
setObjectName(Object * objectPtr,char * name,Parser * parserPtr)1303 Object *setObjectName(Object *objectPtr, char *name, Parser *parserPtr)
1304 {
1305     Node	      *nodePtr, *nextPtr;
1306     Module	      *modulePtr;
1307     Object	      *newObjectPtr;
1308 
1309     if (objectPtr->export.name) {
1310 	smiFree(objectPtr->export.name);
1311     }
1312     objectPtr->export.name = name;
1313     /*
1314      * If this name is found on the pending list (at depth==1 in
1315      * pendingRootNode), we have to move the corresponding subtree to
1316      * the main tree.
1317      */
1318     for (nodePtr = parserPtr->pendingNodePtr->firstChildPtr; nodePtr;
1319 	 nodePtr = nextPtr) {
1320 
1321 	/*
1322 	 * probably we change the contents of `pending', so remember
1323 	 * the next pointer.
1324 	 */
1325 	nextPtr = nodePtr->nextPtr;
1326 
1327 	if (!strcmp(nodePtr->firstObjectPtr->export.name, name)) {
1328 
1329 	    /*
1330 	     * remove nodePtr from the pendingRootNode tree.
1331 	     */
1332 	    if (nodePtr->prevPtr) {
1333 		nodePtr->prevPtr->nextPtr = nodePtr->nextPtr;
1334 	    } else {
1335 		parserPtr->pendingNodePtr->firstChildPtr = nodePtr->nextPtr;
1336 	    }
1337 	    if (nodePtr->nextPtr) {
1338 		nodePtr->nextPtr->prevPtr = nodePtr->prevPtr;
1339 	    } else {
1340 		parserPtr->pendingNodePtr->lastChildPtr = nodePtr->prevPtr;
1341 	    }
1342 
1343 #if 0
1344 	    objectPtr->nodePtr->firstObjectPtr = NULL;
1345 	    objectPtr->nodePtr->lastObjectPtr = NULL;
1346 #else
1347 	    if (objectPtr->nodePtr->lastObjectPtr != NULL) {
1348 		if (objectPtr->nodePtr->lastObjectPtr->export.oid == NULL) {
1349 		    objectPtr->nodePtr->lastObjectPtr =
1350 			objectPtr->nodePtr->lastObjectPtr->prevSameNodePtr;
1351 		    if (objectPtr->nodePtr->lastObjectPtr == NULL) {
1352 			objectPtr->nodePtr->firstObjectPtr = NULL;
1353 		    }
1354 		}
1355 	    }
1356 #endif
1357 
1358 	    newObjectPtr = nodePtr->firstObjectPtr;
1359 	    if (newObjectPtr) {
1360 		modulePtr = newObjectPtr->modulePtr;
1361 		if (modulePtr->objectPtr == objectPtr) {
1362 		    modulePtr->objectPtr = newObjectPtr;
1363 		}
1364 		if (modulePtr->firstObjectPtr == objectPtr) {
1365 		    modulePtr->firstObjectPtr = objectPtr->nextPtr;
1366 		    modulePtr->firstObjectPtr->prevPtr = NULL;
1367 		}
1368 		if (modulePtr->lastObjectPtr == objectPtr) {
1369 		    modulePtr->lastObjectPtr = objectPtr->prevPtr;
1370 		    modulePtr->lastObjectPtr->nextPtr = NULL;
1371 		}
1372 
1373 		mergeNodeTrees(objectPtr->nodePtr, nodePtr, parserPtr);
1374 		smiFree(objectPtr->export.name);
1375 		smiFree(objectPtr);
1376 		return newObjectPtr;
1377 	    } else {
1378 		return objectPtr;
1379 	    }
1380 	}
1381     }
1382     return objectPtr;
1383 }
1384 
1385 
1386 
1387 /*
1388  *----------------------------------------------------------------------
1389  *
1390  * setObjectType --
1391  *
1392  *      Set the type (pointer to a Type struct) of a given Object.
1393  *
1394  * Results:
1395  *	None.
1396  *
1397  * Side effects:
1398  *      None.
1399  *
1400  *----------------------------------------------------------------------
1401  */
1402 
setObjectType(Object * objectPtr,Type * typePtr)1403 void setObjectType(Object *objectPtr, Type *typePtr)
1404 {
1405     objectPtr->typePtr = typePtr;
1406 }
1407 
1408 
1409 
1410 /*
1411  *----------------------------------------------------------------------
1412  *
1413  * setObjectAccess --
1414  *
1415  *      Set the access of a given Object.
1416  *
1417  * Results:
1418  *	None.
1419  *
1420  * Side effects:
1421  *      None.
1422  *
1423  *----------------------------------------------------------------------
1424  */
1425 
setObjectAccess(Object * objectPtr,SmiAccess access)1426 void setObjectAccess(Object *objectPtr, SmiAccess access)
1427 {
1428     objectPtr->export.access = access;
1429 }
1430 
1431 
1432 
1433 /*
1434  *----------------------------------------------------------------------
1435  *
1436  * setObjectStatus --
1437  *
1438  *      Set the status of a given Object.
1439  *
1440  * Results:
1441  *	None.
1442  *
1443  * Side effects:
1444  *      None.
1445  *
1446  *----------------------------------------------------------------------
1447  */
1448 
setObjectStatus(Object * objectPtr,SmiStatus status)1449 void setObjectStatus(Object *objectPtr, SmiStatus status)
1450 {
1451     objectPtr->export.status = status;
1452 }
1453 
1454 
1455 
1456 /*
1457  *----------------------------------------------------------------------
1458  *
1459  * setObjectDescription --
1460  *
1461  *      Set the description of a given Object.
1462  *
1463  * Results:
1464  *	None.
1465  *
1466  * Side effects:
1467  *      None.
1468  *
1469  *----------------------------------------------------------------------
1470  */
1471 
setObjectDescription(Object * objectPtr,char * description,Parser * parserPtr)1472 void setObjectDescription(Object *objectPtr, char *description,
1473 			  Parser *parserPtr)
1474 {
1475     if (objectPtr->export.description)
1476 	smiFree(objectPtr->export.description);
1477     if (parserPtr->flags & SMI_FLAG_NODESCR) {
1478 	smiFree(description);
1479 	objectPtr->export.description = NULL;
1480     } else {
1481 	objectPtr->export.description = description;
1482     }
1483 }
1484 
1485 
1486 
1487 /*
1488  *----------------------------------------------------------------------
1489  *
1490  * setObjectReference --
1491  *
1492  *      Set the reference of a given Object.
1493  *
1494  * Results:
1495  *	None.
1496  *
1497  * Side effects:
1498  *      None.
1499  *
1500  *----------------------------------------------------------------------
1501  */
1502 
setObjectReference(Object * objectPtr,char * reference,Parser * parserPtr)1503 void setObjectReference(Object *objectPtr, char *reference, Parser *parserPtr)
1504 {
1505     if (objectPtr->export.reference)
1506 	smiFree(objectPtr->export.reference);
1507     if (parserPtr->flags & SMI_FLAG_NODESCR) {
1508 	smiFree(reference);
1509 	objectPtr->export.reference = NULL;
1510     } else {
1511 	objectPtr->export.reference = reference;
1512     }
1513 }
1514 
1515 
1516 /*
1517  *----------------------------------------------------------------------
1518  *
1519  * setObjectFormat --
1520  *
1521  *      Set the format of a given Object.
1522  *
1523  * Results:
1524  *	None.
1525  *
1526  * Side effects:
1527  *      None.
1528  *
1529  *----------------------------------------------------------------------
1530  */
1531 
setObjectFormat(Object * objectPtr,char * format)1532 void setObjectFormat(Object *objectPtr, char *format)
1533 {
1534     if (objectPtr->export.format) smiFree(objectPtr->export.format);
1535     objectPtr->export.format = format;
1536 }
1537 
1538 
1539 
1540 /*
1541  *----------------------------------------------------------------------
1542  *
1543  * setObjectUnits --
1544  *
1545  *      Set the units of a given Object.
1546  *
1547  * Results:
1548  *	None.
1549  *
1550  * Side effects:
1551  *      None.
1552  *
1553  *----------------------------------------------------------------------
1554  */
1555 
setObjectUnits(Object * objectPtr,char * units)1556 void setObjectUnits(Object *objectPtr, char *units)
1557 {
1558     if (objectPtr->export.units) smiFree(objectPtr->export.units);
1559     objectPtr->export.units = units;
1560 }
1561 
1562 
1563 
1564 /*
1565  *----------------------------------------------------------------------
1566  *
1567  * setObjectDecl --
1568  *
1569  *      Set the declaring macro of a given Object.
1570  *
1571  * Results:
1572  *	None.
1573  *
1574  * Side effects:
1575  *      None.
1576  *
1577  *----------------------------------------------------------------------
1578  */
1579 
setObjectDecl(Object * objectPtr,SmiDecl decl)1580 void setObjectDecl(Object *objectPtr, SmiDecl decl)
1581 {
1582     objectPtr->export.decl = decl;
1583 }
1584 
1585 
1586 
1587 /*
1588  *----------------------------------------------------------------------
1589  *
1590  * setObjectLine --
1591  *
1592  *      Set the line of definition of a given Object.
1593  *
1594  * Results:
1595  *	None.
1596  *
1597  * Side effects:
1598  *      None.
1599  *
1600  *----------------------------------------------------------------------
1601  */
1602 
setObjectLine(Object * objectPtr,int line,Parser * parserPtr)1603 void setObjectLine(Object *objectPtr, int line, Parser *parserPtr)
1604 {
1605     if (line) {
1606 	objectPtr->line = line;
1607     } else {
1608 	objectPtr->line = parserPtr ? parserPtr->line : -1;
1609     }
1610 }
1611 
1612 
1613 
1614 /*
1615  *----------------------------------------------------------------------
1616  *
1617  * setObjectNodekind --
1618  *
1619  *      Set the language independant SmiNodekind of a given Object.
1620  *
1621  * Results:
1622  *	None.
1623  *
1624  * Side effects:
1625  *      None.
1626  *
1627  *----------------------------------------------------------------------
1628  */
1629 
setObjectNodekind(Object * objectPtr,SmiNodekind nodekind)1630 void setObjectNodekind(Object *objectPtr, SmiNodekind nodekind)
1631 {
1632     objectPtr->export.nodekind = nodekind;
1633 }
1634 
1635 
1636 
1637 /*
1638  *----------------------------------------------------------------------
1639  *
1640  * addObjectFlags --
1641  *
1642  *      Add flags to the flags of a given Object.
1643  *
1644  * Results:
1645  *	None.
1646  *
1647  * Side effects:
1648  *      None.
1649  *
1650  *----------------------------------------------------------------------
1651  */
1652 
addObjectFlags(Object * objectPtr,ObjectFlags flags)1653 void addObjectFlags(Object *objectPtr, ObjectFlags flags)
1654 {
1655     objectPtr->flags |= flags;
1656 }
1657 
1658 
1659 
1660 /*
1661  *----------------------------------------------------------------------
1662  *
1663  * deleteObjectFlags --
1664  *
1665  *      Delete flags from the flags of a given Object.
1666  *
1667  * Results:
1668  *	None.
1669  *
1670  * Side effects:
1671  *      None.
1672  *
1673  *----------------------------------------------------------------------
1674  */
1675 
deleteObjectFlags(Object * objectPtr,ObjectFlags flags)1676 void deleteObjectFlags(Object *objectPtr, ObjectFlags flags)
1677 {
1678     objectPtr->flags &= ~flags;
1679 }
1680 
1681 
1682 
1683 /*
1684  *----------------------------------------------------------------------
1685  *
1686  * checkObjectFlag --
1687  *
1688  *      Check whether a given set of flags of a given Object are all set.
1689  *
1690  * Results:
1691  *	true if all named flags are set.
1692  *
1693  * Side effects:
1694  *      None.
1695  *
1696  *----------------------------------------------------------------------
1697  */
1698 
checkObjectFlags(Object * objectPtr,ObjectFlags flags)1699 int checkObjectFlags(Object *objectPtr, ObjectFlags flags)
1700 {
1701     return ((objectPtr->flags & flags) == flags);
1702 }
1703 
1704 
1705 
1706 /*
1707  *----------------------------------------------------------------------
1708  *
1709  * setObjectIndex --
1710  *
1711  *      Set the list of INDEX elements of a given Object.
1712  *
1713  * Results:
1714  *	None.
1715  *
1716  * Side effects:
1717  *      None.
1718  *
1719  *----------------------------------------------------------------------
1720  */
1721 
1722 /* TODO remove me
1723 void setObjectIndex(Object *objectPtr, Index *indexPtr)
1724     Object	 *objectPtr;
1725     Index	 *indexPtr;
1726 {
1727     objectPtr->indexPtr = indexPtr;
1728 }
1729 */
1730 
1731 
1732 /*
1733  *----------------------------------------------------------------------
1734  *
1735  * setObjectList --
1736  *
1737  *      Set the list of objects of a notification type or object group
1738  *	or the list of notifications of a notification group.
1739  *
1740  * Results:
1741  *	None.
1742  *
1743  * Side effects:
1744  *      None.
1745  *
1746  *----------------------------------------------------------------------
1747  */
1748 
setObjectList(Object * objectPtr,List * listPtr)1749 void setObjectList(Object *objectPtr, List *listPtr)
1750 {
1751     objectPtr->listPtr = listPtr;
1752 }
1753 
1754 
1755 
1756 /*
1757  *----------------------------------------------------------------------
1758  *
1759  * setObjectRelated --
1760  *
1761  *      Set the related object of a given object (e.g. SMIv2 AUGMENTS)
1762  *
1763  * Results:
1764  *	None.
1765  *
1766  * Side effects:
1767  *      None.
1768  *
1769  *----------------------------------------------------------------------
1770  */
1771 
setObjectRelated(Object * objectPtr,Object * relatedPtr)1772 void setObjectRelated(Object *objectPtr, Object *relatedPtr)
1773 {
1774     objectPtr->relatedPtr = relatedPtr;
1775 }
1776 
1777 
1778 
1779 /*
1780  *----------------------------------------------------------------------
1781  *
1782  * setObjectImplied --
1783  *
1784  *      Set the implied flag of a given object
1785  *
1786  * Results:
1787  *	None.
1788  *
1789  * Side effects:
1790  *      None.
1791  *
1792  *----------------------------------------------------------------------
1793  */
1794 
setObjectImplied(Object * objectPtr,int implied)1795 void setObjectImplied(Object *objectPtr, int implied)
1796 {
1797     objectPtr->export.implied = implied;
1798 }
1799 
1800 
1801 
1802 /*
1803  *----------------------------------------------------------------------
1804  *
1805  * setObjectCreate --
1806  *
1807  *      Set the create flag of a given (table entry) object
1808  *
1809  * Results:
1810  *	None.
1811  *
1812  * Side effects:
1813  *      None.
1814  *
1815  *----------------------------------------------------------------------
1816  */
1817 
setObjectCreate(Object * objectPtr,int create)1818 void setObjectCreate(Object *objectPtr, int create)
1819 {
1820     objectPtr->export.create = create;
1821 }
1822 
1823 
1824 
1825 /*
1826  *----------------------------------------------------------------------
1827  *
1828  * setObjectIndexkind --
1829  *
1830  *      Set the indexkind of a given (table entry) object
1831  *
1832  * Results:
1833  *	None.
1834  *
1835  * Side effects:
1836  *      None.
1837  *
1838  *----------------------------------------------------------------------
1839  */
1840 
setObjectIndexkind(Object * objectPtr,SmiIndexkind indexkind)1841 void setObjectIndexkind(Object *objectPtr, SmiIndexkind indexkind)
1842 {
1843     objectPtr->export.indexkind = indexkind;
1844 }
1845 
1846 
1847 
1848 /*
1849  *----------------------------------------------------------------------
1850  *
1851  * setObjectValue --
1852  *
1853  *      Set the default value pointer of a given Object.
1854  *
1855  * Results:
1856  *	None.
1857  *
1858  * Side effects:
1859  *      None.
1860  *
1861  *----------------------------------------------------------------------
1862  */
1863 
setObjectValue(Object * objectPtr,SmiValue * valuePtr)1864 void setObjectValue(Object *objectPtr, SmiValue *valuePtr)
1865 {
1866     objectPtr->export.value = *valuePtr;
1867     smiFree(valuePtr);
1868 }
1869 
1870 
1871 
1872 /*
1873  *----------------------------------------------------------------------
1874  *
1875  * setObjectUniqueness --
1876  *
1877  *      Set the uniqueness entry of an object
1878  *
1879  * Results:
1880  *	None.
1881  *
1882  * Side effects:
1883  *      None.
1884  *
1885  *----------------------------------------------------------------------
1886  */
1887 
setObjectUniqueness(Object * objectPtr,List * listPtr)1888 void setObjectUniqueness(Object *objectPtr, List *listPtr)
1889 {
1890     objectPtr->uniquenessPtr = listPtr;
1891 }
1892 
1893 
1894 
1895 /*
1896  *----------------------------------------------------------------------
1897  *
1898  * setObjectInstallErrors --
1899  *
1900  *      Set the install errors entry of an object
1901  *
1902  * Results:
1903  *	None.
1904  *
1905  * Side effects:
1906  *      None.
1907  *
1908  *----------------------------------------------------------------------
1909  */
1910 
1911 /*void setObjectInstallErrors(Object *objectPtr, List *listPtr)
1912 {
1913     objectPtr->installErrorsPtr = listPtr;
1914 }*/
1915 
1916 
1917 
1918 /*
1919  *----------------------------------------------------------------------
1920  *
1921  * findNodeByParentAndSubid --
1922  *
1923  *      Lookup a Node by a given parent and subid value.
1924  *
1925  * Results:
1926  *      A pointer to the Node structure or
1927  *	NULL if it is not found.
1928  *
1929  * Side effects:
1930  *      None.
1931  *
1932  *----------------------------------------------------------------------
1933  */
1934 
findNodeByParentAndSubid(Node * parentNodePtr,SmiSubid subid)1935 Node *findNodeByParentAndSubid(Node *parentNodePtr, SmiSubid subid)
1936 {
1937     Node *nodePtr;
1938 
1939     if (parentNodePtr &&
1940 	(parentNodePtr != smiHandle->parserPtr->pendingNodePtr)) {
1941 	for (nodePtr = parentNodePtr->firstChildPtr; nodePtr;
1942 	     nodePtr = nodePtr->nextPtr) {
1943 	    if (nodePtr->subid == subid) {
1944 		return (nodePtr);
1945 	    }
1946 	}
1947     }
1948 
1949     return (NULL);
1950 }
1951 
1952 
1953 
1954 /*
1955  *----------------------------------------------------------------------
1956  *
1957  * findNodeByOid --
1958  *
1959  *      Lookup a Node by a given array of numerical subids.
1960  *
1961  * Results:
1962  *      A pointer to the Node structure or
1963  *	NULL if it is not found.
1964  *
1965  * Side effects:
1966  *      None.
1967  *
1968  *----------------------------------------------------------------------
1969  */
1970 
findNodeByOid(unsigned int oidlen,SmiSubid * oid)1971 Node *findNodeByOid(unsigned int oidlen, SmiSubid *oid)
1972 {
1973     Node          *nodePtr;
1974     unsigned int  i;
1975 
1976     nodePtr = smiHandle->rootNodePtr;
1977     for(i = 0; i < oidlen && nodePtr; i++) {
1978 	nodePtr = findNodeByParentAndSubid(nodePtr, oid[i]);
1979     }
1980 
1981     return (nodePtr);
1982 }
1983 
1984 
1985 
1986 /*
1987  *----------------------------------------------------------------------
1988  *
1989  * findNodeByOidString --
1990  *
1991  *      Lookup a Node by a given string of concatinated numerical subids.
1992  *
1993  * Results:
1994  *      A pointer to the Node structure or
1995  *	NULL if it is not found.
1996  *
1997  * Side effects:
1998  *      None.
1999  *
2000  *----------------------------------------------------------------------
2001  */
2002 
findNodeByOidString(char * oid)2003 Node *findNodeByOidString(char *oid)
2004 {
2005     Node *nodePtr;
2006     char *s;
2007     char *p;
2008 
2009     s = smiStrdup(oid);
2010     nodePtr = smiHandle->rootNodePtr;
2011     for(p = strtok(s, ". "); p && nodePtr; p = strtok(NULL, ". ")) {
2012 	nodePtr = findNodeByParentAndSubid(nodePtr, atoi(p));
2013     }
2014 
2015     smiFree(s);
2016     return (nodePtr);
2017 }
2018 
2019 
2020 
2021 /*
2022  *----------------------------------------------------------------------
2023  *
2024  * findObjectByNode --
2025  *
2026  *      Lookup an Object by a given Node. Note, that there might be
2027  *	multiple definitions for one node.
2028  *
2029  * Results:
2030  *      A pointer to the first Object structure in the current View or
2031  *	a pointer to the first Object if none is in the current View or
2032  *	NULL if it is not found.
2033  *
2034  * Side effects:
2035  *      None.
2036  *
2037  *----------------------------------------------------------------------
2038  */
2039 
findObjectByNode(Node * nodePtr)2040 Object *findObjectByNode(Node *nodePtr)
2041 {
2042     Object    *objectPtr;
2043     Object    *goodObjectPtr = NULL;
2044 
2045     /* first, try to find an object in the current view. */
2046     for (objectPtr = nodePtr->firstObjectPtr; objectPtr;
2047 	 objectPtr = objectPtr->nextSameNodePtr) {
2048 	if (isInView(objectPtr->modulePtr->export.name)) {
2049 	    if (! goodObjectPtr) {
2050 		goodObjectPtr = objectPtr;
2051 	    } else if (objectPtr->modulePtr->export.language
2052 		       > goodObjectPtr->modulePtr->export.language) {
2053 		goodObjectPtr = objectPtr;
2054 	    }
2055 	}
2056     }
2057 
2058     return goodObjectPtr ? goodObjectPtr : nodePtr->firstObjectPtr;
2059 }
2060 
2061 
2062 
2063 /*
2064  *----------------------------------------------------------------------
2065  *
2066  * findObjectByModuleAndNode --
2067  *
2068  *      Lookup an Object by a given Node and Module. This is necessary
2069  *	since there might be different declarations in different modules
2070  *	for the same OID.
2071  *
2072  * Results:
2073  *      A pointer to the Object structure or
2074  *	NULL if it is not found.
2075  *
2076  * Side effects:
2077  *      None.
2078  *
2079  *----------------------------------------------------------------------
2080  */
2081 
findObjectByModuleAndNode(Module * modulePtr,Node * nodePtr)2082 Object *findObjectByModuleAndNode(Module *modulePtr, Node *nodePtr)
2083 {
2084     Object    *objectPtr;
2085 
2086     for (objectPtr = nodePtr->firstObjectPtr; objectPtr;
2087 	 objectPtr = objectPtr->nextSameNodePtr) {
2088 	if (objectPtr->modulePtr == modulePtr) {
2089 	    return (objectPtr);
2090 	}
2091     }
2092 
2093     return (NULL);
2094 }
2095 
2096 
2097 
2098 /*
2099  *----------------------------------------------------------------------
2100  *
2101  * findObjectByModulenameAndNode --
2102  *
2103  *      Lookup an Object by a given Node and Modulename. This is necessary
2104  *	since there might be different declarations in different modules
2105  *	for the same OID.
2106  *
2107  * Results:
2108  *      A pointer to the Object structure or
2109  *	NULL if it is not found.
2110  *
2111  * Side effects:
2112  *      None.
2113  *
2114  *----------------------------------------------------------------------
2115  */
2116 
findObjectByModulenameAndNode(const char * modulename,Node * nodePtr)2117 Object *findObjectByModulenameAndNode(const char *modulename, Node *nodePtr)
2118 {
2119     Object     *objectPtr;
2120 
2121     for (objectPtr = nodePtr->firstObjectPtr; objectPtr;
2122 	 objectPtr = objectPtr->nextSameNodePtr) {
2123 	if (!strcmp(objectPtr->modulePtr->export.name, modulename)) {
2124 	    return (objectPtr);
2125 	}
2126     }
2127 
2128     return (NULL);
2129 }
2130 
2131 
2132 
2133 /*
2134  *----------------------------------------------------------------------
2135  *
2136  * findObjectByName --
2137  *
2138  *      Lookup an Object by a given name. Note, that
2139  *	there might be more than one Object with the same name.
2140  *	In this case, it is undefined which Object is returned.
2141  *
2142  * Results:
2143  *      A pointer to the Object structure or
2144  *	NULL if it is not found.
2145  *
2146  * Side effects:
2147  *      None.
2148  *
2149  *----------------------------------------------------------------------
2150  */
2151 
findObjectByName(const char * objectname)2152 Object *findObjectByName(const char *objectname)
2153 {
2154     Module	     *modulePtr;
2155     Object           *objectPtr;
2156 
2157     for (modulePtr = smiHandle->firstModulePtr; modulePtr;
2158 	 modulePtr = modulePtr->nextPtr) {
2159 	for (objectPtr = modulePtr->firstObjectPtr; objectPtr;
2160 	     objectPtr = objectPtr->nextPtr) {
2161 	    if ((objectPtr->export.name) &&
2162 		!strcmp(objectPtr->export.name, objectname)) {
2163 		/*
2164 		 * We return the first matching object.
2165 		 * TODO: probably we should check if there are more matching
2166 		 *       objects, and give a warning if there's another one.
2167 		 */
2168 		return (objectPtr);
2169 	    }
2170 	}
2171     }
2172 
2173     return (NULL);
2174 }
2175 
2176 
2177 
2178 /*
2179  *----------------------------------------------------------------------
2180  *
2181  * findNextObjectByName --
2182  *
2183  *      Lookup the next Object by a given name. Note, that
2184  *	there might be more than one Object with the same name.
2185  *
2186  * Results:
2187  *      A pointer to the Object structure or
2188  *	NULL if it is not found.
2189  *
2190  * Side effects:
2191  *      None.
2192  *
2193  *----------------------------------------------------------------------
2194  */
2195 
findNextObjectByName(const char * objectname,Object * prevObjectPtr)2196 Object *findNextObjectByName(const char *objectname, Object *prevObjectPtr)
2197 {
2198     Module	     *modulePtr;
2199     Object           *objectPtr;
2200 
2201     for (modulePtr = prevObjectPtr->modulePtr->nextPtr; modulePtr;
2202 	 modulePtr = modulePtr->nextPtr) {
2203 	for (objectPtr = modulePtr->firstObjectPtr; objectPtr;
2204 	     objectPtr = objectPtr->nextPtr) {
2205 	    if ((objectPtr->export.name)
2206 		&& !strcmp(objectPtr->export.name, objectname)) {
2207 		/*
2208 		 * We return the first matching object.
2209 		 * TODO: probably we should check if there are more matching
2210 		 *       objects, and give a warning if there's another one.
2211 		 */
2212 		return (objectPtr);
2213 	    }
2214 	}
2215     }
2216 
2217     return (NULL);
2218 }
2219 
2220 
2221 
2222 /*
2223  *----------------------------------------------------------------------
2224  *
2225  * findObjectByModulenameAndName --
2226  *
2227  *      Lookup a Object by a given Module and name.
2228  *
2229  * Results:
2230  *      A pointer to the Object structure or
2231  *	NULL if it is not found.
2232  *
2233  * Side effects:
2234  *      None.
2235  *
2236  *----------------------------------------------------------------------
2237  */
2238 
findObjectByModulenameAndName(const char * modulename,const char * objectname)2239 Object *findObjectByModulenameAndName(const char *modulename,
2240 				      const char *objectname)
2241 {
2242     Module	     *modulePtr;
2243     Object	     *objectPtr;
2244 
2245     modulePtr = findModuleByName(modulename);
2246 
2247     if (modulePtr) {
2248 	for (objectPtr = modulePtr->firstObjectPtr; objectPtr;
2249 	     objectPtr = objectPtr->nextPtr) {
2250 	    if ((objectPtr->export.name) &&
2251 		!strcmp(objectPtr->export.name, objectname)) {
2252 		return (objectPtr);
2253 	    }
2254 	}
2255     }
2256 
2257     /*
2258      * Some toplevel Objects seem to be always known.
2259      */
2260     if ((!strcmp(objectname, "iso")) ||
2261 	(!strcmp(objectname, "ccitt")) ||
2262 	(!strcmp(objectname, "joint-iso-ccitt"))) {
2263 	return findObjectByName(objectname);
2264     }
2265 
2266     return (NULL);
2267 }
2268 
2269 
2270 
2271 /*
2272  *----------------------------------------------------------------------
2273  *
2274  * findObjectByModuleAndName --
2275  *
2276  *      Lookup a Object by a given Module and name.
2277  *
2278  * Results:
2279  *      A pointer to the Object structure or
2280  *	NULL if it is not found.
2281  *
2282  * Side effects:
2283  *      None.
2284  *
2285  *----------------------------------------------------------------------
2286  */
2287 
findObjectByModuleAndName(Module * modulePtr,const char * objectname)2288 Object *findObjectByModuleAndName(Module *modulePtr, const char *objectname)
2289 {
2290     Object	  *objectPtr;
2291 
2292     if (! objectname) {
2293 	return NULL;
2294     }
2295 
2296     if (modulePtr) {
2297 	for (objectPtr = modulePtr->firstObjectPtr; objectPtr;
2298 	     objectPtr = objectPtr->nextPtr) {
2299 	    if ((objectPtr->export.name) &&
2300 		!strcmp(objectPtr->export.name, objectname)) {
2301 		return (objectPtr);
2302 	    }
2303 	}
2304     }
2305 
2306     /*
2307      * Some toplevel Objects seem to be always known.
2308      */
2309     if ((!strcmp(objectname, "iso")) ||
2310 	(!strcmp(objectname, "ccitt")) ||
2311 	(!strcmp(objectname, "joint-iso-ccitt"))) {
2312 	return findObjectByName(objectname);
2313     }
2314 
2315     return (NULL);
2316 }
2317 
2318 
2319 
2320 /*
2321  *----------------------------------------------------------------------
2322  *
2323  * addType --
2324  *
2325  *      Create a new Type structure.
2326  *
2327  * Results:
2328  *      A pointer to the new Type structure or
2329  *	NULL if terminated due to an error.
2330  *
2331  * Side effects:
2332  *      None.
2333  *
2334  *----------------------------------------------------------------------
2335  */
2336 
addType(char * type_name,SmiBasetype basetype,TypeFlags flags,Parser * parserPtr)2337 Type *addType(char *type_name, SmiBasetype basetype, TypeFlags flags,
2338 	      Parser *parserPtr)
2339 {
2340     Type	   *typePtr;
2341     Module	   *modulePtr;
2342 
2343     modulePtr = parserPtr ? parserPtr->modulePtr : NULL;
2344 
2345     typePtr = smiMalloc(sizeof(Type));
2346 
2347     typePtr->export.name	        = type_name;
2348     typePtr->export.basetype		= basetype;
2349     typePtr->export.decl		= SMI_DECL_UNKNOWN;
2350     typePtr->export.format		= NULL;
2351     typePtr->export.value.basetype	= SMI_BASETYPE_UNKNOWN;
2352     typePtr->export.units		= NULL;
2353     typePtr->export.status		= SMI_STATUS_UNKNOWN;
2354     typePtr->export.description		= NULL;
2355     typePtr->export.reference		= NULL;
2356 
2357     typePtr->modulePtr			= modulePtr;
2358     typePtr->listPtr			= NULL;
2359     typePtr->flags			= flags;
2360     typePtr->parentPtr                  = NULL;
2361     typePtr->line			= parserPtr ? parserPtr->line : -1;
2362 
2363     typePtr->nextPtr			= NULL;
2364     if (modulePtr) {
2365 	typePtr->prevPtr		= modulePtr->lastTypePtr;
2366 	if (!modulePtr->firstTypePtr)
2367 	    modulePtr->firstTypePtr	= typePtr;
2368 	if (modulePtr->lastTypePtr)
2369 	    modulePtr->lastTypePtr->nextPtr = typePtr;
2370 	modulePtr->lastTypePtr		= typePtr;
2371     } else {
2372 	typePtr->prevPtr		= NULL;
2373     }
2374 
2375     return (typePtr);
2376 }
2377 
2378 
2379 
2380 /*
2381  *----------------------------------------------------------------------
2382  *
2383  * duplicateType --
2384  *
2385  *      Create a new Type as a duplicate of a given one but with
2386  *      an affiliation to the current module.
2387  *
2388  * Results:
2389  *      A pointer to the new Type structure or
2390  *	NULL if terminated due to an error.
2391  *
2392  * Side effects:
2393  *      None.
2394  *
2395  *----------------------------------------------------------------------
2396  */
2397 
duplicateType(Type * templatePtr,TypeFlags flags,Parser * parserPtr)2398 Type *duplicateType(Type *templatePtr, TypeFlags flags, Parser *parserPtr)
2399 {
2400     Type		  *typePtr;
2401     Module		  *modulePtr;
2402 
2403     typePtr = (Type *) smiMalloc(sizeof(Type));
2404 
2405     modulePtr = parserPtr->modulePtr;
2406 
2407     typePtr->export.name	        = NULL;
2408     typePtr->export.basetype		= templatePtr->export.basetype;
2409     typePtr->export.decl		= SMI_DECL_IMPLICIT_TYPE;
2410     typePtr->export.format		= NULL;
2411     typePtr->export.value.basetype	= SMI_BASETYPE_UNKNOWN;
2412     typePtr->export.units		= NULL;
2413     typePtr->export.status		= templatePtr->export.status;
2414     typePtr->export.description		= NULL;
2415     typePtr->export.reference		= NULL;
2416 
2417     typePtr->modulePtr			= modulePtr;
2418     typePtr->listPtr			= NULL;
2419     typePtr->flags			= templatePtr->flags;
2420     typePtr->line			= parserPtr ? parserPtr->line : -1;
2421 
2422     typePtr->nextPtr			= NULL;
2423     typePtr->prevPtr			= modulePtr->lastTypePtr;
2424     if (!modulePtr->firstTypePtr)
2425 	modulePtr->firstTypePtr		= typePtr;
2426     if (modulePtr->lastTypePtr)
2427 	modulePtr->lastTypePtr->nextPtr	= typePtr;
2428     modulePtr->lastTypePtr		= typePtr;
2429 
2430     setTypeParent(typePtr, templatePtr);
2431 
2432     return (typePtr);
2433 }
2434 
2435 
2436 
2437 /*
2438  *----------------------------------------------------------------------
2439  *
2440  * setTypeName --
2441  *
2442  *      Set the name of a given Type. If it already exists, merge the
2443  *	two types.
2444  *
2445  * Results:
2446  *	None.
2447  *
2448  * Side effects:
2449  *      None.
2450  *
2451  *----------------------------------------------------------------------
2452  */
2453 
setTypeName(Type * typePtr,char * name)2454 Type *setTypeName(Type *typePtr, char *name)
2455 {
2456     Type              *type2Ptr;
2457     List	      *listPtr;
2458 
2459     if (typePtr->export.name) {
2460 	smiFree(typePtr->export.name);
2461     }
2462     typePtr->export.name = smiStrdup(name);
2463 
2464     if (! typePtr->export.name) {
2465 	return typePtr;
2466     }
2467 
2468     /*
2469      * If a type with this name already exists, it must be a forward
2470      * reference and both types have to be merged.
2471      */
2472     for (type2Ptr = typePtr->modulePtr->firstTypePtr; type2Ptr;
2473 	 type2Ptr = type2Ptr->nextPtr) {
2474 
2475 	if (type2Ptr->export.name &&
2476 	    (!strcmp(type2Ptr->export.name, name)) &&
2477 	    (type2Ptr != typePtr)) {
2478 
2479 	    /*
2480 	     * remove typePtr from the type list.
2481 	     */
2482 	    if (typePtr->prevPtr) {
2483 		typePtr->prevPtr->nextPtr = typePtr->nextPtr;
2484 	    } else {
2485 		typePtr->modulePtr->firstTypePtr = typePtr->nextPtr;
2486 	    }
2487 	    if (typePtr->nextPtr) {
2488 		typePtr->nextPtr->prevPtr = typePtr->prevPtr;
2489 	    } else {
2490 		typePtr->modulePtr->lastTypePtr = typePtr->prevPtr;
2491 	    }
2492 
2493 	    type2Ptr->export.basetype     = typePtr->export.basetype;
2494 	    type2Ptr->export.decl         = typePtr->export.decl;
2495 	    type2Ptr->export.format       = typePtr->export.format;
2496 	    type2Ptr->export.value        = typePtr->export.value;
2497 	    type2Ptr->export.units        = typePtr->export.units;
2498 	    type2Ptr->export.status       = typePtr->export.status;
2499 	    type2Ptr->export.description  = typePtr->export.description;
2500 	    type2Ptr->export.reference    = typePtr->export.reference;
2501 
2502 	    type2Ptr->parentPtr    = typePtr->parentPtr;
2503 	    type2Ptr->listPtr      = typePtr->listPtr;
2504 	    type2Ptr->flags        = typePtr->flags;
2505 	    type2Ptr->line         = typePtr->line;
2506 
2507 	    /*
2508 	     * if it's an enum or bits type, we also have to adjust
2509 	     * the references from the named numbers back to the type.
2510 	     */
2511 	    if ((type2Ptr->export.basetype == SMI_BASETYPE_ENUM) ||
2512 		(type2Ptr->export.basetype == SMI_BASETYPE_BITS)) {
2513 		for (listPtr = type2Ptr->listPtr; listPtr;
2514 		     listPtr = listPtr->nextPtr) {
2515 		    ((NamedNumber *)(listPtr->ptr))->typePtr = type2Ptr;
2516 		}
2517 	    }
2518 
2519 	    smiFree(typePtr->export.name);
2520 	    smiFree(typePtr);
2521 
2522 	    return type2Ptr;
2523 	}
2524     }
2525     return typePtr;
2526 }
2527 
2528 
2529 
2530 /*
2531  *----------------------------------------------------------------------
2532  *
2533  * setTypeParent --
2534  *
2535  *      Set the parent of a given Type.
2536  *
2537  * Results:
2538  *	None.
2539  *
2540  * Side effects:
2541  *      None.
2542  *
2543  *----------------------------------------------------------------------
2544  */
2545 
setTypeParent(Type * typePtr,Type * parentPtr)2546 void setTypeParent(Type *typePtr, Type *parentPtr)
2547 {
2548     typePtr->parentPtr = parentPtr;
2549 }
2550 
2551 
2552 
2553 /*
2554  *----------------------------------------------------------------------
2555  *
2556  * setTypeStatus --
2557  *
2558  *      Set the status of a given Type.
2559  *
2560  * Results:
2561  *	None.
2562  *
2563  * Side effects:
2564  *      None.
2565  *
2566  *----------------------------------------------------------------------
2567  */
2568 
setTypeStatus(Type * typePtr,SmiStatus status)2569 void setTypeStatus(Type *typePtr, SmiStatus status)
2570 {
2571     typePtr->export.status = status;
2572 }
2573 
2574 
2575 
2576 /*
2577  *----------------------------------------------------------------------
2578  *
2579  * setTypeBasetype --
2580  *
2581  *      Set the basetype of a given Type.
2582  *
2583  * Results:
2584  *	None.
2585  *
2586  * Side effects:
2587  *      None.
2588  *
2589  *----------------------------------------------------------------------
2590  */
2591 
setTypeBasetype(Type * typePtr,SmiBasetype basetype)2592 void setTypeBasetype(Type *typePtr, SmiBasetype basetype)
2593 {
2594     typePtr->export.basetype = basetype;
2595 }
2596 
2597 
2598 
2599 /*
2600  *----------------------------------------------------------------------
2601  *
2602  * setTypeDescription --
2603  *
2604  *      Set the description of a given Type.
2605  *
2606  * Results:
2607  *	None.
2608  *
2609  * Side effects:
2610  *      None.
2611  *
2612  *----------------------------------------------------------------------
2613  */
2614 
setTypeDescription(Type * typePtr,char * description,Parser * parserPtr)2615 void setTypeDescription(Type *typePtr, char *description, Parser *parserPtr)
2616 {
2617     if (typePtr->export.description)
2618 	smiFree(typePtr->export.description);
2619     if (parserPtr->flags & SMI_FLAG_NODESCR) {
2620 	smiFree(description);
2621 	typePtr->export.description = NULL;
2622     } else {
2623 	typePtr->export.description = description;
2624     }
2625 }
2626 
2627 
2628 
2629 /*
2630  *----------------------------------------------------------------------
2631  *
2632  * setTypeReference --
2633  *
2634  *      Set the reference of a given Type.
2635  *
2636  * Results:
2637  *	None.
2638  *
2639  * Side effects:
2640  *      None.
2641  *
2642  *----------------------------------------------------------------------
2643  */
2644 
setTypeReference(Type * typePtr,char * reference,Parser * parserPtr)2645 void setTypeReference(Type *typePtr, char *reference, Parser *parserPtr)
2646 {
2647     if (typePtr->export.reference)
2648 	smiFree(typePtr->export.reference);
2649     if (parserPtr->flags & SMI_FLAG_NODESCR) {
2650 	smiFree(reference);
2651 	typePtr->export.reference = NULL;
2652     } else {
2653 	typePtr->export.reference = reference;
2654     }
2655 }
2656 
2657 
2658 
2659 /*
2660  *----------------------------------------------------------------------
2661  *
2662  * setTypeList --
2663  *
2664  *      Set the pointer to a struct list. This used for
2665  *	- columns of a SEQUENCE type,
2666  *	- enumeration items of an enumeration integer type,
2667  *	- min-max pair items of a range restricted type,
2668  *	- min-max pars items of a size restricted type.
2669  *
2670  * Results:
2671  *	None.
2672  *
2673  * Side effects:
2674  *      None.
2675  *
2676  *----------------------------------------------------------------------
2677  */
2678 
setTypeList(Type * typePtr,List * listPtr)2679 void setTypeList(Type *typePtr, List *listPtr)
2680 {
2681     if (!typePtr->listPtr) {
2682 	typePtr->listPtr  = listPtr;
2683     }
2684 }
2685 
2686 
2687 
2688 /*
2689  *----------------------------------------------------------------------
2690  *
2691  * setTypeFormat --
2692  *
2693  *      Set the format (displayHint) of a given Type.
2694  *
2695  * Results:
2696  *	None.
2697  *
2698  * Side effects:
2699  *      None.
2700  *
2701  *----------------------------------------------------------------------
2702  */
2703 
setTypeFormat(Type * typePtr,char * format)2704 void setTypeFormat(Type *typePtr, char *format)
2705 {
2706     if (typePtr->export.format) smiFree(typePtr->export.format);
2707     typePtr->export.format = format;
2708 }
2709 
2710 
2711 
2712 /*
2713  *----------------------------------------------------------------------
2714  *
2715  * setTypeUnits --
2716  *
2717  *      Set the units of a given Type. Note: units of types are only
2718  *	present in SMIng, not in SMIv2.
2719  *
2720  * Results:
2721  *	None.
2722  *
2723  * Side effects:
2724  *      None.
2725  *
2726  *----------------------------------------------------------------------
2727  */
2728 
setTypeUnits(Type * typePtr,char * units)2729 void setTypeUnits(Type *typePtr, char *units)
2730 {
2731     if (typePtr->export.units) smiFree(typePtr->export.units);
2732     typePtr->export.units = units;
2733 }
2734 
2735 
2736 
2737 /*
2738  *----------------------------------------------------------------------
2739  *
2740  * setTypeDecl --
2741  *
2742  *      Set the declaring macro of a given Type.
2743  *
2744  * Results:
2745  *	None.
2746  *
2747  * Side effects:
2748  *      None.
2749  *
2750  *----------------------------------------------------------------------
2751  */
2752 
setTypeDecl(Type * typePtr,SmiDecl decl)2753 void setTypeDecl(Type *typePtr, SmiDecl decl)
2754 {
2755     typePtr->export.decl = decl;
2756 }
2757 
2758 
2759 
2760 /*
2761  *----------------------------------------------------------------------
2762  *
2763  * setTypeLine --
2764  *
2765  *      Set the line of definition of a given Type.
2766  *
2767  * Results:
2768  *	None.
2769  *
2770  * Side effects:
2771  *      None.
2772  *
2773  *----------------------------------------------------------------------
2774  */
2775 
setTypeLine(Type * typePtr,int line,Parser * parserPtr)2776 void setTypeLine(Type *typePtr, int line, Parser *parserPtr)
2777 {
2778     if (line) {
2779 	typePtr->line = line;
2780     } else {
2781 	typePtr->line = parserPtr ? parserPtr->line : -1;
2782     }
2783 }
2784 
2785 
2786 
2787 /*
2788  *----------------------------------------------------------------------
2789  *
2790  * setTypeValue --
2791  *
2792  *      Set the default value pointer of a given Type.
2793  *
2794  * Results:
2795  *	None.
2796  *
2797  * Side effects:
2798  *      None.
2799  *
2800  *----------------------------------------------------------------------
2801  */
2802 
setTypeValue(Type * typePtr,SmiValue * valuePtr)2803 void setTypeValue(Type *typePtr, SmiValue *valuePtr)
2804 {
2805     typePtr->export.value = *valuePtr;
2806 }
2807 
2808 
2809 
2810 /*
2811  *----------------------------------------------------------------------
2812  *
2813  * addTypeFlags --
2814  *
2815  *      Add flags to the flags of a given Type.
2816  *
2817  * Results:
2818  *	None.
2819  *
2820  * Side effects:
2821  *      None.
2822  *
2823  *----------------------------------------------------------------------
2824  */
2825 
addTypeFlags(Type * typePtr,TypeFlags flags)2826 void addTypeFlags(Type *typePtr, TypeFlags flags)
2827 {
2828     typePtr->flags |= flags;
2829 }
2830 
2831 
2832 
2833 /*
2834  *----------------------------------------------------------------------
2835  *
2836  * deleteTypeFlags --
2837  *
2838  *      Delete flags from the flags of a given Type.
2839  *
2840  * Results:
2841  *	None.
2842  *
2843  * Side effects:
2844  *      None.
2845  *
2846  *----------------------------------------------------------------------
2847  */
2848 
deleteTypeFlags(Type * typePtr,TypeFlags flags)2849 void deleteTypeFlags(Type *typePtr, TypeFlags flags)
2850 {
2851     typePtr->flags &= ~flags;
2852 }
2853 
2854 
2855 
2856 /*
2857  *----------------------------------------------------------------------
2858  *
2859  * findTypeByName --
2860  *
2861  *      Lookup a Type by a given name.
2862  *
2863  * Results:
2864  *      A pointer to the Type structure or
2865  *	NULL if it is not found.
2866  *
2867  * Side effects:
2868  *      None.
2869  *
2870  *----------------------------------------------------------------------
2871  */
2872 
findTypeByName(const char * type_name)2873 Type * findTypeByName(const char *type_name)
2874 {
2875     Module *modulePtr;
2876     Type   *typePtr;
2877 
2878     for (modulePtr = smiHandle->firstModulePtr; modulePtr;
2879 	 modulePtr = modulePtr->nextPtr) {
2880 	for (typePtr = modulePtr->firstTypePtr; typePtr;
2881 	     typePtr = typePtr->nextPtr) {
2882 	    if ((typePtr->export.name) &&
2883 		!strcmp(typePtr->export.name, type_name)) {
2884 		return (typePtr);
2885 	    }
2886 	}
2887     }
2888 
2889     return (NULL);
2890 }
2891 
2892 
2893 
2894 /*
2895  *----------------------------------------------------------------------
2896  *
2897  * findNextTypeByName --
2898  *
2899  *      Lookup the next Type by a given name.
2900  *
2901  * Results:
2902  *      A pointer to the Type structure or
2903  *	NULL if it is not found.
2904  *
2905  * Side effects:
2906  *      None.
2907  *
2908  *----------------------------------------------------------------------
2909  */
2910 
findNextTypeByName(const char * type_name,Type * prevTypePtr)2911 Type *findNextTypeByName(const char *type_name, Type *prevTypePtr)
2912 {
2913     Module *modulePtr;
2914     Type   *typePtr;
2915 
2916     for (modulePtr = prevTypePtr->modulePtr->nextPtr; modulePtr;
2917 	 modulePtr = modulePtr->nextPtr) {
2918 	for (typePtr = modulePtr->firstTypePtr; typePtr;
2919 	     typePtr = typePtr->nextPtr) {
2920 	    if ((typePtr->export.name) &&
2921 		!strcmp(typePtr->export.name, type_name)) {
2922 		return (typePtr);
2923 	    }
2924 	}
2925     }
2926 
2927     return (NULL);
2928 }
2929 
2930 
2931 
2932 /*
2933  *----------------------------------------------------------------------
2934  *
2935  * findTypeByModulenameAndName --
2936  *
2937  *      Lookup a Type by a given Module and name.
2938  *
2939  * Results:
2940  *      A pointer to the Type structure or
2941  *	NULL if it is not found.
2942  *
2943  * Side effects:
2944  *      None.
2945  *
2946  *----------------------------------------------------------------------
2947  */
2948 
findTypeByModulenameAndName(const char * modulename,const char * type_name)2949 Type *findTypeByModulenameAndName(const char *modulename,
2950 				  const char *type_name)
2951 {
2952     Type       *typePtr;
2953     Module     *modulePtr;
2954 
2955     modulePtr = findModuleByName(modulename);
2956 
2957     if (modulePtr) {
2958 	for (typePtr = modulePtr->firstTypePtr; typePtr;
2959 	     typePtr = typePtr->nextPtr) {
2960 	    if ((typePtr->export.name) && !strcmp(typePtr->export.name, type_name)) {
2961 		return (typePtr);
2962 	    }
2963 	}
2964     }
2965 
2966     return (NULL);
2967 }
2968 
2969 
2970 
2971 /*
2972  *----------------------------------------------------------------------
2973  *
2974  * findTypeByModuleAndName --
2975  *
2976  *      Lookup a Type by a given Module and name.
2977  *
2978  * Results:
2979  *      A pointer to the Type structure or
2980  *	NULL if it is not found.
2981  *
2982  * Side effects:
2983  *      None.
2984  *
2985  *----------------------------------------------------------------------
2986  */
2987 
findTypeByModuleAndName(Module * modulePtr,const char * type_name)2988 Type *findTypeByModuleAndName(Module *modulePtr, const char *type_name)
2989 {
2990     Type        *typePtr;
2991 
2992     if (modulePtr) {
2993 	for (typePtr = modulePtr->firstTypePtr; typePtr;
2994 	     typePtr = typePtr->nextPtr) {
2995 	    if ((typePtr->export.name) &&
2996 		!strcmp(typePtr->export.name, type_name)) {
2997 		return (typePtr);
2998 	    }
2999 	}
3000     }
3001 
3002     return (NULL);
3003 }
3004 
3005 
3006 
3007 /*
3008  *----------------------------------------------------------------------
3009  *
3010  * findTypeNamedNumber --
3011  *
3012  *
3013  *
3014  * Results:
3015  *
3016  * Side effects:
3017  *
3018  *---------------------------------------------------------------------- */
3019 
findTypeNamedNumber(Type * typePtr,SmiInteger32 number)3020 NamedNumber *findTypeNamedNumber(Type *typePtr,
3021 				 SmiInteger32 number)
3022 {
3023     List *listPtr;
3024 
3025     for (listPtr = typePtr->listPtr;
3026 	 listPtr; listPtr = listPtr->nextPtr) {
3027 	if (((NamedNumber *)(listPtr->ptr))->export.value.value.integer32 ==
3028 	    number)
3029 	    break;
3030     }
3031 
3032     return (NamedNumber *)(listPtr->ptr);
3033 }
3034 
3035 
3036 
3037 /*
3038  *----------------------------------------------------------------------
3039  *
3040  * addIdentity --
3041  *
3042  *      Create a new Identity structure.
3043  *
3044  * Results:
3045  *      A pointer to the new Identity structure or
3046  *	NULL if terminated due to an error.
3047  *
3048  * Side effects:
3049  *      None.
3050  *
3051  *---------------------------------------------------------------------- */
3052 
addIdentity(char * identityname,Parser * parserPtr)3053 Identity *addIdentity(char *identityname, Parser *parserPtr)
3054 {
3055 	Identity  *identityPtr;
3056     Module	  *modulePtr;
3057 
3058     modulePtr = parserPtr->modulePtr;
3059 
3060     identityPtr = (Identity*) smiMalloc(sizeof(Identity));
3061 
3062     identityPtr->export.name = identityname;
3063     identityPtr->export.status      = SMI_STATUS_UNKNOWN;
3064     identityPtr->export.description = NULL;
3065     identityPtr->export.reference   = NULL;
3066 	identityPtr->parentPtr   = NULL;
3067 
3068     identityPtr->modulePtr   	 	= parserPtr->modulePtr;
3069     identityPtr->line	  	 		= parserPtr ? parserPtr->line : -1;
3070 
3071     identityPtr->nextPtr			= NULL;
3072     identityPtr->prevPtr			= modulePtr->lastIdentityPtr;
3073     if (!modulePtr->firstIdentityPtr)
3074 		modulePtr->firstIdentityPtr	= identityPtr;
3075     if (modulePtr->lastIdentityPtr)
3076 		modulePtr->lastIdentityPtr->nextPtr	= identityPtr;
3077     modulePtr->lastIdentityPtr		= identityPtr;
3078 
3079     return (identityPtr);
3080 
3081 }
3082 
3083 /*
3084  *----------------------------------------------------------------------
3085  *
3086  * setIdentityDecl --
3087  *
3088  *      Set the declaring macro of a given Identity.
3089  *
3090  * Results:
3091  *	None.
3092  *
3093  * Side effects:
3094  *      None.
3095  *
3096  *----------------------------------------------------------------------
3097  */
3098 
setIdentityDecl(Identity * identityPtr,SmiDecl decl)3099 void setIdentityDecl(Identity *identityPtr, SmiDecl decl)
3100 {
3101     identityPtr->export.decl = decl;
3102 }
3103 
3104 /*
3105  *----------------------------------------------------------------------
3106  *
3107  * setIdentityStatus --
3108  *
3109  *      Set the status of a given Identity.
3110  *
3111  * Results:
3112  *	None.
3113  *
3114  * Side effects:
3115  *      None.
3116  *
3117  *----------------------------------------------------------------------
3118  */
3119 
setIdentityStatus(Identity * identityPtr,SmiStatus status)3120 void setIdentityStatus(Identity *identityPtr, SmiStatus status)
3121 {
3122     identityPtr->export.status = status;
3123 }
3124 
3125 
3126 
3127 /*
3128  *----------------------------------------------------------------------
3129  *
3130  * setIdentityDescription --
3131  *
3132  *      Set the description of a given Identity.
3133  *
3134  * Results:
3135  *	None.
3136  *
3137  * Side effects:
3138  *      None.
3139  *
3140  *----------------------------------------------------------------------
3141  */
3142 
setIdentityDescription(Identity * identityPtr,char * description,Parser * parserPtr)3143 void setIdentityDescription(Identity *identityPtr, char *description, Parser *parserPtr)
3144 {
3145     if (identityPtr->export.description) smiFree(identityPtr->export.description);
3146     if (parserPtr->flags & SMI_FLAG_NODESCR) {
3147 	smiFree(description);
3148 	identityPtr->export.description = NULL;
3149     } else {
3150 	identityPtr->export.description = description;
3151     }
3152 }
3153 
3154 
3155 
3156 /*
3157  *----------------------------------------------------------------------
3158  *
3159  * setIdentityReference --
3160  *
3161  *      Set the reference of a given Identity.
3162  *
3163  * Results:
3164  *	None.
3165  *
3166  * Side effects:
3167  *      None.
3168  *
3169  *----------------------------------------------------------------------
3170  */
3171 
setIdentityReference(Identity * identityPtr,char * reference,Parser * parserPtr)3172 void setIdentityReference(Identity *identityPtr, char *reference, Parser *parserPtr)
3173 {
3174     if (identityPtr->export.reference)
3175 	smiFree(identityPtr->export.reference);
3176     if (parserPtr->flags & SMI_FLAG_NODESCR) {
3177 	smiFree(reference);
3178 	identityPtr->export.reference = NULL;
3179     } else {
3180 	identityPtr->export.reference = reference;
3181     }
3182 }
3183 
3184 /*
3185  *----------------------------------------------------------------------
3186  *
3187  * setIdentityParent --
3188  *
3189  *      Set the parent of a given Identity to given Identity pointer.
3190  *
3191  * Results:
3192  *	None.
3193  *
3194  * Side effects:
3195  *      None.
3196  *
3197  *----------------------------------------------------------------------
3198  */
3199 
setIdentityParent(Identity * identityPtr,Identity * parentPtr)3200 void setIdentityParent(Identity *identityPtr, Identity *parentPtr)
3201 {
3202     if(identityPtr) identityPtr->parentPtr = parentPtr;
3203 }
3204 
3205 
3206 /*
3207  *----------------------------------------------------------------------
3208  *
3209  * findIdentityByName --
3210  *
3211  *      Lookup a Identity by a given name.
3212  *
3213  * Results:
3214  *      A pointer to the Identity structure or
3215  *	NULL if it is not found.
3216  *
3217  * Side effects:
3218  *      None.
3219  *
3220  *----------------------------------------------------------------------
3221  */
3222 
findIdentityByName(const char * identityname)3223 Identity *findIdentityByName(const char *identityname)
3224 {
3225     Module *modulePtr;
3226     Identity   *identityPtr;
3227 
3228     for (modulePtr = smiHandle->firstModulePtr; modulePtr;
3229 	 modulePtr = modulePtr->nextPtr) {
3230 	for (identityPtr = modulePtr->firstIdentityPtr; identityPtr;
3231 	     identityPtr = identityPtr->nextPtr) {
3232 	    if ((identityPtr->export.name) &&
3233 		!strcmp(identityPtr->export.name, identityname)) {
3234 		return (identityPtr);
3235 	    }
3236 	}
3237     }
3238 
3239     return (NULL);
3240 }
3241 
3242 /*
3243  *----------------------------------------------------------------------
3244  *
3245  * findIdentityByModuleAndName --
3246  *
3247  *      Lookup a Identity by a given name and Module.
3248  *
3249  * Results:
3250  *      A pointer to the Identity structure or
3251  *	NULL if it is not found.
3252  *
3253  * Side effects:
3254  *      None.
3255  *
3256  *----------------------------------------------------------------------
3257  */
3258 
findIdentityByModuleAndName(Module * modulePtr,const char * identityname)3259 Identity *findIdentityByModuleAndName(Module *modulePtr,
3260 									const char *identityname)
3261 {
3262     Identity   *identityPtr;
3263 
3264 
3265 	for (identityPtr = modulePtr->firstIdentityPtr; identityPtr;
3266 	     identityPtr = identityPtr->nextPtr) {
3267 	    if ((identityPtr->export.name) &&
3268 		!strcmp(identityPtr->export.name, identityname)) {
3269 		return (identityPtr);
3270 	    }
3271 	}
3272 
3273 
3274     return (NULL);
3275 }
3276 
3277 /*
3278  *----------------------------------------------------------------------
3279  *
3280  * findIdentityByModulenameAndName --
3281  *
3282  *      Lookup a Identity by a given Module and name.
3283  *
3284  * Results:
3285  *      A pointer to the Identity structure or
3286  *	NULL if it is not found.
3287  *
3288  * Side effects:
3289  *      None.
3290  *
3291  *----------------------------------------------------------------------
3292  */
3293 
findIdentityByModulenameAndName(const char * modulename,const char * identity_name)3294 Identity *findIdentityByModulenameAndName(const char *modulename,
3295 				  const char *identity_name)
3296 {
3297     Identity       *identityPtr;
3298     Module     *modulePtr;
3299 
3300     modulePtr = findModuleByName(modulename);
3301 
3302     if (modulePtr) {
3303 	for (identityPtr = modulePtr->firstIdentityPtr; identityPtr;
3304 	     identityPtr = identityPtr->nextPtr) {
3305 	    if ((identityPtr->export.name) && !strcmp(identityPtr->export.name, identity_name)) {
3306 		return (identityPtr);
3307 	    }
3308 	}
3309     }
3310 
3311     return (NULL);
3312 }
3313 
3314 
3315 
3316 /*
3317  *----------------------------------------------------------------------
3318  *
3319  * addClass --
3320  *
3321  *      Create a new Class structure.
3322  *
3323  * Results:
3324  *      A pointer to the new Class structure or
3325  *	NULL if terminated due to an error.
3326  *
3327  * Side effects:
3328  *      None.
3329  *
3330  *---------------------------------------------------------------------- */
3331 
addClass(char * classname,Parser * parserPtr)3332 Class *addClass(char *classname, Parser *parserPtr)
3333 {
3334 	Class  *classPtr;
3335     Module	  *modulePtr;
3336 
3337     modulePtr = parserPtr->modulePtr;
3338 
3339     classPtr = (Class*) smiMalloc(sizeof(Class));
3340 
3341     classPtr->export.name = classname;
3342     classPtr->export.status      = SMI_STATUS_UNKNOWN;
3343     classPtr->export.description = NULL;
3344     classPtr->export.reference   = NULL;
3345 
3346     classPtr->modulePtr   	 	= parserPtr->modulePtr;
3347     classPtr->line	  	 		= parserPtr ? parserPtr->line : -1;
3348 
3349     classPtr->parentPtr			= NULL;
3350     classPtr->firstAttributePtr = NULL;
3351     classPtr->lastAttributePtr  = NULL;
3352     classPtr->firstEventPtr 	= NULL;
3353     classPtr->lastEventPtr 		= NULL;
3354 
3355     classPtr->nextPtr			= NULL;
3356     classPtr->prevPtr			= modulePtr->lastClassPtr;
3357     if (!modulePtr->firstClassPtr)
3358 		modulePtr->firstClassPtr	= classPtr;
3359     if (modulePtr->lastClassPtr)
3360 		modulePtr->lastClassPtr->nextPtr	= classPtr;
3361     modulePtr->lastClassPtr		= classPtr;
3362 
3363     return (classPtr);
3364 
3365 }
3366 
3367 /*
3368  *----------------------------------------------------------------------
3369  *
3370  * setClassDecl --
3371  *
3372  *      Set the declaring macro of a given Class.
3373  *
3374  * Results:
3375  *	None.
3376  *
3377  * Side effects:
3378  *      None.
3379  *
3380  *----------------------------------------------------------------------
3381  */
3382 
setClassDecl(Class * classPtr,SmiDecl decl)3383 void setClassDecl(Class *classPtr, SmiDecl decl)
3384 {
3385     classPtr->export.decl = decl;
3386 }
3387 
3388 /*
3389  *----------------------------------------------------------------------
3390  *
3391  * setClassStatus --
3392  *
3393  *      Set the status of a given Class.
3394  *
3395  * Results:
3396  *	None.
3397  *
3398  * Side effects:
3399  *      None.
3400  *
3401  *----------------------------------------------------------------------
3402  */
3403 
setClassStatus(Class * classPtr,SmiStatus status)3404 void setClassStatus(Class *classPtr, SmiStatus status)
3405 {
3406     classPtr->export.status = status;
3407 }
3408 
3409 
3410 
3411 /*
3412  *----------------------------------------------------------------------
3413  *
3414  * setClassDescription --
3415  *
3416  *      Set the description of a given Class.
3417  *
3418  * Results:
3419  *	None.
3420  *
3421  * Side effects:
3422  *      None.
3423  *
3424  *----------------------------------------------------------------------
3425  */
3426 
setClassDescription(Class * classPtr,char * description,Parser * parserPtr)3427 void setClassDescription(Class *classPtr, char *description, Parser *parserPtr)
3428 {
3429     if (classPtr->export.description) smiFree(classPtr->export.description);
3430     if (parserPtr->flags & SMI_FLAG_NODESCR) {
3431 	smiFree(description);
3432 	classPtr->export.description = NULL;
3433     } else {
3434 	classPtr->export.description = description;
3435     }
3436 }
3437 
3438 
3439 
3440 /*
3441  *----------------------------------------------------------------------
3442  *
3443  * setClassReference --
3444  *
3445  *      Set the reference of a given Class.
3446  *
3447  * Results:
3448  *	None.
3449  *
3450  * Side effects:
3451  *      None.
3452  *
3453  *----------------------------------------------------------------------
3454  */
3455 
setClassReference(Class * classPtr,char * reference,Parser * parserPtr)3456 void setClassReference(Class *classPtr, char *reference, Parser *parserPtr)
3457 {
3458     if (classPtr->export.reference)
3459 	smiFree(classPtr->export.reference);
3460     if (parserPtr->flags & SMI_FLAG_NODESCR) {
3461 	smiFree(reference);
3462 	classPtr->export.reference = NULL;
3463     } else {
3464 	classPtr->export.reference = reference;
3465     }
3466 }
3467 
3468 /*
3469  *----------------------------------------------------------------------
3470  *
3471  * setClassParent --
3472  *
3473  *      Set the parent of a given Class to given Class pointer.
3474  *
3475  * Results:
3476  *	None.
3477  *
3478  * Side effects:
3479  *      None.
3480  *
3481  *----------------------------------------------------------------------
3482  */
3483 
setClassParent(Class * classPtr,Class * parentPtr)3484 void setClassParent(Class *classPtr, Class *parentPtr)
3485 {
3486     if(classPtr) classPtr->parentPtr = parentPtr;
3487 }
3488 
3489 /*
3490  *----------------------------------------------------------------------
3491  *
3492  * findClassByModuleAndName --
3493  *
3494  *      Lookup a Class by a given name.
3495  *
3496  * Results:
3497  *      A pointer to the Class structure or
3498  *	NULL if it is not found.
3499  *
3500  * Side effects:
3501  *      None.
3502  *
3503  *----------------------------------------------------------------------
3504  */
findClassByModuleAndName(Module * modulePtr,char * name)3505 Class *findClassByModuleAndName(Module *modulePtr,char *name)
3506 {
3507     Class   *classPtr;
3508 
3509 	for (classPtr = modulePtr->firstClassPtr; classPtr;
3510 	     classPtr = classPtr->nextPtr) {
3511 	    if ((classPtr->export.name) &&
3512 		!strcmp(classPtr->export.name, name)) {
3513 		return (classPtr);
3514 	    }
3515 	}
3516 
3517     return NULL;
3518 }
3519 
3520 /*
3521  *----------------------------------------------------------------------
3522  *
3523  * findClassByModulenameAndName --
3524  *
3525  *      Lookup a Class by a given Module and name.
3526  *
3527  * Results:
3528  *      A pointer to the Class structure or
3529  *	NULL if it is not found.
3530  *
3531  * Side effects:
3532  *      None.
3533  *
3534  *----------------------------------------------------------------------
3535  */
3536 
findClassByModulenameAndName(const char * modulename,const char * class_name)3537 Class *findClassByModulenameAndName(const char *modulename,
3538 				  const char *class_name)
3539 {
3540     Class       *classPtr;
3541     Module     *modulePtr;
3542 
3543     modulePtr = findModuleByName(modulename);
3544 
3545     if (modulePtr) {
3546 	for (classPtr = modulePtr->firstClassPtr; classPtr;
3547 	     classPtr = classPtr->nextPtr) {
3548 	    if ((classPtr->export.name) && !strcmp(classPtr->export.name, class_name)) {
3549 		return (classPtr);
3550 	    }
3551 	}
3552     }
3553 
3554     return (NULL);
3555 }
3556 
3557 /*
3558  *----------------------------------------------------------------------
3559  *
3560  * duplicateTypeToAttribute --
3561  *
3562  *      Create a new Attribute as a duplicate of a given type but with
3563  *      an affiliation to the given Class.
3564  *
3565  * Results:
3566  *      A pointer to the new Attribute structure or
3567  *	NULL if terminated due to an error.
3568  *
3569  * Side effects:
3570  *      None.
3571  *
3572  *----------------------------------------------------------------------
3573  */
3574 
duplicateTypeToAttribute(Type * templatePtr,Class * classPtr,Parser * parserPtr)3575 Attribute *duplicateTypeToAttribute(Type *templatePtr, Class *classPtr, Parser *parserPtr)
3576 {
3577     Attribute		  *attributePtr;
3578 
3579     if(!classPtr) return NULL;
3580 
3581     attributePtr = (Attribute *) smiMalloc(sizeof(Attribute));
3582 
3583 
3584     attributePtr->export.name	        = NULL;
3585     attributePtr->export.basetype		= templatePtr->export.basetype;
3586     attributePtr->export.decl		= SMI_DECL_ATTRIBUTE;
3587     attributePtr->export.format		= NULL;
3588     attributePtr->export.value.basetype	= templatePtr->export.basetype;
3589     attributePtr->export.units		= NULL;
3590     attributePtr->export.status		= templatePtr->export.status;
3591     attributePtr->export.description		= NULL;
3592     attributePtr->export.reference		= NULL;
3593 
3594     attributePtr->classPtr			= classPtr;
3595     attributePtr->listPtr			= NULL;
3596     attributePtr->line			= parserPtr ? parserPtr->line : -1;
3597 
3598     attributePtr->nextPtr			= NULL;
3599     attributePtr->prevPtr			= classPtr->lastAttributePtr;
3600     if (!classPtr->firstAttributePtr)
3601 	classPtr->firstAttributePtr		= attributePtr;
3602     if (classPtr->lastAttributePtr)
3603 	classPtr->lastAttributePtr->nextPtr	= attributePtr;
3604     classPtr->lastAttributePtr		= attributePtr;
3605 
3606     setAttributeParentType(attributePtr, templatePtr);
3607 
3608     return (attributePtr);
3609 }
3610 
3611 
3612 /*
3613  *----------------------------------------------------------------------
3614  *
3615  * addAttribute --
3616  *
3617  *      Create a new Attribute structure and tie it to the given Class.
3618  *
3619  * Results:
3620  *      A pointer to the new Attribute structure or
3621  *	NULL if terminated due to an error.
3622  *
3623  * Side effects:
3624  *      None.
3625  *
3626  *----------------------------------------------------------------------
3627  */
3628 
addAttribute(char * attribute_name,Class * classPtr,Parser * parserPtr)3629 Attribute *addAttribute(char *attribute_name,
3630 	      Class *classPtr, Parser *parserPtr)
3631 {
3632     Attribute	   *attributePtr;
3633 
3634     attributePtr = smiMalloc(sizeof(Attribute));
3635 
3636     attributePtr->export.name	        = attribute_name;
3637    	attributePtr->export.basetype		= SMI_BASETYPE_UNKNOWN;
3638     attributePtr->export.decl		= SMI_DECL_UNKNOWN;
3639     attributePtr->export.format		= NULL;
3640     attributePtr->export.value.basetype	= SMI_BASETYPE_UNKNOWN;
3641     attributePtr->export.units		= NULL;
3642     attributePtr->export.status		= SMI_STATUS_UNKNOWN;
3643     attributePtr->export.description		= NULL;
3644     attributePtr->export.reference		= NULL;
3645 
3646     attributePtr->classPtr			= classPtr;
3647     attributePtr->listPtr			= NULL;
3648     attributePtr->parentTypePtr     = NULL;
3649     attributePtr->parentClassPtr    = NULL;
3650     attributePtr->line			= parserPtr ? parserPtr->line : -1;
3651 
3652     attributePtr->nextPtr			= NULL;
3653     if (classPtr) {
3654 	attributePtr->prevPtr		= classPtr->lastAttributePtr;
3655 	if (!classPtr->firstAttributePtr)
3656 	    classPtr->firstAttributePtr	= attributePtr;
3657 	if (classPtr->lastAttributePtr)
3658 	    classPtr->lastAttributePtr->nextPtr = attributePtr;
3659 	classPtr->lastAttributePtr		= attributePtr;
3660     } else {
3661 	attributePtr->prevPtr		= NULL;
3662     }
3663 
3664     return (attributePtr);
3665 }
3666 
3667 /*
3668  *----------------------------------------------------------------------
3669  *
3670  * setAttributeDecl --
3671  *
3672  *      Set the declaring macro of a given Attribute.
3673  *
3674  * Results:
3675  *	None.
3676  *
3677  * Side effects:
3678  *      None.
3679  *
3680  *----------------------------------------------------------------------
3681  */
3682 
setAttributeDecl(Attribute * attributePtr,SmiDecl decl)3683 void setAttributeDecl(Attribute *attributePtr, SmiDecl decl)
3684 {
3685     attributePtr->export.decl = decl;
3686 }
3687 
3688 /*
3689  *----------------------------------------------------------------------
3690  *
3691  * setAttributeParentType --
3692  *
3693  *      Set the parent of a given attribute.
3694  *
3695  * Results:
3696  *	None.
3697  *
3698  * Side effects:
3699  *      None.
3700  *
3701  *----------------------------------------------------------------------
3702  */
3703 
setAttributeParentType(Attribute * attributePtr,Type * parentPtr)3704 void setAttributeParentType(Attribute *attributePtr, Type *parentPtr)
3705 {
3706     attributePtr->parentTypePtr = parentPtr;
3707 }
3708 
3709 /*
3710  *----------------------------------------------------------------------
3711  *
3712  * setAttributeParentClass --
3713  *
3714  *      Set the parent Class of a given attribute.
3715  *
3716  * Results:
3717  *	None.
3718  *
3719  * Side effects:
3720  *      None.
3721  *
3722  *----------------------------------------------------------------------
3723  */
3724 
setAttributeParentClass(Attribute * attributePtr,Class * parentPtr)3725 void setAttributeParentClass(Attribute *attributePtr, Class *parentPtr)
3726 {
3727     attributePtr->parentClassPtr = parentPtr;
3728 }
3729 
3730 /*
3731  *----------------------------------------------------------------------
3732  *
3733  * setAttributeList --
3734  *
3735  *      Set the pointer to a struct list. This used for
3736  *	- enumeration items of an enumeration integer type,
3737  *	- min-max pair items of a range restricted type,
3738  *	- min-max pars items of a size restricted type.
3739  *
3740  * Results:
3741  *	None.
3742  *
3743  * Side effects:
3744  *      None.
3745  *
3746  *----------------------------------------------------------------------
3747  */
3748 
setAttributeList(Attribute * attributePtr,List * listPtr)3749 void setAttributeList(Attribute *attributePtr, List *listPtr)
3750 {
3751     if (!attributePtr->listPtr) {
3752 	attributePtr->listPtr  = listPtr;
3753     }
3754 }
3755 
3756 /*
3757  *----------------------------------------------------------------------
3758  *
3759  * setAttributeName --
3760  *
3761  *      Set the name of a given Attribute.
3762  *
3763  * Results:
3764  *	None.
3765  *
3766  * Side effects:
3767  *      None.
3768  *
3769  *----------------------------------------------------------------------
3770  */
3771 
setAttributeName(Attribute * attributePtr,char * name)3772 void setAttributeName(Attribute *attributePtr, char *name)
3773 {
3774 
3775     attributePtr->export.name = smiStrdup(name);
3776 }
3777 
3778 /*
3779  *----------------------------------------------------------------------
3780  *
3781  * setAttributeAccess --
3782  *
3783  *      Set the access of a given Attribute.
3784  *
3785  * Results:
3786  *	None.
3787  *
3788  * Side effects:
3789  *      None.
3790  *
3791  *----------------------------------------------------------------------
3792  */
setAttributeAccess(Attribute * attributePtr,SmiAccess access)3793 void setAttributeAccess(Attribute *attributePtr,SmiAccess access)
3794 {
3795 	attributePtr->export.access = access;
3796 }
3797 
3798 
3799 /*
3800  *----------------------------------------------------------------------
3801  *
3802  * addEvent --
3803  *
3804  *      Create a new Event structure and tie it to the given Class.
3805  *
3806  * Results:
3807  *      A pointer to the new Event structure or
3808  *	NULL if terminated due to an error.
3809  *
3810  * Side effects:
3811  *      None.
3812  *
3813  *----------------------------------------------------------------------
3814  */
addEvent(char * eventname,Class * classPtr,Parser * parserPtr)3815 Event *addEvent(char *eventname, Class *classPtr,
3816 		             Parser *parserPtr)
3817 {
3818     Event	   *eventPtr;
3819 
3820    eventPtr = smiMalloc(sizeof(Event));
3821 
3822    	eventPtr->export.name	    = eventname;
3823     eventPtr->export.decl		= SMI_DECL_EVENT;
3824     eventPtr->export.status	= SMI_STATUS_UNKNOWN;
3825     eventPtr->export.description		= NULL;
3826     eventPtr->export.reference		= NULL;
3827 
3828     eventPtr->classPtr			= classPtr;
3829     eventPtr->line			= parserPtr ? parserPtr->line : -1;
3830 
3831     eventPtr->nextPtr			= NULL;
3832     if (classPtr) {
3833 	eventPtr->prevPtr		= classPtr->lastEventPtr;
3834 	if (!classPtr->firstEventPtr)
3835 	    classPtr->firstEventPtr	= eventPtr;
3836 	if (classPtr->lastEventPtr)
3837 	    classPtr->lastEventPtr->nextPtr = eventPtr;
3838 	classPtr->lastEventPtr		= eventPtr;
3839     } else {
3840 	eventPtr->prevPtr		= NULL;
3841     }
3842 
3843     return (eventPtr);
3844 }
3845 
3846 
3847 
3848 /*
3849  *----------------------------------------------------------------------
3850  *
3851  * addMacro --
3852  *
3853  *      Create a new Macro structure.
3854  *
3855  * Results:
3856  *      A pointer to the new Macro structure or
3857  *	NULL if terminated due to an error.
3858  *
3859  * Side effects:
3860  *      None.
3861  *
3862  *---------------------------------------------------------------------- */
3863 
addMacro(char * macroname,MacroFlags flags,Parser * parserPtr)3864 Macro *addMacro(char *macroname, MacroFlags flags, Parser *parserPtr)
3865 {
3866     Macro	  *macroPtr;
3867     Module	  *modulePtr;
3868 
3869     modulePtr = parserPtr->modulePtr;
3870 
3871     /* TODO: Check wheather this macro already exists?? */
3872 
3873     macroPtr = (Macro *) smiMalloc(sizeof(Macro));
3874 
3875     macroPtr->export.name 	 = macroname;
3876     macroPtr->export.status      = SMI_STATUS_UNKNOWN;
3877     macroPtr->export.description = NULL;
3878     macroPtr->export.reference   = NULL;
3879 
3880     macroPtr->modulePtr   	 = parserPtr->modulePtr;
3881     macroPtr->flags       	 = flags;
3882     macroPtr->line	  	 = parserPtr ? parserPtr->line : -1;
3883 
3884     macroPtr->nextPtr				= NULL;
3885     macroPtr->prevPtr				= modulePtr->lastMacroPtr;
3886     if (!modulePtr->firstMacroPtr)
3887 	modulePtr->firstMacroPtr		= macroPtr;
3888     if (modulePtr->lastMacroPtr)
3889 	modulePtr->lastMacroPtr->nextPtr	= macroPtr;
3890     modulePtr->lastMacroPtr			= macroPtr;
3891 
3892     return (macroPtr);
3893 }
3894 
3895 
3896 
3897 /*
3898  *----------------------------------------------------------------------
3899  *
3900  * setMacroStatus --
3901  *
3902  *      Set the status of a given Macro.
3903  *
3904  * Results:
3905  *	None.
3906  *
3907  * Side effects:
3908  *      None.
3909  *
3910  *----------------------------------------------------------------------
3911  */
3912 
setMacroStatus(Macro * macroPtr,SmiStatus status)3913 void setMacroStatus(Macro *macroPtr, SmiStatus status)
3914 {
3915     macroPtr->export.status = status;
3916 }
3917 
3918 
3919 
3920 /*
3921  *----------------------------------------------------------------------
3922  *
3923  * setMacroDescription --
3924  *
3925  *      Set the description of a given Macro.
3926  *
3927  * Results:
3928  *	None.
3929  *
3930  * Side effects:
3931  *      None.
3932  *
3933  *----------------------------------------------------------------------
3934  */
3935 
setMacroDescription(Macro * macroPtr,char * description,Parser * parserPtr)3936 void setMacroDescription(Macro *macroPtr, char *description, Parser *parserPtr)
3937 {
3938     if (macroPtr->export.description) smiFree(macroPtr->export.description);
3939     if (parserPtr->flags & SMI_FLAG_NODESCR) {
3940 	smiFree(description);
3941 	macroPtr->export.description = NULL;
3942     } else {
3943 	macroPtr->export.description = description;
3944     }
3945 }
3946 
3947 
3948 
3949 /*
3950  *----------------------------------------------------------------------
3951  *
3952  * setMacroReference --
3953  *
3954  *      Set the reference of a given Macro.
3955  *
3956  * Results:
3957  *	None.
3958  *
3959  * Side effects:
3960  *      None.
3961  *
3962  *----------------------------------------------------------------------
3963  */
3964 
setMacroReference(Macro * macroPtr,char * reference,Parser * parserPtr)3965 void setMacroReference(Macro *macroPtr, char *reference, Parser *parserPtr)
3966 {
3967     if (macroPtr->export.reference)
3968 	smiFree(macroPtr->export.reference);
3969     if (parserPtr->flags & SMI_FLAG_NODESCR) {
3970 	smiFree(reference);
3971 	macroPtr->export.reference = NULL;
3972     } else {
3973 	macroPtr->export.reference = reference;
3974     }
3975 }
3976 
3977 /*
3978  *----------------------------------------------------------------------
3979  *
3980  * setMacroAbnf --
3981  *
3982  *      Set the abnf string of a given extension(SMIng only).
3983  *
3984  * Results:
3985  *	None.
3986  *
3987  * Side effects:
3988  *      None.
3989  *
3990  *----------------------------------------------------------------------
3991  */
3992 
setMacroAbnf(Macro * macroPtr,char * abnf,Parser * parserPtr)3993 void setMacroAbnf(Macro *macroPtr, char *abnf, Parser *parserPtr)
3994 {
3995     if (macroPtr->export.abnf)
3996 	smiFree(macroPtr->export.abnf);
3997     if (parserPtr->flags & SMI_FLAG_NODESCR) {
3998 	smiFree(abnf);
3999 	macroPtr->export.abnf = NULL;
4000     } else {
4001 	macroPtr->export.abnf = abnf;
4002     }
4003 }
4004 
4005 
4006 
4007 /*
4008  *----------------------------------------------------------------------
4009  *
4010  * setMacroDecl --
4011  *
4012  *      Set the declaring macro of a given Macro.
4013  *
4014  * Results:
4015  *	None.
4016  *
4017  * Side effects:
4018  *      None.
4019  *
4020  *----------------------------------------------------------------------
4021  */
4022 
setMacroDecl(Macro * macroPtr,SmiDecl decl)4023 void setMacroDecl(Macro *macroPtr, SmiDecl decl)
4024 {
4025     macroPtr->export.decl = decl;
4026 }
4027 
4028 
4029 
4030 /*
4031  *----------------------------------------------------------------------
4032  *
4033  * setMacroLine --
4034  *
4035  *      Set the line of definition of a given Macro.
4036  *
4037  * Results:
4038  *	None.
4039  *
4040  * Side effects:
4041  *      None.
4042  *
4043  *----------------------------------------------------------------------
4044  */
4045 
setMacroLine(Macro * macroPtr,int line,Parser * parserPtr)4046 void setMacroLine(Macro *macroPtr, int line, Parser *parserPtr)
4047 {
4048     if (line) {
4049 	macroPtr->line = line;
4050     } else {
4051 	macroPtr->line = parserPtr ? parserPtr->line : -1;
4052     }
4053 }
4054 
4055 
4056 
4057 /*
4058  *----------------------------------------------------------------------
4059  *
4060  * findMacroByName --
4061  *
4062  *      Lookup a Macro by a given name.
4063  *
4064  * Results:
4065  *      A pointer to the Macro structure or
4066  *	NULL if it is not found.
4067  *
4068  * Side effects:
4069  *      None.
4070  *
4071  *----------------------------------------------------------------------
4072  */
4073 
findMacroByName(const char * macroname)4074 Macro *findMacroByName(const char *macroname)
4075 {
4076     Module *modulePtr;
4077     Macro   *macroPtr;
4078 
4079     for (modulePtr = smiHandle->firstModulePtr; modulePtr;
4080 	 modulePtr = modulePtr->nextPtr) {
4081 	for (macroPtr = modulePtr->firstMacroPtr; macroPtr;
4082 	     macroPtr = macroPtr->nextPtr) {
4083 	    if ((macroPtr->export.name) &&
4084 		!strcmp(macroPtr->export.name, macroname)) {
4085 		return (macroPtr);
4086 	    }
4087 	}
4088     }
4089 
4090     return (NULL);
4091 }
4092 
4093 
4094 
4095 /*
4096  *----------------------------------------------------------------------
4097  *
4098  * findMacroByModuleAndName --
4099  *
4100  *      Lookup a Macro by a given Module and name.
4101  *
4102  * Results:
4103  *      A pointer to the Macro structure or
4104  *	NULL if it is not found.
4105  *
4106  * Side effects:
4107  *      None.
4108  *
4109  *----------------------------------------------------------------------
4110  */
4111 
findMacroByModuleAndName(Module * modulePtr,const char * macroname)4112 Macro *findMacroByModuleAndName(Module *modulePtr, const char *macroname)
4113 {
4114     Macro      *macroPtr;
4115 
4116     if (modulePtr) {
4117 	for (macroPtr = modulePtr->firstMacroPtr; macroPtr;
4118 	     macroPtr = macroPtr->nextPtr) {
4119 	    if (!strcmp(macroPtr->export.name, macroname)) {
4120 		return (macroPtr);
4121 	    }
4122 	}
4123     }
4124 
4125     return (NULL);
4126 }
4127 
4128 
4129 
4130 /*
4131  *----------------------------------------------------------------------
4132  *
4133  * findNamedNumberByName --
4134  *
4135  *      Lookup the value of a namev nuber in a given typ.
4136  *
4137  * Results:
4138  *      A pointer to the NamedNumber structure or
4139  *	NULL if it is not found.
4140  *
4141  * Side effects:
4142  *      None.
4143  *
4144  *----------------------------------------------------------------------
4145  */
4146 
findNamedNumberByName(Type * typePtr,const char * name)4147 NamedNumber *findNamedNumberByName(Type *typePtr,const char *name)
4148 {
4149 	List *listPtr;
4150 
4151     if(typePtr->export.basetype != SMI_BASETYPE_ENUM &&
4152     	typePtr->export.basetype != SMI_BASETYPE_BITS) return NULL;
4153 
4154     for (listPtr = typePtr->listPtr;
4155 	 listPtr; listPtr = listPtr->nextPtr) {
4156 	if (!strcmp(((NamedNumber *)(listPtr->ptr))->export.name
4157 	    , name))
4158 	    return (NamedNumber *)(listPtr->ptr);
4159     }
4160 
4161     return NULL;
4162 }
4163 
4164 
4165 
4166 
4167 
4168 /*
4169  *----------------------------------------------------------------------
4170  *
4171  * smiInitData --
4172  *
4173  *      Initialize all need data structures at program start.
4174  *
4175  * Results:
4176  *      0 on success or -1 on an error.
4177  *
4178  * Side effects:
4179  *      None.
4180  *
4181  *----------------------------------------------------------------------
4182  */
4183 
smiInitData()4184 int smiInitData()
4185 {
4186     Object	    *objectPtr;
4187     Parser	    parser;
4188 
4189     smiHandle->flags = 0;
4190 
4191     smiHandle->firstModulePtr = NULL;
4192     smiHandle->lastModulePtr = NULL;
4193     smiHandle->firstViewPtr = NULL;
4194     smiHandle->lastViewPtr = NULL;
4195 
4196     /*
4197      * Initialize a root Node for the main MIB tree.
4198      */
4199     smiHandle->rootNodePtr = addNode(NULL, 0, NODE_FLAG_ROOT, NULL);
4200 
4201     /*
4202      * Initialize a root Node for pending (forward referenced) nodes.
4203      */
4204     smiHandle->parserPtr = &parser;
4205     parser.pendingNodePtr = addNode(NULL, 0, NODE_FLAG_ROOT, NULL);
4206 
4207     /*
4208      * Initialize the top level well-known nodes, ccitt, iso, joint-iso-ccitt
4209      * belonging to a dummy module "". This is needed for SMIv1/v2. SMIng
4210      * defines it in a special SMIng module.
4211      */
4212     parser.path			= NULL;
4213     parser.flags		= smiHandle->flags;
4214     parser.file			= NULL;
4215     parser.line			= -1;
4216     parser.modulePtr = addModule(smiStrdup(""), smiStrdup(""), 0, NULL);
4217 
4218     addView("");
4219 
4220     objectPtr = addObject(smiStrdup("ccitt"), smiHandle->rootNodePtr, 0, 0, &parser);
4221     objectPtr->export.oid = objectPtr->nodePtr->oid =
4222 	smiMalloc(sizeof(int));
4223     objectPtr->export.oidlen = objectPtr->nodePtr->oidlen = 1;
4224     objectPtr->nodePtr->oid[0] = 0;
4225     objectPtr->export.nodekind = SMI_NODEKIND_NODE;
4226     objectPtr = addObject(smiStrdup("iso"), smiHandle->rootNodePtr, 1, 0, &parser);
4227     objectPtr->export.oid = objectPtr->nodePtr->oid =
4228 	smiMalloc(sizeof(int));
4229     objectPtr->export.oidlen = objectPtr->nodePtr->oidlen = 1;
4230     objectPtr->nodePtr->oid[0] = 1;
4231     objectPtr->export.nodekind = SMI_NODEKIND_NODE;
4232     objectPtr = addObject(smiStrdup("joint-iso-ccitt"), smiHandle->rootNodePtr, 2, 0, &parser);
4233     objectPtr->export.oid = objectPtr->nodePtr->oid =
4234 	smiMalloc(sizeof(int));
4235     objectPtr->export.oidlen = objectPtr->nodePtr->oidlen = 1;
4236     objectPtr->nodePtr->oid[0] = 2;
4237     objectPtr->export.nodekind = SMI_NODEKIND_NODE;
4238 
4239 
4240     smiHandle->typeOctetStringPtr =
4241 	addType(smiStrdup("OctetString"),
4242 		SMI_BASETYPE_OCTETSTRING, 0, &parser);
4243     smiHandle->typeObjectIdentifierPtr =
4244 	addType(smiStrdup("ObjectIdentifier"),
4245 		SMI_BASETYPE_OBJECTIDENTIFIER, 0, &parser);
4246     smiHandle->typeInteger32Ptr =
4247 	addType(smiStrdup("Integer32"),
4248 		SMI_BASETYPE_INTEGER32, 0, &parser);
4249     smiHandle->typeUnsigned32Ptr =
4250 	addType(smiStrdup("Unsigned32"),
4251 		SMI_BASETYPE_UNSIGNED32, 0, &parser);
4252     smiHandle->typeInteger64Ptr =
4253 	addType(smiStrdup("Integer64"),
4254 		SMI_BASETYPE_INTEGER64, 0, &parser);
4255     smiHandle->typeUnsigned64Ptr =
4256 	addType(smiStrdup("Unsigned64"),
4257 		SMI_BASETYPE_UNSIGNED64, 0, &parser);
4258     smiHandle->typeFloat32Ptr =
4259 	addType(smiStrdup("Float32"),
4260 		SMI_BASETYPE_FLOAT32, 0, &parser);
4261     smiHandle->typeFloat64Ptr =
4262 	addType(smiStrdup("Float64"),
4263 		SMI_BASETYPE_FLOAT64, 0, &parser);
4264     smiHandle->typeFloat128Ptr =
4265 	addType(smiStrdup("Float128"),
4266 		SMI_BASETYPE_FLOAT128, 0, &parser);
4267     smiHandle->typeEnumPtr =
4268 	addType(smiStrdup("Enumeration"),
4269 		SMI_BASETYPE_ENUM, 0, &parser);
4270     smiHandle->typeBitsPtr =
4271 	addType(smiStrdup("Bits"),
4272 		SMI_BASETYPE_BITS, 0, &parser);
4273 	smiHandle->typePointerPtr =
4274 	addType(smiStrdup("Pointer"),
4275 		SMI_BASETYPE_POINTER, 0, &parser);
4276 
4277     return (0);
4278 }
4279 
4280 
4281 
4282 /*
4283  *----------------------------------------------------------------------
4284  *
4285  * freeNodeTree --
4286  *
4287  *      Free all node of a node (sub)tree.
4288  *
4289  * Results:
4290  *      0 on success or -1 on an error.
4291  *
4292  * Side effects:
4293  *      None.
4294  *
4295  *----------------------------------------------------------------------
4296  */
4297 
freeNodeTree(Node * rootPtr)4298 static void freeNodeTree(Node *rootPtr)
4299 {
4300     Node       *nodePtr, *nextPtr;
4301 
4302     for (nodePtr = rootPtr->firstChildPtr; nodePtr; nodePtr = nextPtr) {
4303 	nextPtr = nodePtr->nextPtr;
4304 	freeNodeTree(nodePtr);
4305 	smiFree(nodePtr->oid);
4306 	smiFree(nodePtr);
4307     }
4308     rootPtr->firstChildPtr = NULL;
4309     rootPtr->lastChildPtr = NULL;
4310     rootPtr->firstObjectPtr = NULL;
4311     rootPtr->lastObjectPtr = NULL;
4312     rootPtr->nextPtr = NULL;
4313     rootPtr->prevPtr = NULL;
4314     rootPtr->parentPtr = NULL;
4315 }
4316 
4317 
4318 
4319 /*
4320  *----------------------------------------------------------------------
4321  *
4322  * smiFreeData --
4323  *
4324  *      Free all data structures.
4325  *
4326  * Results:
4327  *      0 on success or -1 on an error.
4328  *
4329  * Side effects:
4330  *      None.
4331  *
4332  *----------------------------------------------------------------------
4333  */
4334 
smiFreeData()4335 void smiFreeData()
4336 {
4337     View       *viewPtr, *nextViewPtr;
4338     Macro      *macroPtr, *nextMacroPtr;
4339     Module     *modulePtr, *nextModulePtr;
4340     Import     *importPtr, *nextImportPtr;
4341     Identity     *identityPtr, *nextIdentityPtr;
4342     Revision   *revisionPtr, *nextRevisionPtr;
4343     List       *listPtr, *nextListPtr;
4344     Type       *typePtr, *nextTypePtr;
4345     Class	   *classPtr, *nextClassPtr;
4346     Attribute  *attributePtr, *nextAttributePtr;
4347     Event 	   *eventPtr,	*nextEventPtr;
4348     Object     *objectPtr, *nextObjectPtr;
4349 
4350     for (viewPtr = smiHandle->firstViewPtr; viewPtr; viewPtr = nextViewPtr) {
4351 	nextViewPtr = viewPtr->nextPtr;
4352 	smiFree(viewPtr->name);
4353 	smiFree(viewPtr);
4354     }
4355 
4356     /*
4357      * In this first module loop we remove each module's imports,
4358      * revisions, macros, and objects.
4359      */
4360     for (modulePtr = smiHandle->firstModulePtr; modulePtr;
4361 	 modulePtr = nextModulePtr) {
4362 	nextModulePtr = modulePtr->nextPtr;
4363 
4364 	for (importPtr = modulePtr->firstImportPtr; importPtr;
4365 	     importPtr = nextImportPtr) {
4366 	    nextImportPtr = importPtr->nextPtr;
4367 	    smiFree(importPtr->export.module);
4368 	    smiFree(importPtr->export.name);
4369 	    smiFree(importPtr);
4370 	}
4371 
4372 	for (revisionPtr = modulePtr->firstRevisionPtr; revisionPtr;
4373 	     revisionPtr = nextRevisionPtr) {
4374 	    nextRevisionPtr = revisionPtr->nextPtr;
4375 	    smiFree(revisionPtr->export.description);
4376 	    smiFree(revisionPtr);
4377 	}
4378 
4379 	for (macroPtr = modulePtr->firstMacroPtr; macroPtr;
4380 	     macroPtr = nextMacroPtr) {
4381 	    nextMacroPtr = macroPtr->nextPtr;
4382 	    smiFree(macroPtr->export.name);
4383 	    smiFree(macroPtr->export.abnf);
4384 	    smiFree(macroPtr->export.reference);
4385 	    smiFree(macroPtr->export.description);
4386 	    smiFree(macroPtr);
4387 
4388 	}
4389 	for (identityPtr = modulePtr->firstIdentityPtr; identityPtr;
4390 	     identityPtr = nextIdentityPtr) {
4391 	    nextIdentityPtr = identityPtr->nextPtr;
4392 	    smiFree(identityPtr->export.name);
4393 	    smiFree(identityPtr->export.reference);
4394 	    smiFree(identityPtr->export.description);
4395 	    smiFree(identityPtr);
4396 	}
4397 
4398 	for (objectPtr = modulePtr->firstObjectPtr; objectPtr;
4399 	     objectPtr = nextObjectPtr) {
4400 
4401 	    nextObjectPtr = objectPtr->nextPtr;
4402 	    smiFree(objectPtr->export.name);
4403 	    smiFree(objectPtr->export.description);
4404 	    smiFree(objectPtr->export.reference);
4405 	    smiFree(objectPtr->export.format);
4406 	    smiFree(objectPtr->export.units);
4407 	    for (listPtr = objectPtr->listPtr; listPtr;
4408 		 listPtr = nextListPtr) {
4409 		nextListPtr = listPtr->nextPtr;
4410 		smiFree(listPtr);
4411 	    }
4412 	    for (listPtr = objectPtr->optionlistPtr; listPtr;
4413 		 listPtr = nextListPtr) {
4414 		nextListPtr = listPtr->nextPtr;
4415 		smiFree(((Option *)(listPtr->ptr))->export.description);
4416 		smiFree((Option *)(listPtr->ptr));
4417 		smiFree(listPtr);
4418 	    }
4419 	    for (listPtr = objectPtr->refinementlistPtr; listPtr;
4420 		 listPtr = nextListPtr) {
4421 		nextListPtr = listPtr->nextPtr;
4422 		smiFree(((Refinement *)(listPtr->ptr))->export.description);
4423 		smiFree((Refinement *)(listPtr->ptr));
4424 		smiFree(listPtr);
4425 	    }
4426 	    if (objectPtr->typePtr) {
4427 		if ((objectPtr->typePtr->export.basetype ==
4428 		     SMI_BASETYPE_OCTETSTRING ||
4429 		     objectPtr->typePtr->export.basetype ==
4430 		     SMI_BASETYPE_BITS)) {
4431 		    smiFree(objectPtr->export.value.value.ptr);
4432 		} else if ((objectPtr->typePtr->export.basetype ==
4433 			    SMI_BASETYPE_OBJECTIDENTIFIER) &&
4434 			   (objectPtr->export.value.basetype ==
4435 			    objectPtr->typePtr->export.basetype)) {
4436 		    smiFree(objectPtr->export.value.value.oid);
4437 		}
4438 
4439 	    }
4440 	    smiFree(objectPtr);
4441 
4442 
4443 
4444 
4445 	}
4446 
4447 
4448 	for (classPtr = modulePtr->firstClassPtr; classPtr;
4449 	     classPtr = nextClassPtr) {
4450 
4451 	    nextClassPtr = classPtr->nextPtr;
4452 	   	for (attributePtr = classPtr->firstAttributePtr; attributePtr;
4453 	     attributePtr = nextAttributePtr) {
4454 
4455 	    nextAttributePtr = attributePtr->nextPtr;
4456 
4457 	    for (listPtr = attributePtr->listPtr; listPtr;
4458 		 listPtr = nextListPtr) {
4459 		nextListPtr = listPtr->nextPtr;
4460 		if ((attributePtr->export.basetype == SMI_BASETYPE_BITS) ||
4461 		    (attributePtr->export.basetype == SMI_BASETYPE_ENUM)) {
4462 		    smiFree(((NamedNumber *)(listPtr->ptr))->export.name);
4463 		    smiFree((NamedNumber *)(listPtr->ptr));
4464 		} else if ((attributePtr->export.basetype == SMI_BASETYPE_INTEGER32) ||
4465 			   (attributePtr->export.basetype == SMI_BASETYPE_INTEGER64) ||
4466 			   (attributePtr->export.basetype == SMI_BASETYPE_UNSIGNED32) ||
4467 			   (attributePtr->export.basetype == SMI_BASETYPE_UNSIGNED64) ||
4468 			   (attributePtr->export.basetype == SMI_BASETYPE_FLOAT32) ||
4469 			   (attributePtr->export.basetype == SMI_BASETYPE_FLOAT64) ||
4470 			   (attributePtr->export.basetype == SMI_BASETYPE_FLOAT128) ||
4471 			   (attributePtr->export.basetype == SMI_BASETYPE_OCTETSTRING)) {
4472 		    smiFree((Range *)(listPtr->ptr));
4473 		}
4474 		smiFree(listPtr);
4475 	    }
4476 	    smiFree(attributePtr->export.name);
4477 	    smiFree(attributePtr->export.format);
4478 	    smiFree(attributePtr->export.units);
4479 	    smiFree(attributePtr->export.description);
4480 	    smiFree(attributePtr->export.reference);
4481 	    smiFree(attributePtr);
4482 
4483 	    }
4484 
4485 	    for (eventPtr = classPtr->firstEventPtr; eventPtr;
4486 	     eventPtr = nextEventPtr) {
4487 
4488 		nextEventPtr = eventPtr->nextPtr;
4489 		smiFree(eventPtr->export.name);
4490 	    smiFree(eventPtr->export.reference);
4491 	    smiFree(eventPtr->export.description);
4492 	    }
4493 
4494 
4495 	    for (listPtr = classPtr->uniqueList; listPtr;
4496 		 listPtr = nextListPtr) {
4497 		nextListPtr = listPtr->nextPtr;
4498 			smiFree(listPtr);
4499 	    }
4500 
4501 	    smiFree(classPtr->export.name);
4502 	    smiFree(classPtr->export.description);
4503 	    smiFree(classPtr->export.reference);
4504 	    smiFree(classPtr);
4505 
4506 	}
4507     }
4508 
4509     /*
4510      * In this second module loop we remove each module's types
4511      * and the modules themselves. This separation is required, because
4512      * we reference some types of foreign modules in the first loop.
4513      */
4514     for (modulePtr = smiHandle->firstModulePtr; modulePtr;
4515 	 modulePtr = nextModulePtr) {
4516 	nextModulePtr = modulePtr->nextPtr;
4517 
4518 	for (typePtr = modulePtr->firstTypePtr; typePtr;
4519 	     typePtr = nextTypePtr) {
4520 	    nextTypePtr = typePtr->nextPtr;
4521 	    for (listPtr = typePtr->listPtr; listPtr;
4522 		 listPtr = nextListPtr) {
4523 		nextListPtr = listPtr->nextPtr;
4524 		if ((typePtr->export.basetype == SMI_BASETYPE_BITS) ||
4525 		    (typePtr->export.basetype == SMI_BASETYPE_ENUM)) {
4526 		    smiFree(((NamedNumber *)(listPtr->ptr))->export.name);
4527 		    smiFree((NamedNumber *)(listPtr->ptr));
4528 		} else if ((typePtr->export.basetype == SMI_BASETYPE_INTEGER32) ||
4529 			   (typePtr->export.basetype == SMI_BASETYPE_INTEGER64) ||
4530 			   (typePtr->export.basetype == SMI_BASETYPE_UNSIGNED32) ||
4531 			   (typePtr->export.basetype == SMI_BASETYPE_UNSIGNED64) ||
4532 			   (typePtr->export.basetype == SMI_BASETYPE_FLOAT32) ||
4533 			   (typePtr->export.basetype == SMI_BASETYPE_FLOAT64) ||
4534 			   (typePtr->export.basetype == SMI_BASETYPE_FLOAT128) ||
4535 			   (typePtr->export.basetype == SMI_BASETYPE_OCTETSTRING)) {
4536 		    smiFree((Range *)(listPtr->ptr));
4537 		}
4538 		smiFree(listPtr);
4539 	    }
4540 	    smiFree(typePtr->export.name);
4541 	    smiFree(typePtr->export.format);
4542 	    smiFree(typePtr->export.units);
4543 	    smiFree(typePtr->export.description);
4544 	    smiFree(typePtr->export.reference);
4545 	    smiFree(typePtr);
4546 	}
4547 
4548 	smiFree(modulePtr->export.name);
4549 	smiFree(modulePtr->export.path);
4550 	smiFree(modulePtr->export.organization);
4551 	smiFree(modulePtr->export.contactinfo);
4552 	smiFree(modulePtr->export.description);
4553 	smiFree(modulePtr->export.reference);
4554 	smiFree(modulePtr);
4555     }
4556 
4557     freeNodeTree(smiHandle->rootNodePtr);
4558     smiFree(smiHandle->rootNodePtr);
4559 
4560     return;
4561 }
4562 
4563 
4564 
4565 /*
4566  *----------------------------------------------------------------------
4567  *
4568  * loadModule --
4569  *
4570  *      Load a MIB module. If modulename is a plain name, the file is
4571  *	search along the SMIPATH environment variable. If modulename
4572  *	contains a `.' or DIR_SEPARATOR it is assumed to be the path.
4573  *
4574  * Results:
4575  *      0 on success or -1 on an error.
4576  *
4577  * Side effects:
4578  *      None.
4579  *
4580  *----------------------------------------------------------------------
4581  */
4582 
loadModule(const char * modulename,Parser * parserPtr)4583 Module *loadModule(const char *modulename, Parser *parserPtr)
4584 {
4585     Parser	    parser;
4586     Parser          *parentParserPtr;
4587     char	    *path = NULL, *dir, *smipath;
4588     int		    sming = 0;
4589     int             c, i;
4590     FILE	    *file;
4591     char	    sep[2];
4592 
4593     static const char *ext[] = {
4594 	"", ".my", ".smiv1", ".smiv2", ".sming", ".mib", ".txt", NULL
4595     };
4596 
4597     if ((!modulename) || !strlen(modulename)) {
4598 	return NULL;
4599     }
4600 
4601     if (!smiIsPath(modulename)) {
4602 	/*
4603 	 * A plain modulename. Lookup the path along SMIPATH...
4604 	 */
4605 	if (!smiHandle->path) {
4606 	    return NULL;
4607 	}
4608 
4609 	smipath = smiStrdup(smiHandle->path);
4610 	sep[0] = PATH_SEPARATOR; sep[1] = 0;
4611 	for (dir = strtok(smipath, sep);
4612 	     dir; dir = strtok(NULL, sep)) {
4613 	    for (i = 0; ext[i]; i++) {
4614 		smiAsprintf(&path, "%s%c%s%s", dir, DIR_SEPARATOR,
4615 			    modulename, ext[i]);
4616 		if (! access(path, R_OK)) {
4617 		    break;
4618 		}
4619 		smiFree(path);
4620 	    }
4621 	    if (ext[i]) break;
4622 	    {
4623 		char *newmodulename = smiStrdup(modulename);
4624 		for (i = 0; newmodulename[i]; i++) {
4625 		    newmodulename[i] = tolower(newmodulename[i]);
4626 		}
4627 		for (i = 0; ext[i]; i++) {
4628 		    smiAsprintf(&path, "%s%c%s%s", dir, DIR_SEPARATOR,
4629 				newmodulename, ext[i]);
4630 		    if (! access(path, R_OK)) {
4631 			break;
4632 		    }
4633 		    smiFree(path);
4634 		}
4635 		smiFree(newmodulename);
4636 		if (ext[i]) break;
4637 	    }
4638 
4639 	    path = NULL;
4640 	}
4641 	smiFree(smipath);
4642     } else {
4643 	/*
4644 	 * A full path. Take it.
4645 	 */
4646 	path = smiStrdup(modulename);
4647     }
4648 
4649 #if !defined(_MSC_VER) && !defined(__MINGW32__)
4650     if (!path && smiHandle->cache && smiHandle->cacheProg) {
4651 	/* Not found in the path; now try to fetch & cache the module. */
4652 	int  pid;
4653 	char *argv[4];
4654 	char *cmd;
4655 	int  status;
4656 	smiAsprintf(&path, "%s%c%s",
4657 		    smiHandle->cache, DIR_SEPARATOR, modulename);
4658 	if (access(path, R_OK)) {
4659 	    smiAsprintf(&cmd, "%s %s", smiHandle->cacheProg, modulename);
4660 	    pid = fork();
4661 	    if (pid != -1) {
4662 		if (!pid) {
4663 		    argv[0] = "sh"; argv[1] = "-c"; argv[2] = cmd; argv[3] = 0;
4664 		    execv("/bin/sh", argv);
4665 		    exit(127);
4666 		}
4667 		waitpid(pid, &status, 0);
4668 	    }
4669 	    smiFree(cmd);
4670 	    if (access(path, R_OK)) {
4671 		smiFree(path);
4672 		path = NULL;
4673 	    }
4674 	}
4675     }
4676 #endif
4677 
4678     if (!path) {
4679 	smiPrintError(parserPtr, ERR_MODULE_NOT_FOUND, modulename);
4680 	return NULL;
4681     }
4682 
4683     parser.path			= path;
4684 
4685     /*
4686      * Look into the file to determine whether it contains
4687      * SMIv1/SMIv2 or SMIng definitions.
4688      */
4689 
4690     file = fopen(path, "r");
4691     if (! file) {
4692 	smiPrintError(parserPtr, ERR_OPENING_INPUTFILE, path, strerror(errno));
4693 	smiFree(path);
4694 	return NULL;
4695     }
4696     while ((c = fgetc(file))) {
4697 	if (c == '-' || isupper(c)) {
4698 	    sming = 0;
4699 	    break;
4700 	} else if (c == '/' || c == 'm') {
4701 	    sming = 1;
4702 	    break;
4703 	} else if (c == EOF || ! isspace(c)) {
4704 	    smiPrintError(parserPtr, ERR_ILLEGAL_INPUTFILE, path);
4705 	    smiFree(path);
4706 	    fclose(file);
4707 	    return NULL;
4708 	}
4709     }
4710     rewind(file);
4711 
4712 
4713     if (sming == 0) {
4714 #ifdef BACKEND_SMI
4715 	parentParserPtr = smiHandle->parserPtr;
4716 	smiHandle->parserPtr = &parser;
4717 	parser.path			= path;
4718 	parser.flags			= smiHandle->flags;
4719 	parser.modulePtr		= NULL;
4720 	parser.complianceModulePtr	= NULL;
4721 	parser.capabilitiesModulePtr	= NULL;
4722 	parser.currentDecl              = SMI_DECL_UNKNOWN;
4723 	parser.firstStatementLine       = 0;
4724 	parser.firstNestedStatementLine = 0;
4725 	parser.firstRevisionLine        = 0;
4726 	parser.file			= file;
4727 
4728 	/*
4729 	 * Initialize a root Node for pending (forward referenced) nodes.
4730 	 */
4731 	parser.pendingNodePtr = addNode(NULL, 0, NODE_FLAG_ROOT, NULL);
4732 
4733 	if (smiEnterLexRecursion(parser.file) < 0) {
4734 	    smiPrintError(&parser, ERR_MAX_LEX_DEPTH);
4735 	    fclose(parser.file);
4736 	}
4737 	smiDepth++;
4738 	parser.line			= 1;
4739 	smiparse((void *)&parser);
4740 	freeNodeTree(parser.pendingNodePtr);
4741 	smiFree(parser.pendingNodePtr);
4742 	smiLeaveLexRecursion();
4743 	smiDepth--;
4744 	fclose(parser.file);
4745 	smiFree(path);
4746 	smiHandle->parserPtr = parentParserPtr;
4747 	return parser.modulePtr;
4748 #else
4749 	smiPrintError(parserPtr, ERR_SMI_NOT_SUPPORTED, path);
4750 	smiFree(path);
4751         fclose(file);
4752 	return NULL;
4753 #endif
4754     }
4755 
4756     if (sming == 1) {
4757 #ifdef BACKEND_SMING
4758 	parentParserPtr = smiHandle->parserPtr;
4759 	smiHandle->parserPtr = &parser;
4760 	parser.path			= path;
4761 	parser.flags			= smiHandle->flags;
4762 	parser.modulePtr		= NULL;
4763 	parser.complianceModulePtr	= NULL;
4764 	parser.capabilitiesModulePtr	= NULL;
4765 	parser.currentDecl              = SMI_DECL_UNKNOWN;
4766 	parser.firstStatementLine       = 0;
4767 	parser.firstNestedStatementLine = 0;
4768 	parser.firstRevisionLine        = 0;
4769 	parser.file			= file;
4770 
4771 	/*
4772 	 * Initialize a root Node for pending (forward referenced) nodes.
4773 	 */
4774 	parser.pendingNodePtr = addNode(NULL, 0, NODE_FLAG_ROOT, NULL);
4775 
4776 	if (smingEnterLexRecursion(parser.file) < 0) {
4777 	    smiPrintError(&parser, ERR_MAX_LEX_DEPTH);
4778 	    fclose(parser.file);
4779 	}
4780 	smiDepth++;
4781 	parser.line			= 1;
4782 	smingparse((void *)&parser);
4783 	freeNodeTree(parser.pendingNodePtr);
4784 	smiFree(parser.pendingNodePtr);
4785 	smingLeaveLexRecursion();
4786 	smiDepth--;
4787 	fclose(parser.file);
4788 	smiFree(path);
4789 	smiHandle->parserPtr = parentParserPtr;
4790 	return parser.modulePtr;
4791 #else
4792 	smiPrintError(parserPtr, ERR_SMING_NOT_SUPPORTED, path);
4793 	smiFree(path);
4794         fclose(file);
4795 	return NULL;
4796 #endif
4797     }
4798 
4799     smiFree(path);
4800     fclose(file);
4801     return NULL;
4802 }
4803