/* * data.c -- * * Operations on the main data structures. * * Copyright (c) 1999-2002 Frank Strauss, Technical University of Braunschweig. * * See the file "COPYING" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * @(#) $Id: data.c 7822 2008-03-01 13:22:42Z schoenw $ */ #include #include #include #include #include #if !defined(_MSC_VER) && !defined(__MINGW32__) #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_WIN_H #include "win.h" #endif #include "error.h" #include "util.h" #include "data.h" #include "smi.h" #ifdef HAVE_DMALLOC_H #include #endif #ifdef BACKEND_SMI #include "scanner-smi.h" extern int smiparse(); #endif #ifdef BACKEND_SMING #include "scanner-sming.h" extern int smingparse(); #endif #define stringKind(kind) ( \ (kind == KIND_ANY) ? "ANY" : \ (kind == KIND_MODULE) ? "MODULE" : \ (kind == KIND_MACRO) ? "MACRO" : \ (kind == KIND_TYPE) ? "TYPE" : \ (kind == KIND_OBJECT) ? "OBJECT" : \ (kind == KIND_IMPORT) ? "IMPORT" : \ "unknown" ) int smiDepth = 0; static Handle *firstHandlePtr = NULL; static Handle *lastHandlePtr = NULL; /* *---------------------------------------------------------------------- * * addHandle -- * * Adds a libsmi handle with a given name. * * Results: * 0 on success or -1 on an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Handle *addHandle(const char *name) { Handle *handlePtr; handlePtr = (Handle *) smiMalloc(sizeof(Handle)); handlePtr->name = smiStrdup(name); handlePtr->nextPtr = NULL; handlePtr->prevPtr = lastHandlePtr; if (!firstHandlePtr) firstHandlePtr = handlePtr; if (lastHandlePtr) lastHandlePtr->nextPtr = handlePtr; lastHandlePtr = handlePtr; return (handlePtr); } /* *---------------------------------------------------------------------- * * removeHandle -- * * Removes a given libsmi handle. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void removeHandle(Handle *handlePtr) { if (handlePtr->prevPtr) { handlePtr->prevPtr->nextPtr = handlePtr->nextPtr; } else { firstHandlePtr = handlePtr->nextPtr; } if (handlePtr->nextPtr) { handlePtr->nextPtr->prevPtr = handlePtr->prevPtr; } else { lastHandlePtr = handlePtr->prevPtr; } smiFree(handlePtr->name); smiFree(handlePtr); } /* *---------------------------------------------------------------------- * * findHandleByName -- * * Lookup an libsmi handle by its name. * * Results: * A pointer to the Handle structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Handle *findHandleByName(const char *name) { Handle *handlePtr; if (!name) return NULL; for (handlePtr = firstHandlePtr; handlePtr; handlePtr = handlePtr->nextPtr) { if (!strcmp(handlePtr->name, name)) { return (handlePtr); } } return NULL; } /* *---------------------------------------------------------------------- * * addView -- * * Add a module to the `view' (the list of modules, seen by the user). * * Results: * A pointer to the new View structure or * NULL if terminated due to an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) View *addView(const char *modulename) { View *viewPtr; viewPtr = (View *) smiMalloc(sizeof(View)); viewPtr->name = smiStrdup(modulename); viewPtr->nextPtr = NULL; viewPtr->prevPtr = smiHandle->lastViewPtr; if (!smiHandle->firstViewPtr) smiHandle->firstViewPtr = viewPtr; if (smiHandle->lastViewPtr) smiHandle->lastViewPtr->nextPtr = viewPtr; smiHandle->lastViewPtr = viewPtr; return (viewPtr); } /* *---------------------------------------------------------------------- * * isInView -- * * Check, whether a given module is in the current view. * * Results: * != 0 if in view, 0 otherwise. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) int isInView(const char *modulename) { View *viewPtr; #if 0 if (smiHandle->flags & SMI_FLAG_VIEWALL) { return 1; } #endif for (viewPtr = smiHandle->firstViewPtr; viewPtr; viewPtr = viewPtr->nextPtr) { if (!strcmp(modulename, viewPtr->name)) { return 1; } } return 0; } /* *---------------------------------------------------------------------- * * addModule -- * * Create a new MIB module. * * Results: * A pointer to the new Module structure or * NULL if terminated due to an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Module *addModule(char *modulename, char *path, ModuleFlags flags, Parser *parserPtr) { Module *modulePtr; modulePtr = (Module *) smiMalloc(sizeof(Module)); modulePtr->export.name = modulename; modulePtr->export.path = path; modulePtr->export.language = SMI_LANGUAGE_UNKNOWN; modulePtr->export.organization = NULL; modulePtr->export.contactinfo = NULL; modulePtr->export.description = NULL; modulePtr->export.reference = NULL; modulePtr->export.conformance = 0; modulePtr->lastUpdated = 0; modulePtr->flags = flags; modulePtr->objectPtr = NULL; modulePtr->prefixNodePtr = NULL; modulePtr->firstObjectPtr = NULL; modulePtr->lastObjectPtr = NULL; modulePtr->firstTypePtr = NULL; modulePtr->lastTypePtr = NULL; modulePtr->firstMacroPtr = NULL; modulePtr->lastMacroPtr = NULL; modulePtr->firstImportPtr = NULL; modulePtr->lastImportPtr = NULL; modulePtr->firstRevisionPtr = NULL; modulePtr->lastRevisionPtr = NULL; modulePtr->numImportedIdentifiers = 0; modulePtr->numStatements = 0; modulePtr->numModuleIdentities = 0; modulePtr->nextPtr = NULL; modulePtr->prevPtr = smiHandle->lastModulePtr; if (!smiHandle->firstModulePtr) smiHandle->firstModulePtr = modulePtr; if (smiHandle->lastModulePtr) smiHandle->lastModulePtr->nextPtr = modulePtr; smiHandle->lastModulePtr = modulePtr; return (modulePtr); } /* *---------------------------------------------------------------------- * * setModuleIdentityObject -- * * Set the objectPtr of a given Module to the OBJECT-IDENTITY object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setModuleIdentityObject(Module *modulePtr, Object *objectPtr) { modulePtr->objectPtr = objectPtr; } /* *---------------------------------------------------------------------- * * setModuleLastUpdated -- * * Set the lastUpdated time_t value of a given Module. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setModuleLastUpdated(Module *modulePtr, time_t lastUpdated) { modulePtr->lastUpdated = lastUpdated; } /* *---------------------------------------------------------------------- * * setModuleOrganization -- * * Set the organization string of a given Module. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setModuleOrganization(Module *modulePtr, char *organization) { modulePtr->export.organization = organization; while (strlen(organization) && organization[strlen(organization)-1] == '\n') { organization[strlen(organization) - 1] = 0; } } /* *---------------------------------------------------------------------- * * setModuleContactInfo -- * * Set the contactInfo string of a given Module. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setModuleContactInfo(Module *modulePtr, char *contactinfo) { modulePtr->export.contactinfo = contactinfo; } /* *---------------------------------------------------------------------- * * setModuleDescription -- * * Set the description string of a given Module. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setModuleDescription(Module *modulePtr, char *description, Parser *parserPtr) { if (modulePtr->export.description) smiFree(modulePtr->export.description); if (parserPtr->flags & SMI_FLAG_NODESCR) { smiFree(description); modulePtr->export.description = NULL; } else { modulePtr->export.description = description; } } /* *---------------------------------------------------------------------- * * setModuleReference -- * * Set the reference string of a given Module. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setModuleReference(Module *modulePtr, char *reference, Parser *parserPtr) { if (modulePtr->export.reference) smiFree(modulePtr->export.reference); if (parserPtr->flags & SMI_FLAG_NODESCR) { smiFree(reference); modulePtr->export.reference = NULL; } else { modulePtr->export.reference = reference; } } /* *---------------------------------------------------------------------- * * findModuleByName -- * * Lookup a Module by a given name. * * Results: * A pointer to the Module structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Module *findModuleByName(const char *modulename) { Module *modulePtr; for (modulePtr = smiHandle->firstModulePtr; modulePtr; modulePtr = modulePtr->nextPtr) { if ((modulePtr->export.name) && !strcmp(modulePtr->export.name, modulename)) { return (modulePtr); } } return (NULL); } /* *---------------------------------------------------------------------- * * addRevision -- * * Adds a revision entry for the given module. * * Results: * 0 on success or -1 on an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Revision *addRevision(time_t date, char *description, Parser *parserPtr) { Revision *revisionPtr, *r; Module *modulePtr; revisionPtr = (Revision *) smiMalloc(sizeof(Revision)); modulePtr = parserPtr->modulePtr; revisionPtr->modulePtr = modulePtr; revisionPtr->export.date = date; if (parserPtr->flags & SMI_FLAG_NODESCR) { smiFree(description); revisionPtr->export.description = NULL; } else { revisionPtr->export.description = description; } revisionPtr->line = parserPtr ? parserPtr->line : -1; for (r = modulePtr->lastRevisionPtr; r; r = r->prevPtr) { if (r->export.date > date) break; } if (r) { revisionPtr->nextPtr = r->nextPtr; revisionPtr->prevPtr = r; if (r->nextPtr) { r->nextPtr->prevPtr = revisionPtr; } else { modulePtr->lastRevisionPtr = revisionPtr; } r->nextPtr = revisionPtr; } else { revisionPtr->prevPtr = NULL; if (modulePtr->firstRevisionPtr) { modulePtr->firstRevisionPtr->prevPtr = revisionPtr; revisionPtr->nextPtr = modulePtr->firstRevisionPtr; } else { modulePtr->lastRevisionPtr = revisionPtr; revisionPtr->nextPtr = NULL; } modulePtr->firstRevisionPtr = revisionPtr; } return (revisionPtr); } /* *---------------------------------------------------------------------- * * setRevisionLine -- * * Set the line of definition of a given Revision. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setRevisionLine(Revision *revisionPtr, int line, Parser *parserPtr) { if (line) { revisionPtr->line = line; } else { revisionPtr->line = parserPtr ? parserPtr->line : -1; } } /* *---------------------------------------------------------------------- * * addImport -- * * Adds a descriptor to the actual module's list of imported * descriptors. This list may be checked by checkImports() * afterwards. * * Results: * 0 on success or -1 on an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Import *addImport(char *name, Parser *parserPtr) { Import *importPtr; Module *modulePtr; importPtr = (Import *) smiMalloc(sizeof(Import)); modulePtr = parserPtr->modulePtr; importPtr->modulePtr = modulePtr; importPtr->export.name = name; importPtr->export.module = NULL; /* not yet known */ importPtr->kind = KIND_UNKNOWN; /* not yet known */ importPtr->use = 0; importPtr->flags = 0; importPtr->line = parserPtr ? parserPtr->line : -1; importPtr->nextPtr = NULL; importPtr->prevPtr = modulePtr->lastImportPtr; if (!modulePtr->firstImportPtr) modulePtr->firstImportPtr = importPtr; if (modulePtr->lastImportPtr) modulePtr->lastImportPtr->nextPtr = importPtr; modulePtr->lastImportPtr = importPtr; return (importPtr); } /* *---------------------------------------------------------------------- * * addImportFlags -- * * Add flags to the flags of a given Import struct. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void addImportFlags(Import *importPtr, ImportFlags flags) { importPtr->flags |= flags; } /* *---------------------------------------------------------------------- * * setImportModulename -- * * Set the modulename part of a given Import struct. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setImportModulename(Import *importPtr, char *modulename) { if (importPtr->export.module) { smiFree(importPtr->export.module); } importPtr->export.module = modulename; } /* *---------------------------------------------------------------------- * * checkImports -- * * Check wheather all descriptors in the actual module's list * are imported by a given Module. Implicitly set all Imports' * module names. * * Results: * 0 on success or -1 on an error or number of descriptors not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) int checkImports(Module *modulePtr, Parser *parserPtr) { int n = 0; Import *importPtr; SmiNode *smiNode; SmiType *smiType; SmiMacro *smiMacro; for (importPtr = parserPtr->modulePtr->firstImportPtr; importPtr; importPtr = importPtr->nextPtr) { if (importPtr->kind == KIND_UNKNOWN) { if (modulePtr) { if ((smiNode = smiGetNode(&modulePtr->export, importPtr->export.name))) { importPtr->export.module = smiStrdup(modulePtr->export.name); importPtr->kind = KIND_OBJECT; } else if ((smiType = smiGetType(&modulePtr->export, importPtr->export.name))) { importPtr->export.module = smiStrdup(modulePtr->export.name); importPtr->kind = KIND_TYPE; } else if ((smiMacro = smiGetMacro(&modulePtr->export, importPtr->export.name))) { importPtr->export.module = smiStrdup(modulePtr->export.name); importPtr->kind = KIND_MACRO; } else { n++; importPtr->export.module = smiStrdup(modulePtr->export.name); smiPrintError(parserPtr, ERR_IDENTIFIER_NOT_IN_MODULE, importPtr->export.name, modulePtr->export.name); importPtr->kind = KIND_NOTFOUND; } } else { n++; importPtr->export.module = smiStrdup(""); importPtr->kind = KIND_NOTFOUND; } } } return (n); } /* *---------------------------------------------------------------------- * * findImportByName -- * * Lookup an import descriptor by its name and the module to look in. * * Results: * A pointer to the Import structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Import *findImportByName(const char *name, Module *modulePtr) { Import *importPtr; if (!name) return NULL; for (importPtr = modulePtr->firstImportPtr; importPtr; importPtr = importPtr->nextPtr) { if ((!strcmp(importPtr->export.name, name)) && (!(importPtr->flags & FLAG_INCOMPLIANCE))) { return (importPtr); } } return NULL; } /* *---------------------------------------------------------------------- * * findImportByModulenameAndName -- * * Lookup an import descriptor by its name and the modulename * it is imported from and the module to look in. * * Results: * A pointer to the Import structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Import *findImportByModulenameAndName(const char *modulename, const char *name, Module *modulePtr) { Import *importPtr; for (importPtr = modulePtr->firstImportPtr; importPtr; importPtr = importPtr->nextPtr) { if ((!strcmp(importPtr->export.name, name)) && (!strcmp(importPtr->export.module, modulename))) { return (importPtr); } } return (NULL); } /* *---------------------------------------------------------------------- * * addObject -- * * Create a new Object and Node or update an existing one. * Also updates other Objects and Nodes according * to the PendingNode information. * * Results: * A pointer to the new Object structure or * NULL if terminated due to an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Object *addObject(char *objectname, Node *parentNodePtr, SmiSubid subid, ObjectFlags flags, Parser *parserPtr) { Object *objectPtr; Node *nodePtr; Module *modulePtr; objectPtr = (Object *) smiMalloc(sizeof(Object)); modulePtr = parserPtr ? parserPtr->modulePtr : NULL; objectPtr->export.name = objectname; objectPtr->export.decl = SMI_DECL_UNKNOWN; objectPtr->export.access = SMI_ACCESS_UNKNOWN; objectPtr->export.status = SMI_STATUS_UNKNOWN; objectPtr->export.format = NULL; objectPtr->export.value.basetype = SMI_BASETYPE_UNKNOWN; objectPtr->export.units = NULL; objectPtr->export.description = NULL; objectPtr->export.reference = NULL; objectPtr->export.indexkind = SMI_INDEX_UNKNOWN; objectPtr->export.implied = 0; objectPtr->export.create = 0; objectPtr->export.nodekind = SMI_NODEKIND_UNKNOWN; objectPtr->modulePtr = modulePtr; objectPtr->nodePtr = NULL; objectPtr->prevSameNodePtr = NULL; objectPtr->nextSameNodePtr = NULL; objectPtr->typePtr = NULL; objectPtr->listPtr = NULL; objectPtr->flags = flags; objectPtr->line = parserPtr ? parserPtr->line : -1; objectPtr->uniquenessPtr = NULL; objectPtr->export.oidlen = 0; /* filled in by */ objectPtr->export.oid = NULL; /* second pass. */ objectPtr->nextPtr = NULL; if (modulePtr) { objectPtr->prevPtr = modulePtr->lastObjectPtr; if (!modulePtr->firstObjectPtr) modulePtr->firstObjectPtr = objectPtr; if (modulePtr->lastObjectPtr) modulePtr->lastObjectPtr->nextPtr = objectPtr; modulePtr->lastObjectPtr = objectPtr; } else { objectPtr->prevPtr = NULL; } /* * Link it into the tree. */ nodePtr = findNodeByParentAndSubid(parentNodePtr, subid); if ((parentNodePtr == parserPtr->pendingNodePtr) || (!nodePtr)) { /* a new Node has to be created for this Object */ nodePtr = addNode(parentNodePtr, subid, flags, parserPtr); nodePtr->firstObjectPtr = objectPtr; nodePtr->lastObjectPtr = objectPtr; } else { objectPtr->prevSameNodePtr = nodePtr->lastObjectPtr; if (!nodePtr->firstObjectPtr) nodePtr->firstObjectPtr = objectPtr; if (nodePtr->lastObjectPtr) nodePtr->lastObjectPtr->nextSameNodePtr = objectPtr; nodePtr->lastObjectPtr = objectPtr; } objectPtr->nodePtr = nodePtr; return (objectPtr); } /* *---------------------------------------------------------------------- * * duplicateObject -- * * Create a new Object as a duplicate of a given one but with * an affiliation to another module with new flags and with * uninitialzied values. * * Results: * A pointer to the new Object structure or * NULL if terminated due to an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Object *duplicateObject(Object *templatePtr, ObjectFlags flags, Parser *parserPtr) { Object *objectPtr; Node *nodePtr; Module *modulePtr; objectPtr = (Object *) smiMalloc(sizeof(Object)); modulePtr = parserPtr->modulePtr; nodePtr = templatePtr->nodePtr; objectPtr->export.name = NULL; objectPtr->export.decl = SMI_DECL_UNKNOWN; objectPtr->export.access = SMI_ACCESS_UNKNOWN; objectPtr->export.status = SMI_STATUS_UNKNOWN; objectPtr->export.format = NULL; objectPtr->export.value.basetype = SMI_BASETYPE_UNKNOWN; objectPtr->export.units = NULL; objectPtr->export.description = NULL; objectPtr->export.reference = NULL; objectPtr->export.indexkind = SMI_INDEX_UNKNOWN; objectPtr->export.implied = 0; objectPtr->export.create = 0; objectPtr->export.nodekind = SMI_NODEKIND_UNKNOWN; objectPtr->modulePtr = modulePtr; objectPtr->nodePtr = nodePtr; objectPtr->prevSameNodePtr = NULL; objectPtr->nextSameNodePtr = NULL; objectPtr->typePtr = NULL; objectPtr->listPtr = NULL; objectPtr->flags = flags; objectPtr->line = parserPtr ? parserPtr->line : -1; objectPtr->export.oidlen = 0; /* filled in by */ objectPtr->export.oid = NULL; /* second pass. */ objectPtr->nextPtr = NULL; if (modulePtr) { objectPtr->prevPtr = modulePtr->lastObjectPtr; if (!modulePtr->firstObjectPtr) modulePtr->firstObjectPtr = objectPtr; if (modulePtr->lastObjectPtr) modulePtr->lastObjectPtr->nextPtr = objectPtr; modulePtr->lastObjectPtr = objectPtr; } else { objectPtr->prevPtr = NULL; } objectPtr->prevSameNodePtr = nodePtr->lastObjectPtr; if (!nodePtr->firstObjectPtr) nodePtr->firstObjectPtr = objectPtr; if (nodePtr->lastObjectPtr) nodePtr->lastObjectPtr->nextSameNodePtr = objectPtr; nodePtr->lastObjectPtr = objectPtr; objectPtr->nodePtr = nodePtr; return (objectPtr); } /* *---------------------------------------------------------------------- * * addNode -- * * Create a new Node by a given parent Node and subid. * * Results: * A pointer to the new Node structure or * NULL if terminated due to an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Node *addNode (Node *parentNodePtr, SmiSubid subid, NodeFlags flags, Parser *parserPtr) { Node *nodePtr; Node *c; nodePtr = (Node *) smiMalloc(sizeof(Node)); nodePtr->flags = flags; nodePtr->subid = subid; nodePtr->parentPtr = parentNodePtr; nodePtr->firstChildPtr = NULL; nodePtr->lastChildPtr = NULL; nodePtr->firstObjectPtr = NULL; nodePtr->lastObjectPtr = NULL; /* * this cannot be set in all situations (pending sub trees). * we delay it to the second pass. */ nodePtr->oidlen = 0; nodePtr->oid = NULL; if (parentNodePtr) { if (parentNodePtr->firstChildPtr) { for (c = parentNodePtr->firstChildPtr; c && (c->subid < subid); c = c->nextPtr); if (c) { if (c != parentNodePtr->firstChildPtr) { c->prevPtr->nextPtr = nodePtr; nodePtr->prevPtr = c->prevPtr; c->prevPtr = nodePtr; nodePtr->nextPtr = c; } else { c->prevPtr = nodePtr; nodePtr->nextPtr = c; nodePtr->prevPtr = NULL; parentNodePtr->firstChildPtr = nodePtr; } } else { nodePtr->nextPtr = NULL; nodePtr->prevPtr = parentNodePtr->lastChildPtr; parentNodePtr->lastChildPtr->nextPtr = nodePtr; parentNodePtr->lastChildPtr = nodePtr; } } else { parentNodePtr->firstChildPtr = nodePtr; parentNodePtr->lastChildPtr = nodePtr; nodePtr->nextPtr = NULL; nodePtr->prevPtr = NULL; } } return nodePtr; } /* *---------------------------------------------------------------------- * * createNodes -- * * Create all missing Nodes down the tree along all subids of * a given Oid. * * Results: * A pointer to the leaf Node structure or * NULL if terminated due to an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Node *createNodes(unsigned int oidlen, SmiSubid *oid) { Node *parentNodePtr, *nodePtr; unsigned int i; parentNodePtr = smiHandle->rootNodePtr; for(i = 0; i < oidlen; i++) { if (!(nodePtr = findNodeByParentAndSubid(parentNodePtr, oid[i]))) { nodePtr = addNode(parentNodePtr, oid[i], 0, NULL); } parentNodePtr = nodePtr; } return parentNodePtr; } /* *---------------------------------------------------------------------- * * createNodesByOidString -- * * Create all missing Nodes down the tree along all subids of * a given Oid. * * Results: * A pointer to the leaf Node structure or * NULL if terminated due to an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Node *createNodesByOidString(const char *oid) { char *p, *elements; Node *parentNodePtr, *nodePtr; SmiSubid subid; parentNodePtr = smiHandle->rootNodePtr; elements = smiStrdup(oid); p = strtok(elements, "."); do { subid = (unsigned int)strtoul(p, NULL, 0); if (!(nodePtr = findNodeByParentAndSubid(parentNodePtr, subid))) { nodePtr = addNode(parentNodePtr, subid, 0, NULL); } parentNodePtr = nodePtr; } while ((p = strtok(NULL, "."))); smiFree(elements); return parentNodePtr; } /* *---------------------------------------------------------------------- * * getParentNode -- * * Return the parent of a given Node. * * Results: * A pointer to the parent Node structure. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Node *getParentNode(Node *nodePtr) { return nodePtr->parentPtr; } /* *---------------------------------------------------------------------- * * mergeNodeTrees -- * * Merge the subtree rooted at `from' into the `to' tree recursively * and release the `from' tree. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) static void mergeNodeTrees(Node *toNodePtr, Node *fromNodePtr, Parser *parserPtr) { Node *nodePtr, *toChildPtr, *nextPtr; Object *objectPtr; /* (1) merge lists of Objects for this node */ if (fromNodePtr->firstObjectPtr) { if (!toNodePtr->firstObjectPtr) { toNodePtr->firstObjectPtr = fromNodePtr->firstObjectPtr; toNodePtr->lastObjectPtr = fromNodePtr->lastObjectPtr; } else { fromNodePtr->firstObjectPtr->prevSameNodePtr = toNodePtr->lastObjectPtr; toNodePtr->lastObjectPtr->nextSameNodePtr = fromNodePtr->firstObjectPtr; toNodePtr->lastObjectPtr = fromNodePtr->lastObjectPtr; } } for (objectPtr = fromNodePtr->firstObjectPtr; objectPtr; objectPtr = objectPtr->nextSameNodePtr) { objectPtr->nodePtr = toNodePtr; } /* (2) loop: merge all first-level `from' sub-trees to `to' */ /* adjust all `from' sub-nodes' parentPtrs */ for (nodePtr = fromNodePtr->firstChildPtr; nodePtr; nodePtr = nodePtr->nextPtr) { nodePtr->parentPtr = toNodePtr; } if (!toNodePtr->firstChildPtr) { /* * if `to' has no sub-nodes, just move the `from' sub-nodes. */ toNodePtr->firstChildPtr = fromNodePtr->firstChildPtr; toNodePtr->lastChildPtr = fromNodePtr->lastChildPtr; } else { /* * otherwise, we really have to merge both trees... */ for (nodePtr = fromNodePtr->firstChildPtr; nodePtr; ) { nextPtr = nodePtr->nextPtr; if ((toChildPtr = findNodeByParentAndSubid(toNodePtr, nodePtr->subid))) { /* * if a sub-node with the same subid is already present * in `to', merge them recursively. */ mergeNodeTrees(toChildPtr, nodePtr, parserPtr); } else { /* * otherwise, move the sub-tree from `from' to `to'. */ if (nodePtr->subid < toNodePtr->firstChildPtr->subid) { /* move to the head. */ nodePtr->nextPtr = toNodePtr->firstChildPtr; toNodePtr->firstChildPtr = nodePtr; } else if (nodePtr->subid > toNodePtr->lastChildPtr->subid) { /* move to the end. */ nodePtr->prevPtr = toNodePtr->lastChildPtr; toNodePtr->lastChildPtr->nextPtr = nodePtr; toNodePtr->lastChildPtr = nodePtr; } else { /* move to the appropriate place in the `to' list. */ for (toChildPtr = toNodePtr->firstChildPtr; toChildPtr->nextPtr->subid < nodePtr->subid; toChildPtr = toChildPtr->nextPtr); toChildPtr->nextPtr->prevPtr = nodePtr; nodePtr->nextPtr = toChildPtr->nextPtr; nodePtr->prevPtr = toChildPtr; toChildPtr->nextPtr = nodePtr; } } nodePtr = nextPtr; } } smiFree(fromNodePtr); } /* *---------------------------------------------------------------------- * * setObjectName -- * * Set the name of a given Object. Combine two Objects if the name * already exists. * * Results: * (Object *) of the potentially combined object. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Object *setObjectName(Object *objectPtr, char *name, Parser *parserPtr) { Node *nodePtr, *nextPtr; Module *modulePtr; Object *newObjectPtr; if (objectPtr->export.name) { smiFree(objectPtr->export.name); } objectPtr->export.name = name; /* * If this name is found on the pending list (at depth==1 in * pendingRootNode), we have to move the corresponding subtree to * the main tree. */ for (nodePtr = parserPtr->pendingNodePtr->firstChildPtr; nodePtr; nodePtr = nextPtr) { /* * probably we change the contents of `pending', so remember * the next pointer. */ nextPtr = nodePtr->nextPtr; if (!strcmp(nodePtr->firstObjectPtr->export.name, name)) { /* * remove nodePtr from the pendingRootNode tree. */ if (nodePtr->prevPtr) { nodePtr->prevPtr->nextPtr = nodePtr->nextPtr; } else { parserPtr->pendingNodePtr->firstChildPtr = nodePtr->nextPtr; } if (nodePtr->nextPtr) { nodePtr->nextPtr->prevPtr = nodePtr->prevPtr; } else { parserPtr->pendingNodePtr->lastChildPtr = nodePtr->prevPtr; } #if 0 objectPtr->nodePtr->firstObjectPtr = NULL; objectPtr->nodePtr->lastObjectPtr = NULL; #else if (objectPtr->nodePtr->lastObjectPtr != NULL) { if (objectPtr->nodePtr->lastObjectPtr->export.oid == NULL) { objectPtr->nodePtr->lastObjectPtr = objectPtr->nodePtr->lastObjectPtr->prevSameNodePtr; if (objectPtr->nodePtr->lastObjectPtr == NULL) { objectPtr->nodePtr->firstObjectPtr = NULL; } } } #endif newObjectPtr = nodePtr->firstObjectPtr; if (newObjectPtr) { modulePtr = newObjectPtr->modulePtr; if (modulePtr->objectPtr == objectPtr) { modulePtr->objectPtr = newObjectPtr; } if (modulePtr->firstObjectPtr == objectPtr) { modulePtr->firstObjectPtr = objectPtr->nextPtr; modulePtr->firstObjectPtr->prevPtr = NULL; } if (modulePtr->lastObjectPtr == objectPtr) { modulePtr->lastObjectPtr = objectPtr->prevPtr; modulePtr->lastObjectPtr->nextPtr = NULL; } mergeNodeTrees(objectPtr->nodePtr, nodePtr, parserPtr); smiFree(objectPtr->export.name); smiFree(objectPtr); return newObjectPtr; } else { return objectPtr; } } } return objectPtr; } /* *---------------------------------------------------------------------- * * setObjectType -- * * Set the type (pointer to a Type struct) of a given Object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectType(Object *objectPtr, Type *typePtr) { objectPtr->typePtr = typePtr; } /* *---------------------------------------------------------------------- * * setObjectAccess -- * * Set the access of a given Object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectAccess(Object *objectPtr, SmiAccess access) { objectPtr->export.access = access; } /* *---------------------------------------------------------------------- * * setObjectStatus -- * * Set the status of a given Object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectStatus(Object *objectPtr, SmiStatus status) { objectPtr->export.status = status; } /* *---------------------------------------------------------------------- * * setObjectDescription -- * * Set the description of a given Object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectDescription(Object *objectPtr, char *description, Parser *parserPtr) { if (objectPtr->export.description) smiFree(objectPtr->export.description); if (parserPtr->flags & SMI_FLAG_NODESCR) { smiFree(description); objectPtr->export.description = NULL; } else { objectPtr->export.description = description; } } /* *---------------------------------------------------------------------- * * setObjectReference -- * * Set the reference of a given Object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectReference(Object *objectPtr, char *reference, Parser *parserPtr) { if (objectPtr->export.reference) smiFree(objectPtr->export.reference); if (parserPtr->flags & SMI_FLAG_NODESCR) { smiFree(reference); objectPtr->export.reference = NULL; } else { objectPtr->export.reference = reference; } } /* *---------------------------------------------------------------------- * * setObjectFormat -- * * Set the format of a given Object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectFormat(Object *objectPtr, char *format) { if (objectPtr->export.format) smiFree(objectPtr->export.format); objectPtr->export.format = format; } /* *---------------------------------------------------------------------- * * setObjectUnits -- * * Set the units of a given Object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectUnits(Object *objectPtr, char *units) { if (objectPtr->export.units) smiFree(objectPtr->export.units); objectPtr->export.units = units; } /* *---------------------------------------------------------------------- * * setObjectDecl -- * * Set the declaring macro of a given Object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectDecl(Object *objectPtr, SmiDecl decl) { objectPtr->export.decl = decl; } /* *---------------------------------------------------------------------- * * setObjectLine -- * * Set the line of definition of a given Object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectLine(Object *objectPtr, int line, Parser *parserPtr) { if (line) { objectPtr->line = line; } else { objectPtr->line = parserPtr ? parserPtr->line : -1; } } /* *---------------------------------------------------------------------- * * setObjectNodekind -- * * Set the language independant SmiNodekind of a given Object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectNodekind(Object *objectPtr, SmiNodekind nodekind) { objectPtr->export.nodekind = nodekind; } /* *---------------------------------------------------------------------- * * addObjectFlags -- * * Add flags to the flags of a given Object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void addObjectFlags(Object *objectPtr, ObjectFlags flags) { objectPtr->flags |= flags; } /* *---------------------------------------------------------------------- * * deleteObjectFlags -- * * Delete flags from the flags of a given Object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void deleteObjectFlags(Object *objectPtr, ObjectFlags flags) { objectPtr->flags &= ~flags; } /* *---------------------------------------------------------------------- * * checkObjectFlag -- * * Check whether a given set of flags of a given Object are all set. * * Results: * true if all named flags are set. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) int checkObjectFlags(Object *objectPtr, ObjectFlags flags) { return ((objectPtr->flags & flags) == flags); } /* *---------------------------------------------------------------------- * * setObjectIndex -- * * Set the list of INDEX elements of a given Object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ /* TODO remove me void setObjectIndex(Object *objectPtr, Index *indexPtr) Object *objectPtr; Index *indexPtr; { objectPtr->indexPtr = indexPtr; } */ /* *---------------------------------------------------------------------- * * setObjectList -- * * Set the list of objects of a notification type or object group * or the list of notifications of a notification group. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectList(Object *objectPtr, List *listPtr) { objectPtr->listPtr = listPtr; } /* *---------------------------------------------------------------------- * * setObjectRelated -- * * Set the related object of a given object (e.g. SMIv2 AUGMENTS) * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectRelated(Object *objectPtr, Object *relatedPtr) { objectPtr->relatedPtr = relatedPtr; } /* *---------------------------------------------------------------------- * * setObjectImplied -- * * Set the implied flag of a given object * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectImplied(Object *objectPtr, int implied) { objectPtr->export.implied = implied; } /* *---------------------------------------------------------------------- * * setObjectCreate -- * * Set the create flag of a given (table entry) object * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectCreate(Object *objectPtr, int create) { objectPtr->export.create = create; } /* *---------------------------------------------------------------------- * * setObjectIndexkind -- * * Set the indexkind of a given (table entry) object * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectIndexkind(Object *objectPtr, SmiIndexkind indexkind) { objectPtr->export.indexkind = indexkind; } /* *---------------------------------------------------------------------- * * setObjectValue -- * * Set the default value pointer of a given Object. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectValue(Object *objectPtr, SmiValue *valuePtr) { objectPtr->export.value = *valuePtr; smiFree(valuePtr); } /* *---------------------------------------------------------------------- * * setObjectUniqueness -- * * Set the uniqueness entry of an object * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setObjectUniqueness(Object *objectPtr, List *listPtr) { objectPtr->uniquenessPtr = listPtr; } /* *---------------------------------------------------------------------- * * setObjectInstallErrors -- * * Set the install errors entry of an object * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ /*void setObjectInstallErrors(Object *objectPtr, List *listPtr) { objectPtr->installErrorsPtr = listPtr; }*/ /* *---------------------------------------------------------------------- * * findNodeByParentAndSubid -- * * Lookup a Node by a given parent and subid value. * * Results: * A pointer to the Node structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Node *findNodeByParentAndSubid(Node *parentNodePtr, SmiSubid subid) { Node *nodePtr; if (parentNodePtr && (parentNodePtr != smiHandle->parserPtr->pendingNodePtr)) { for (nodePtr = parentNodePtr->firstChildPtr; nodePtr; nodePtr = nodePtr->nextPtr) { if (nodePtr->subid == subid) { return (nodePtr); } } } return (NULL); } /* *---------------------------------------------------------------------- * * findNodeByOid -- * * Lookup a Node by a given array of numerical subids. * * Results: * A pointer to the Node structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Node *findNodeByOid(unsigned int oidlen, SmiSubid *oid) { Node *nodePtr; unsigned int i; nodePtr = smiHandle->rootNodePtr; for(i = 0; i < oidlen && nodePtr; i++) { nodePtr = findNodeByParentAndSubid(nodePtr, oid[i]); } return (nodePtr); } /* *---------------------------------------------------------------------- * * findNodeByOidString -- * * Lookup a Node by a given string of concatinated numerical subids. * * Results: * A pointer to the Node structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Node *findNodeByOidString(char *oid) { Node *nodePtr; char *s; char *p; s = smiStrdup(oid); nodePtr = smiHandle->rootNodePtr; for(p = strtok(s, ". "); p && nodePtr; p = strtok(NULL, ". ")) { nodePtr = findNodeByParentAndSubid(nodePtr, atoi(p)); } smiFree(s); return (nodePtr); } /* *---------------------------------------------------------------------- * * findObjectByNode -- * * Lookup an Object by a given Node. Note, that there might be * multiple definitions for one node. * * Results: * A pointer to the first Object structure in the current View or * a pointer to the first Object if none is in the current View or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Object *findObjectByNode(Node *nodePtr) { Object *objectPtr; Object *goodObjectPtr = NULL; /* first, try to find an object in the current view. */ for (objectPtr = nodePtr->firstObjectPtr; objectPtr; objectPtr = objectPtr->nextSameNodePtr) { if (isInView(objectPtr->modulePtr->export.name)) { if (! goodObjectPtr) { goodObjectPtr = objectPtr; } else if (objectPtr->modulePtr->export.language > goodObjectPtr->modulePtr->export.language) { goodObjectPtr = objectPtr; } } } return goodObjectPtr ? goodObjectPtr : nodePtr->firstObjectPtr; } /* *---------------------------------------------------------------------- * * findObjectByModuleAndNode -- * * Lookup an Object by a given Node and Module. This is necessary * since there might be different declarations in different modules * for the same OID. * * Results: * A pointer to the Object structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Object *findObjectByModuleAndNode(Module *modulePtr, Node *nodePtr) { Object *objectPtr; for (objectPtr = nodePtr->firstObjectPtr; objectPtr; objectPtr = objectPtr->nextSameNodePtr) { if (objectPtr->modulePtr == modulePtr) { return (objectPtr); } } return (NULL); } /* *---------------------------------------------------------------------- * * findObjectByModulenameAndNode -- * * Lookup an Object by a given Node and Modulename. This is necessary * since there might be different declarations in different modules * for the same OID. * * Results: * A pointer to the Object structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Object *findObjectByModulenameAndNode(const char *modulename, Node *nodePtr) { Object *objectPtr; for (objectPtr = nodePtr->firstObjectPtr; objectPtr; objectPtr = objectPtr->nextSameNodePtr) { if (!strcmp(objectPtr->modulePtr->export.name, modulename)) { return (objectPtr); } } return (NULL); } /* *---------------------------------------------------------------------- * * findObjectByName -- * * Lookup an Object by a given name. Note, that * there might be more than one Object with the same name. * In this case, it is undefined which Object is returned. * * Results: * A pointer to the Object structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Object *findObjectByName(const char *objectname) { Module *modulePtr; Object *objectPtr; for (modulePtr = smiHandle->firstModulePtr; modulePtr; modulePtr = modulePtr->nextPtr) { for (objectPtr = modulePtr->firstObjectPtr; objectPtr; objectPtr = objectPtr->nextPtr) { if ((objectPtr->export.name) && !strcmp(objectPtr->export.name, objectname)) { /* * We return the first matching object. * TODO: probably we should check if there are more matching * objects, and give a warning if there's another one. */ return (objectPtr); } } } return (NULL); } /* *---------------------------------------------------------------------- * * findNextObjectByName -- * * Lookup the next Object by a given name. Note, that * there might be more than one Object with the same name. * * Results: * A pointer to the Object structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Object *findNextObjectByName(const char *objectname, Object *prevObjectPtr) { Module *modulePtr; Object *objectPtr; for (modulePtr = prevObjectPtr->modulePtr->nextPtr; modulePtr; modulePtr = modulePtr->nextPtr) { for (objectPtr = modulePtr->firstObjectPtr; objectPtr; objectPtr = objectPtr->nextPtr) { if ((objectPtr->export.name) && !strcmp(objectPtr->export.name, objectname)) { /* * We return the first matching object. * TODO: probably we should check if there are more matching * objects, and give a warning if there's another one. */ return (objectPtr); } } } return (NULL); } /* *---------------------------------------------------------------------- * * findObjectByModulenameAndName -- * * Lookup a Object by a given Module and name. * * Results: * A pointer to the Object structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Object *findObjectByModulenameAndName(const char *modulename, const char *objectname) { Module *modulePtr; Object *objectPtr; modulePtr = findModuleByName(modulename); if (modulePtr) { for (objectPtr = modulePtr->firstObjectPtr; objectPtr; objectPtr = objectPtr->nextPtr) { if ((objectPtr->export.name) && !strcmp(objectPtr->export.name, objectname)) { return (objectPtr); } } } /* * Some toplevel Objects seem to be always known. */ if ((!strcmp(objectname, "iso")) || (!strcmp(objectname, "ccitt")) || (!strcmp(objectname, "joint-iso-ccitt"))) { return findObjectByName(objectname); } return (NULL); } /* *---------------------------------------------------------------------- * * findObjectByModuleAndName -- * * Lookup a Object by a given Module and name. * * Results: * A pointer to the Object structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Object *findObjectByModuleAndName(Module *modulePtr, const char *objectname) { Object *objectPtr; if (! objectname) { return NULL; } if (modulePtr) { for (objectPtr = modulePtr->firstObjectPtr; objectPtr; objectPtr = objectPtr->nextPtr) { if ((objectPtr->export.name) && !strcmp(objectPtr->export.name, objectname)) { return (objectPtr); } } } /* * Some toplevel Objects seem to be always known. */ if ((!strcmp(objectname, "iso")) || (!strcmp(objectname, "ccitt")) || (!strcmp(objectname, "joint-iso-ccitt"))) { return findObjectByName(objectname); } return (NULL); } /* *---------------------------------------------------------------------- * * addType -- * * Create a new Type structure. * * Results: * A pointer to the new Type structure or * NULL if terminated due to an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Type *addType(char *type_name, SmiBasetype basetype, TypeFlags flags, Parser *parserPtr) { Type *typePtr; Module *modulePtr; modulePtr = parserPtr ? parserPtr->modulePtr : NULL; typePtr = smiMalloc(sizeof(Type)); typePtr->export.name = type_name; typePtr->export.basetype = basetype; typePtr->export.decl = SMI_DECL_UNKNOWN; typePtr->export.format = NULL; typePtr->export.value.basetype = SMI_BASETYPE_UNKNOWN; typePtr->export.units = NULL; typePtr->export.status = SMI_STATUS_UNKNOWN; typePtr->export.description = NULL; typePtr->export.reference = NULL; typePtr->modulePtr = modulePtr; typePtr->listPtr = NULL; typePtr->flags = flags; typePtr->parentPtr = NULL; typePtr->line = parserPtr ? parserPtr->line : -1; typePtr->nextPtr = NULL; if (modulePtr) { typePtr->prevPtr = modulePtr->lastTypePtr; if (!modulePtr->firstTypePtr) modulePtr->firstTypePtr = typePtr; if (modulePtr->lastTypePtr) modulePtr->lastTypePtr->nextPtr = typePtr; modulePtr->lastTypePtr = typePtr; } else { typePtr->prevPtr = NULL; } return (typePtr); } /* *---------------------------------------------------------------------- * * duplicateType -- * * Create a new Type as a duplicate of a given one but with * an affiliation to the current module. * * Results: * A pointer to the new Type structure or * NULL if terminated due to an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Type *duplicateType(Type *templatePtr, TypeFlags flags, Parser *parserPtr) { Type *typePtr; Module *modulePtr; typePtr = (Type *) smiMalloc(sizeof(Type)); modulePtr = parserPtr->modulePtr; typePtr->export.name = NULL; typePtr->export.basetype = templatePtr->export.basetype; typePtr->export.decl = SMI_DECL_IMPLICIT_TYPE; typePtr->export.format = NULL; typePtr->export.value.basetype = SMI_BASETYPE_UNKNOWN; typePtr->export.units = NULL; typePtr->export.status = templatePtr->export.status; typePtr->export.description = NULL; typePtr->export.reference = NULL; typePtr->modulePtr = modulePtr; typePtr->listPtr = NULL; typePtr->flags = templatePtr->flags; typePtr->line = parserPtr ? parserPtr->line : -1; typePtr->nextPtr = NULL; typePtr->prevPtr = modulePtr->lastTypePtr; if (!modulePtr->firstTypePtr) modulePtr->firstTypePtr = typePtr; if (modulePtr->lastTypePtr) modulePtr->lastTypePtr->nextPtr = typePtr; modulePtr->lastTypePtr = typePtr; setTypeParent(typePtr, templatePtr); return (typePtr); } /* *---------------------------------------------------------------------- * * setTypeName -- * * Set the name of a given Type. If it already exists, merge the * two types. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Type *setTypeName(Type *typePtr, char *name) { Type *type2Ptr; List *listPtr; if (typePtr->export.name) { smiFree(typePtr->export.name); } typePtr->export.name = smiStrdup(name); if (! typePtr->export.name) { return typePtr; } /* * If a type with this name already exists, it must be a forward * reference and both types have to be merged. */ for (type2Ptr = typePtr->modulePtr->firstTypePtr; type2Ptr; type2Ptr = type2Ptr->nextPtr) { if (type2Ptr->export.name && (!strcmp(type2Ptr->export.name, name)) && (type2Ptr != typePtr)) { /* * remove typePtr from the type list. */ if (typePtr->prevPtr) { typePtr->prevPtr->nextPtr = typePtr->nextPtr; } else { typePtr->modulePtr->firstTypePtr = typePtr->nextPtr; } if (typePtr->nextPtr) { typePtr->nextPtr->prevPtr = typePtr->prevPtr; } else { typePtr->modulePtr->lastTypePtr = typePtr->prevPtr; } type2Ptr->export.basetype = typePtr->export.basetype; type2Ptr->export.decl = typePtr->export.decl; type2Ptr->export.format = typePtr->export.format; type2Ptr->export.value = typePtr->export.value; type2Ptr->export.units = typePtr->export.units; type2Ptr->export.status = typePtr->export.status; type2Ptr->export.description = typePtr->export.description; type2Ptr->export.reference = typePtr->export.reference; type2Ptr->parentPtr = typePtr->parentPtr; type2Ptr->listPtr = typePtr->listPtr; type2Ptr->flags = typePtr->flags; type2Ptr->line = typePtr->line; /* * if it's an enum or bits type, we also have to adjust * the references from the named numbers back to the type. */ if ((type2Ptr->export.basetype == SMI_BASETYPE_ENUM) || (type2Ptr->export.basetype == SMI_BASETYPE_BITS)) { for (listPtr = type2Ptr->listPtr; listPtr; listPtr = listPtr->nextPtr) { ((NamedNumber *)(listPtr->ptr))->typePtr = type2Ptr; } } smiFree(typePtr->export.name); smiFree(typePtr); return type2Ptr; } } return typePtr; } /* *---------------------------------------------------------------------- * * setTypeParent -- * * Set the parent of a given Type. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setTypeParent(Type *typePtr, Type *parentPtr) { typePtr->parentPtr = parentPtr; } /* *---------------------------------------------------------------------- * * setTypeStatus -- * * Set the status of a given Type. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setTypeStatus(Type *typePtr, SmiStatus status) { typePtr->export.status = status; } /* *---------------------------------------------------------------------- * * setTypeBasetype -- * * Set the basetype of a given Type. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setTypeBasetype(Type *typePtr, SmiBasetype basetype) { typePtr->export.basetype = basetype; } /* *---------------------------------------------------------------------- * * setTypeDescription -- * * Set the description of a given Type. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setTypeDescription(Type *typePtr, char *description, Parser *parserPtr) { if (typePtr->export.description) smiFree(typePtr->export.description); if (parserPtr->flags & SMI_FLAG_NODESCR) { smiFree(description); typePtr->export.description = NULL; } else { typePtr->export.description = description; } } /* *---------------------------------------------------------------------- * * setTypeReference -- * * Set the reference of a given Type. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setTypeReference(Type *typePtr, char *reference, Parser *parserPtr) { if (typePtr->export.reference) smiFree(typePtr->export.reference); if (parserPtr->flags & SMI_FLAG_NODESCR) { smiFree(reference); typePtr->export.reference = NULL; } else { typePtr->export.reference = reference; } } /* *---------------------------------------------------------------------- * * setTypeList -- * * Set the pointer to a struct list. This used for * - columns of a SEQUENCE type, * - enumeration items of an enumeration integer type, * - min-max pair items of a range restricted type, * - min-max pars items of a size restricted type. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setTypeList(Type *typePtr, List *listPtr) { if (!typePtr->listPtr) { typePtr->listPtr = listPtr; } } /* *---------------------------------------------------------------------- * * setTypeFormat -- * * Set the format (displayHint) of a given Type. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setTypeFormat(Type *typePtr, char *format) { if (typePtr->export.format) smiFree(typePtr->export.format); typePtr->export.format = format; } /* *---------------------------------------------------------------------- * * setTypeUnits -- * * Set the units of a given Type. Note: units of types are only * present in SMIng, not in SMIv2. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setTypeUnits(Type *typePtr, char *units) { if (typePtr->export.units) smiFree(typePtr->export.units); typePtr->export.units = units; } /* *---------------------------------------------------------------------- * * setTypeDecl -- * * Set the declaring macro of a given Type. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setTypeDecl(Type *typePtr, SmiDecl decl) { typePtr->export.decl = decl; } /* *---------------------------------------------------------------------- * * setTypeLine -- * * Set the line of definition of a given Type. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setTypeLine(Type *typePtr, int line, Parser *parserPtr) { if (line) { typePtr->line = line; } else { typePtr->line = parserPtr ? parserPtr->line : -1; } } /* *---------------------------------------------------------------------- * * setTypeValue -- * * Set the default value pointer of a given Type. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setTypeValue(Type *typePtr, SmiValue *valuePtr) { typePtr->export.value = *valuePtr; } /* *---------------------------------------------------------------------- * * addTypeFlags -- * * Add flags to the flags of a given Type. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void addTypeFlags(Type *typePtr, TypeFlags flags) { typePtr->flags |= flags; } /* *---------------------------------------------------------------------- * * deleteTypeFlags -- * * Delete flags from the flags of a given Type. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void deleteTypeFlags(Type *typePtr, TypeFlags flags) { typePtr->flags &= ~flags; } /* *---------------------------------------------------------------------- * * findTypeByName -- * * Lookup a Type by a given name. * * Results: * A pointer to the Type structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Type * findTypeByName(const char *type_name) { Module *modulePtr; Type *typePtr; for (modulePtr = smiHandle->firstModulePtr; modulePtr; modulePtr = modulePtr->nextPtr) { for (typePtr = modulePtr->firstTypePtr; typePtr; typePtr = typePtr->nextPtr) { if ((typePtr->export.name) && !strcmp(typePtr->export.name, type_name)) { return (typePtr); } } } return (NULL); } /* *---------------------------------------------------------------------- * * findNextTypeByName -- * * Lookup the next Type by a given name. * * Results: * A pointer to the Type structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Type *findNextTypeByName(const char *type_name, Type *prevTypePtr) { Module *modulePtr; Type *typePtr; for (modulePtr = prevTypePtr->modulePtr->nextPtr; modulePtr; modulePtr = modulePtr->nextPtr) { for (typePtr = modulePtr->firstTypePtr; typePtr; typePtr = typePtr->nextPtr) { if ((typePtr->export.name) && !strcmp(typePtr->export.name, type_name)) { return (typePtr); } } } return (NULL); } /* *---------------------------------------------------------------------- * * findTypeByModulenameAndName -- * * Lookup a Type by a given Module and name. * * Results: * A pointer to the Type structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Type *findTypeByModulenameAndName(const char *modulename, const char *type_name) { Type *typePtr; Module *modulePtr; modulePtr = findModuleByName(modulename); if (modulePtr) { for (typePtr = modulePtr->firstTypePtr; typePtr; typePtr = typePtr->nextPtr) { if ((typePtr->export.name) && !strcmp(typePtr->export.name, type_name)) { return (typePtr); } } } return (NULL); } /* *---------------------------------------------------------------------- * * findTypeByModuleAndName -- * * Lookup a Type by a given Module and name. * * Results: * A pointer to the Type structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Type *findTypeByModuleAndName(Module *modulePtr, const char *type_name) { Type *typePtr; if (modulePtr) { for (typePtr = modulePtr->firstTypePtr; typePtr; typePtr = typePtr->nextPtr) { if ((typePtr->export.name) && !strcmp(typePtr->export.name, type_name)) { return (typePtr); } } } return (NULL); } /* *---------------------------------------------------------------------- * * findTypeNamedNumber -- * * * * Results: * * Side effects: * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) NamedNumber *findTypeNamedNumber(Type *typePtr, SmiInteger32 number) { List *listPtr; for (listPtr = typePtr->listPtr; listPtr; listPtr = listPtr->nextPtr) { if (((NamedNumber *)(listPtr->ptr))->export.value.value.integer32 == number) break; } return (NamedNumber *)(listPtr->ptr); } /* *---------------------------------------------------------------------- * * addIdentity -- * * Create a new Identity structure. * * Results: * A pointer to the new Identity structure or * NULL if terminated due to an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Identity *addIdentity(char *identityname, Parser *parserPtr) { Identity *identityPtr; Module *modulePtr; modulePtr = parserPtr->modulePtr; identityPtr = (Identity*) smiMalloc(sizeof(Identity)); identityPtr->export.name = identityname; identityPtr->export.status = SMI_STATUS_UNKNOWN; identityPtr->export.description = NULL; identityPtr->export.reference = NULL; identityPtr->parentPtr = NULL; identityPtr->modulePtr = parserPtr->modulePtr; identityPtr->line = parserPtr ? parserPtr->line : -1; identityPtr->nextPtr = NULL; identityPtr->prevPtr = modulePtr->lastIdentityPtr; if (!modulePtr->firstIdentityPtr) modulePtr->firstIdentityPtr = identityPtr; if (modulePtr->lastIdentityPtr) modulePtr->lastIdentityPtr->nextPtr = identityPtr; modulePtr->lastIdentityPtr = identityPtr; return (identityPtr); } /* *---------------------------------------------------------------------- * * setIdentityDecl -- * * Set the declaring macro of a given Identity. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setIdentityDecl(Identity *identityPtr, SmiDecl decl) { identityPtr->export.decl = decl; } /* *---------------------------------------------------------------------- * * setIdentityStatus -- * * Set the status of a given Identity. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setIdentityStatus(Identity *identityPtr, SmiStatus status) { identityPtr->export.status = status; } /* *---------------------------------------------------------------------- * * setIdentityDescription -- * * Set the description of a given Identity. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setIdentityDescription(Identity *identityPtr, char *description, Parser *parserPtr) { if (identityPtr->export.description) smiFree(identityPtr->export.description); if (parserPtr->flags & SMI_FLAG_NODESCR) { smiFree(description); identityPtr->export.description = NULL; } else { identityPtr->export.description = description; } } /* *---------------------------------------------------------------------- * * setIdentityReference -- * * Set the reference of a given Identity. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setIdentityReference(Identity *identityPtr, char *reference, Parser *parserPtr) { if (identityPtr->export.reference) smiFree(identityPtr->export.reference); if (parserPtr->flags & SMI_FLAG_NODESCR) { smiFree(reference); identityPtr->export.reference = NULL; } else { identityPtr->export.reference = reference; } } /* *---------------------------------------------------------------------- * * setIdentityParent -- * * Set the parent of a given Identity to given Identity pointer. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setIdentityParent(Identity *identityPtr, Identity *parentPtr) { if(identityPtr) identityPtr->parentPtr = parentPtr; } /* *---------------------------------------------------------------------- * * findIdentityByName -- * * Lookup a Identity by a given name. * * Results: * A pointer to the Identity structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Identity *findIdentityByName(const char *identityname) { Module *modulePtr; Identity *identityPtr; for (modulePtr = smiHandle->firstModulePtr; modulePtr; modulePtr = modulePtr->nextPtr) { for (identityPtr = modulePtr->firstIdentityPtr; identityPtr; identityPtr = identityPtr->nextPtr) { if ((identityPtr->export.name) && !strcmp(identityPtr->export.name, identityname)) { return (identityPtr); } } } return (NULL); } /* *---------------------------------------------------------------------- * * findIdentityByModuleAndName -- * * Lookup a Identity by a given name and Module. * * Results: * A pointer to the Identity structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Identity *findIdentityByModuleAndName(Module *modulePtr, const char *identityname) { Identity *identityPtr; for (identityPtr = modulePtr->firstIdentityPtr; identityPtr; identityPtr = identityPtr->nextPtr) { if ((identityPtr->export.name) && !strcmp(identityPtr->export.name, identityname)) { return (identityPtr); } } return (NULL); } /* *---------------------------------------------------------------------- * * findIdentityByModulenameAndName -- * * Lookup a Identity by a given Module and name. * * Results: * A pointer to the Identity structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Identity *findIdentityByModulenameAndName(const char *modulename, const char *identity_name) { Identity *identityPtr; Module *modulePtr; modulePtr = findModuleByName(modulename); if (modulePtr) { for (identityPtr = modulePtr->firstIdentityPtr; identityPtr; identityPtr = identityPtr->nextPtr) { if ((identityPtr->export.name) && !strcmp(identityPtr->export.name, identity_name)) { return (identityPtr); } } } return (NULL); } /* *---------------------------------------------------------------------- * * addClass -- * * Create a new Class structure. * * Results: * A pointer to the new Class structure or * NULL if terminated due to an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Class *addClass(char *classname, Parser *parserPtr) { Class *classPtr; Module *modulePtr; modulePtr = parserPtr->modulePtr; classPtr = (Class*) smiMalloc(sizeof(Class)); classPtr->export.name = classname; classPtr->export.status = SMI_STATUS_UNKNOWN; classPtr->export.description = NULL; classPtr->export.reference = NULL; classPtr->modulePtr = parserPtr->modulePtr; classPtr->line = parserPtr ? parserPtr->line : -1; classPtr->parentPtr = NULL; classPtr->firstAttributePtr = NULL; classPtr->lastAttributePtr = NULL; classPtr->firstEventPtr = NULL; classPtr->lastEventPtr = NULL; classPtr->nextPtr = NULL; classPtr->prevPtr = modulePtr->lastClassPtr; if (!modulePtr->firstClassPtr) modulePtr->firstClassPtr = classPtr; if (modulePtr->lastClassPtr) modulePtr->lastClassPtr->nextPtr = classPtr; modulePtr->lastClassPtr = classPtr; return (classPtr); } /* *---------------------------------------------------------------------- * * setClassDecl -- * * Set the declaring macro of a given Class. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setClassDecl(Class *classPtr, SmiDecl decl) { classPtr->export.decl = decl; } /* *---------------------------------------------------------------------- * * setClassStatus -- * * Set the status of a given Class. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setClassStatus(Class *classPtr, SmiStatus status) { classPtr->export.status = status; } /* *---------------------------------------------------------------------- * * setClassDescription -- * * Set the description of a given Class. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setClassDescription(Class *classPtr, char *description, Parser *parserPtr) { if (classPtr->export.description) smiFree(classPtr->export.description); if (parserPtr->flags & SMI_FLAG_NODESCR) { smiFree(description); classPtr->export.description = NULL; } else { classPtr->export.description = description; } } /* *---------------------------------------------------------------------- * * setClassReference -- * * Set the reference of a given Class. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setClassReference(Class *classPtr, char *reference, Parser *parserPtr) { if (classPtr->export.reference) smiFree(classPtr->export.reference); if (parserPtr->flags & SMI_FLAG_NODESCR) { smiFree(reference); classPtr->export.reference = NULL; } else { classPtr->export.reference = reference; } } /* *---------------------------------------------------------------------- * * setClassParent -- * * Set the parent of a given Class to given Class pointer. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setClassParent(Class *classPtr, Class *parentPtr) { if(classPtr) classPtr->parentPtr = parentPtr; } /* *---------------------------------------------------------------------- * * findClassByModuleAndName -- * * Lookup a Class by a given name. * * Results: * A pointer to the Class structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Class *findClassByModuleAndName(Module *modulePtr,char *name) { Class *classPtr; for (classPtr = modulePtr->firstClassPtr; classPtr; classPtr = classPtr->nextPtr) { if ((classPtr->export.name) && !strcmp(classPtr->export.name, name)) { return (classPtr); } } return NULL; } /* *---------------------------------------------------------------------- * * findClassByModulenameAndName -- * * Lookup a Class by a given Module and name. * * Results: * A pointer to the Class structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Class *findClassByModulenameAndName(const char *modulename, const char *class_name) { Class *classPtr; Module *modulePtr; modulePtr = findModuleByName(modulename); if (modulePtr) { for (classPtr = modulePtr->firstClassPtr; classPtr; classPtr = classPtr->nextPtr) { if ((classPtr->export.name) && !strcmp(classPtr->export.name, class_name)) { return (classPtr); } } } return (NULL); } /* *---------------------------------------------------------------------- * * duplicateTypeToAttribute -- * * Create a new Attribute as a duplicate of a given type but with * an affiliation to the given Class. * * Results: * A pointer to the new Attribute structure or * NULL if terminated due to an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Attribute *duplicateTypeToAttribute(Type *templatePtr, Class *classPtr, Parser *parserPtr) { Attribute *attributePtr; if(!classPtr) return NULL; attributePtr = (Attribute *) smiMalloc(sizeof(Attribute)); attributePtr->export.name = NULL; attributePtr->export.basetype = templatePtr->export.basetype; attributePtr->export.decl = SMI_DECL_ATTRIBUTE; attributePtr->export.format = NULL; attributePtr->export.value.basetype = templatePtr->export.basetype; attributePtr->export.units = NULL; attributePtr->export.status = templatePtr->export.status; attributePtr->export.description = NULL; attributePtr->export.reference = NULL; attributePtr->classPtr = classPtr; attributePtr->listPtr = NULL; attributePtr->line = parserPtr ? parserPtr->line : -1; attributePtr->nextPtr = NULL; attributePtr->prevPtr = classPtr->lastAttributePtr; if (!classPtr->firstAttributePtr) classPtr->firstAttributePtr = attributePtr; if (classPtr->lastAttributePtr) classPtr->lastAttributePtr->nextPtr = attributePtr; classPtr->lastAttributePtr = attributePtr; setAttributeParentType(attributePtr, templatePtr); return (attributePtr); } /* *---------------------------------------------------------------------- * * addAttribute -- * * Create a new Attribute structure and tie it to the given Class. * * Results: * A pointer to the new Attribute structure or * NULL if terminated due to an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Attribute *addAttribute(char *attribute_name, Class *classPtr, Parser *parserPtr) { Attribute *attributePtr; attributePtr = smiMalloc(sizeof(Attribute)); attributePtr->export.name = attribute_name; attributePtr->export.basetype = SMI_BASETYPE_UNKNOWN; attributePtr->export.decl = SMI_DECL_UNKNOWN; attributePtr->export.format = NULL; attributePtr->export.value.basetype = SMI_BASETYPE_UNKNOWN; attributePtr->export.units = NULL; attributePtr->export.status = SMI_STATUS_UNKNOWN; attributePtr->export.description = NULL; attributePtr->export.reference = NULL; attributePtr->classPtr = classPtr; attributePtr->listPtr = NULL; attributePtr->parentTypePtr = NULL; attributePtr->parentClassPtr = NULL; attributePtr->line = parserPtr ? parserPtr->line : -1; attributePtr->nextPtr = NULL; if (classPtr) { attributePtr->prevPtr = classPtr->lastAttributePtr; if (!classPtr->firstAttributePtr) classPtr->firstAttributePtr = attributePtr; if (classPtr->lastAttributePtr) classPtr->lastAttributePtr->nextPtr = attributePtr; classPtr->lastAttributePtr = attributePtr; } else { attributePtr->prevPtr = NULL; } return (attributePtr); } /* *---------------------------------------------------------------------- * * setAttributeDecl -- * * Set the declaring macro of a given Attribute. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setAttributeDecl(Attribute *attributePtr, SmiDecl decl) { attributePtr->export.decl = decl; } /* *---------------------------------------------------------------------- * * setAttributeParentType -- * * Set the parent of a given attribute. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setAttributeParentType(Attribute *attributePtr, Type *parentPtr) { attributePtr->parentTypePtr = parentPtr; } /* *---------------------------------------------------------------------- * * setAttributeParentClass -- * * Set the parent Class of a given attribute. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setAttributeParentClass(Attribute *attributePtr, Class *parentPtr) { attributePtr->parentClassPtr = parentPtr; } /* *---------------------------------------------------------------------- * * setAttributeList -- * * Set the pointer to a struct list. This used for * - enumeration items of an enumeration integer type, * - min-max pair items of a range restricted type, * - min-max pars items of a size restricted type. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setAttributeList(Attribute *attributePtr, List *listPtr) { if (!attributePtr->listPtr) { attributePtr->listPtr = listPtr; } } /* *---------------------------------------------------------------------- * * setAttributeName -- * * Set the name of a given Attribute. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setAttributeName(Attribute *attributePtr, char *name) { attributePtr->export.name = smiStrdup(name); } /* *---------------------------------------------------------------------- * * setAttributeAccess -- * * Set the access of a given Attribute. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setAttributeAccess(Attribute *attributePtr,SmiAccess access) { attributePtr->export.access = access; } /* *---------------------------------------------------------------------- * * addEvent -- * * Create a new Event structure and tie it to the given Class. * * Results: * A pointer to the new Event structure or * NULL if terminated due to an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Event *addEvent(char *eventname, Class *classPtr, Parser *parserPtr) { Event *eventPtr; eventPtr = smiMalloc(sizeof(Event)); eventPtr->export.name = eventname; eventPtr->export.decl = SMI_DECL_EVENT; eventPtr->export.status = SMI_STATUS_UNKNOWN; eventPtr->export.description = NULL; eventPtr->export.reference = NULL; eventPtr->classPtr = classPtr; eventPtr->line = parserPtr ? parserPtr->line : -1; eventPtr->nextPtr = NULL; if (classPtr) { eventPtr->prevPtr = classPtr->lastEventPtr; if (!classPtr->firstEventPtr) classPtr->firstEventPtr = eventPtr; if (classPtr->lastEventPtr) classPtr->lastEventPtr->nextPtr = eventPtr; classPtr->lastEventPtr = eventPtr; } else { eventPtr->prevPtr = NULL; } return (eventPtr); } /* *---------------------------------------------------------------------- * * addMacro -- * * Create a new Macro structure. * * Results: * A pointer to the new Macro structure or * NULL if terminated due to an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Macro *addMacro(char *macroname, MacroFlags flags, Parser *parserPtr) { Macro *macroPtr; Module *modulePtr; modulePtr = parserPtr->modulePtr; /* TODO: Check wheather this macro already exists?? */ macroPtr = (Macro *) smiMalloc(sizeof(Macro)); macroPtr->export.name = macroname; macroPtr->export.status = SMI_STATUS_UNKNOWN; macroPtr->export.description = NULL; macroPtr->export.reference = NULL; macroPtr->modulePtr = parserPtr->modulePtr; macroPtr->flags = flags; macroPtr->line = parserPtr ? parserPtr->line : -1; macroPtr->nextPtr = NULL; macroPtr->prevPtr = modulePtr->lastMacroPtr; if (!modulePtr->firstMacroPtr) modulePtr->firstMacroPtr = macroPtr; if (modulePtr->lastMacroPtr) modulePtr->lastMacroPtr->nextPtr = macroPtr; modulePtr->lastMacroPtr = macroPtr; return (macroPtr); } /* *---------------------------------------------------------------------- * * setMacroStatus -- * * Set the status of a given Macro. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setMacroStatus(Macro *macroPtr, SmiStatus status) { macroPtr->export.status = status; } /* *---------------------------------------------------------------------- * * setMacroDescription -- * * Set the description of a given Macro. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setMacroDescription(Macro *macroPtr, char *description, Parser *parserPtr) { if (macroPtr->export.description) smiFree(macroPtr->export.description); if (parserPtr->flags & SMI_FLAG_NODESCR) { smiFree(description); macroPtr->export.description = NULL; } else { macroPtr->export.description = description; } } /* *---------------------------------------------------------------------- * * setMacroReference -- * * Set the reference of a given Macro. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setMacroReference(Macro *macroPtr, char *reference, Parser *parserPtr) { if (macroPtr->export.reference) smiFree(macroPtr->export.reference); if (parserPtr->flags & SMI_FLAG_NODESCR) { smiFree(reference); macroPtr->export.reference = NULL; } else { macroPtr->export.reference = reference; } } /* *---------------------------------------------------------------------- * * setMacroAbnf -- * * Set the abnf string of a given extension(SMIng only). * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setMacroAbnf(Macro *macroPtr, char *abnf, Parser *parserPtr) { if (macroPtr->export.abnf) smiFree(macroPtr->export.abnf); if (parserPtr->flags & SMI_FLAG_NODESCR) { smiFree(abnf); macroPtr->export.abnf = NULL; } else { macroPtr->export.abnf = abnf; } } /* *---------------------------------------------------------------------- * * setMacroDecl -- * * Set the declaring macro of a given Macro. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setMacroDecl(Macro *macroPtr, SmiDecl decl) { macroPtr->export.decl = decl; } /* *---------------------------------------------------------------------- * * setMacroLine -- * * Set the line of definition of a given Macro. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) void setMacroLine(Macro *macroPtr, int line, Parser *parserPtr) { if (line) { macroPtr->line = line; } else { macroPtr->line = parserPtr ? parserPtr->line : -1; } } /* *---------------------------------------------------------------------- * * findMacroByName -- * * Lookup a Macro by a given name. * * Results: * A pointer to the Macro structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Macro *findMacroByName(const char *macroname) { Module *modulePtr; Macro *macroPtr; for (modulePtr = smiHandle->firstModulePtr; modulePtr; modulePtr = modulePtr->nextPtr) { for (macroPtr = modulePtr->firstMacroPtr; macroPtr; macroPtr = macroPtr->nextPtr) { if ((macroPtr->export.name) && !strcmp(macroPtr->export.name, macroname)) { return (macroPtr); } } } return (NULL); } /* *---------------------------------------------------------------------- * * findMacroByModuleAndName -- * * Lookup a Macro by a given Module and name. * * Results: * A pointer to the Macro structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Macro *findMacroByModuleAndName(Module *modulePtr, const char *macroname) { Macro *macroPtr; if (modulePtr) { for (macroPtr = modulePtr->firstMacroPtr; macroPtr; macroPtr = macroPtr->nextPtr) { if (!strcmp(macroPtr->export.name, macroname)) { return (macroPtr); } } } return (NULL); } /* *---------------------------------------------------------------------- * * findNamedNumberByName -- * * Lookup the value of a namev nuber in a given typ. * * Results: * A pointer to the NamedNumber structure or * NULL if it is not found. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) NamedNumber *findNamedNumberByName(Type *typePtr,const char *name) { List *listPtr; if(typePtr->export.basetype != SMI_BASETYPE_ENUM && typePtr->export.basetype != SMI_BASETYPE_BITS) return NULL; for (listPtr = typePtr->listPtr; listPtr; listPtr = listPtr->nextPtr) { if (!strcmp(((NamedNumber *)(listPtr->ptr))->export.name , name)) return (NamedNumber *)(listPtr->ptr); } return NULL; } /* *---------------------------------------------------------------------- * * smiInitData -- * * Initialize all need data structures at program start. * * Results: * 0 on success or -1 on an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ int smiInitData() { Object *objectPtr; Parser parser; smiHandle->flags = 0; smiHandle->firstModulePtr = NULL; smiHandle->lastModulePtr = NULL; smiHandle->firstViewPtr = NULL; smiHandle->lastViewPtr = NULL; /* * Initialize a root Node for the main MIB tree. */ smiHandle->rootNodePtr = addNode(NULL, 0, NODE_FLAG_ROOT, NULL); /* * Initialize a root Node for pending (forward referenced) nodes. */ smiHandle->parserPtr = &parser; parser.pendingNodePtr = addNode(NULL, 0, NODE_FLAG_ROOT, NULL); /* * Initialize the top level well-known nodes, ccitt, iso, joint-iso-ccitt * belonging to a dummy module "". This is needed for SMIv1/v2. SMIng * defines it in a special SMIng module. */ parser.path = NULL; parser.flags = smiHandle->flags; parser.file = NULL; parser.line = -1; parser.modulePtr = addModule(smiStrdup(""), smiStrdup(""), 0, NULL); addView(""); objectPtr = addObject(smiStrdup("ccitt"), smiHandle->rootNodePtr, 0, 0, &parser); objectPtr->export.oid = objectPtr->nodePtr->oid = smiMalloc(sizeof(int)); objectPtr->export.oidlen = objectPtr->nodePtr->oidlen = 1; objectPtr->nodePtr->oid[0] = 0; objectPtr->export.nodekind = SMI_NODEKIND_NODE; objectPtr = addObject(smiStrdup("iso"), smiHandle->rootNodePtr, 1, 0, &parser); objectPtr->export.oid = objectPtr->nodePtr->oid = smiMalloc(sizeof(int)); objectPtr->export.oidlen = objectPtr->nodePtr->oidlen = 1; objectPtr->nodePtr->oid[0] = 1; objectPtr->export.nodekind = SMI_NODEKIND_NODE; objectPtr = addObject(smiStrdup("joint-iso-ccitt"), smiHandle->rootNodePtr, 2, 0, &parser); objectPtr->export.oid = objectPtr->nodePtr->oid = smiMalloc(sizeof(int)); objectPtr->export.oidlen = objectPtr->nodePtr->oidlen = 1; objectPtr->nodePtr->oid[0] = 2; objectPtr->export.nodekind = SMI_NODEKIND_NODE; smiHandle->typeOctetStringPtr = addType(smiStrdup("OctetString"), SMI_BASETYPE_OCTETSTRING, 0, &parser); smiHandle->typeObjectIdentifierPtr = addType(smiStrdup("ObjectIdentifier"), SMI_BASETYPE_OBJECTIDENTIFIER, 0, &parser); smiHandle->typeInteger32Ptr = addType(smiStrdup("Integer32"), SMI_BASETYPE_INTEGER32, 0, &parser); smiHandle->typeUnsigned32Ptr = addType(smiStrdup("Unsigned32"), SMI_BASETYPE_UNSIGNED32, 0, &parser); smiHandle->typeInteger64Ptr = addType(smiStrdup("Integer64"), SMI_BASETYPE_INTEGER64, 0, &parser); smiHandle->typeUnsigned64Ptr = addType(smiStrdup("Unsigned64"), SMI_BASETYPE_UNSIGNED64, 0, &parser); smiHandle->typeFloat32Ptr = addType(smiStrdup("Float32"), SMI_BASETYPE_FLOAT32, 0, &parser); smiHandle->typeFloat64Ptr = addType(smiStrdup("Float64"), SMI_BASETYPE_FLOAT64, 0, &parser); smiHandle->typeFloat128Ptr = addType(smiStrdup("Float128"), SMI_BASETYPE_FLOAT128, 0, &parser); smiHandle->typeEnumPtr = addType(smiStrdup("Enumeration"), SMI_BASETYPE_ENUM, 0, &parser); smiHandle->typeBitsPtr = addType(smiStrdup("Bits"), SMI_BASETYPE_BITS, 0, &parser); smiHandle->typePointerPtr = addType(smiStrdup("Pointer"), SMI_BASETYPE_POINTER, 0, &parser); return (0); } /* *---------------------------------------------------------------------- * * freeNodeTree -- * * Free all node of a node (sub)tree. * * Results: * 0 on success or -1 on an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ static void freeNodeTree(Node *rootPtr) { Node *nodePtr, *nextPtr; for (nodePtr = rootPtr->firstChildPtr; nodePtr; nodePtr = nextPtr) { nextPtr = nodePtr->nextPtr; freeNodeTree(nodePtr); smiFree(nodePtr->oid); smiFree(nodePtr); } rootPtr->firstChildPtr = NULL; rootPtr->lastChildPtr = NULL; rootPtr->firstObjectPtr = NULL; rootPtr->lastObjectPtr = NULL; rootPtr->nextPtr = NULL; rootPtr->prevPtr = NULL; rootPtr->parentPtr = NULL; } /* *---------------------------------------------------------------------- * * smiFreeData -- * * Free all data structures. * * Results: * 0 on success or -1 on an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ void smiFreeData() { View *viewPtr, *nextViewPtr; Macro *macroPtr, *nextMacroPtr; Module *modulePtr, *nextModulePtr; Import *importPtr, *nextImportPtr; Identity *identityPtr, *nextIdentityPtr; Revision *revisionPtr, *nextRevisionPtr; List *listPtr, *nextListPtr; Type *typePtr, *nextTypePtr; Class *classPtr, *nextClassPtr; Attribute *attributePtr, *nextAttributePtr; Event *eventPtr, *nextEventPtr; Object *objectPtr, *nextObjectPtr; for (viewPtr = smiHandle->firstViewPtr; viewPtr; viewPtr = nextViewPtr) { nextViewPtr = viewPtr->nextPtr; smiFree(viewPtr->name); smiFree(viewPtr); } /* * In this first module loop we remove each module's imports, * revisions, macros, and objects. */ for (modulePtr = smiHandle->firstModulePtr; modulePtr; modulePtr = nextModulePtr) { nextModulePtr = modulePtr->nextPtr; for (importPtr = modulePtr->firstImportPtr; importPtr; importPtr = nextImportPtr) { nextImportPtr = importPtr->nextPtr; smiFree(importPtr->export.module); smiFree(importPtr->export.name); smiFree(importPtr); } for (revisionPtr = modulePtr->firstRevisionPtr; revisionPtr; revisionPtr = nextRevisionPtr) { nextRevisionPtr = revisionPtr->nextPtr; smiFree(revisionPtr->export.description); smiFree(revisionPtr); } for (macroPtr = modulePtr->firstMacroPtr; macroPtr; macroPtr = nextMacroPtr) { nextMacroPtr = macroPtr->nextPtr; smiFree(macroPtr->export.name); smiFree(macroPtr->export.abnf); smiFree(macroPtr->export.reference); smiFree(macroPtr->export.description); smiFree(macroPtr); } for (identityPtr = modulePtr->firstIdentityPtr; identityPtr; identityPtr = nextIdentityPtr) { nextIdentityPtr = identityPtr->nextPtr; smiFree(identityPtr->export.name); smiFree(identityPtr->export.reference); smiFree(identityPtr->export.description); smiFree(identityPtr); } for (objectPtr = modulePtr->firstObjectPtr; objectPtr; objectPtr = nextObjectPtr) { nextObjectPtr = objectPtr->nextPtr; smiFree(objectPtr->export.name); smiFree(objectPtr->export.description); smiFree(objectPtr->export.reference); smiFree(objectPtr->export.format); smiFree(objectPtr->export.units); for (listPtr = objectPtr->listPtr; listPtr; listPtr = nextListPtr) { nextListPtr = listPtr->nextPtr; smiFree(listPtr); } for (listPtr = objectPtr->optionlistPtr; listPtr; listPtr = nextListPtr) { nextListPtr = listPtr->nextPtr; smiFree(((Option *)(listPtr->ptr))->export.description); smiFree((Option *)(listPtr->ptr)); smiFree(listPtr); } for (listPtr = objectPtr->refinementlistPtr; listPtr; listPtr = nextListPtr) { nextListPtr = listPtr->nextPtr; smiFree(((Refinement *)(listPtr->ptr))->export.description); smiFree((Refinement *)(listPtr->ptr)); smiFree(listPtr); } if (objectPtr->typePtr) { if ((objectPtr->typePtr->export.basetype == SMI_BASETYPE_OCTETSTRING || objectPtr->typePtr->export.basetype == SMI_BASETYPE_BITS)) { smiFree(objectPtr->export.value.value.ptr); } else if ((objectPtr->typePtr->export.basetype == SMI_BASETYPE_OBJECTIDENTIFIER) && (objectPtr->export.value.basetype == objectPtr->typePtr->export.basetype)) { smiFree(objectPtr->export.value.value.oid); } } smiFree(objectPtr); } for (classPtr = modulePtr->firstClassPtr; classPtr; classPtr = nextClassPtr) { nextClassPtr = classPtr->nextPtr; for (attributePtr = classPtr->firstAttributePtr; attributePtr; attributePtr = nextAttributePtr) { nextAttributePtr = attributePtr->nextPtr; for (listPtr = attributePtr->listPtr; listPtr; listPtr = nextListPtr) { nextListPtr = listPtr->nextPtr; if ((attributePtr->export.basetype == SMI_BASETYPE_BITS) || (attributePtr->export.basetype == SMI_BASETYPE_ENUM)) { smiFree(((NamedNumber *)(listPtr->ptr))->export.name); smiFree((NamedNumber *)(listPtr->ptr)); } else if ((attributePtr->export.basetype == SMI_BASETYPE_INTEGER32) || (attributePtr->export.basetype == SMI_BASETYPE_INTEGER64) || (attributePtr->export.basetype == SMI_BASETYPE_UNSIGNED32) || (attributePtr->export.basetype == SMI_BASETYPE_UNSIGNED64) || (attributePtr->export.basetype == SMI_BASETYPE_FLOAT32) || (attributePtr->export.basetype == SMI_BASETYPE_FLOAT64) || (attributePtr->export.basetype == SMI_BASETYPE_FLOAT128) || (attributePtr->export.basetype == SMI_BASETYPE_OCTETSTRING)) { smiFree((Range *)(listPtr->ptr)); } smiFree(listPtr); } smiFree(attributePtr->export.name); smiFree(attributePtr->export.format); smiFree(attributePtr->export.units); smiFree(attributePtr->export.description); smiFree(attributePtr->export.reference); smiFree(attributePtr); } for (eventPtr = classPtr->firstEventPtr; eventPtr; eventPtr = nextEventPtr) { nextEventPtr = eventPtr->nextPtr; smiFree(eventPtr->export.name); smiFree(eventPtr->export.reference); smiFree(eventPtr->export.description); } for (listPtr = classPtr->uniqueList; listPtr; listPtr = nextListPtr) { nextListPtr = listPtr->nextPtr; smiFree(listPtr); } smiFree(classPtr->export.name); smiFree(classPtr->export.description); smiFree(classPtr->export.reference); smiFree(classPtr); } } /* * In this second module loop we remove each module's types * and the modules themselves. This separation is required, because * we reference some types of foreign modules in the first loop. */ for (modulePtr = smiHandle->firstModulePtr; modulePtr; modulePtr = nextModulePtr) { nextModulePtr = modulePtr->nextPtr; for (typePtr = modulePtr->firstTypePtr; typePtr; typePtr = nextTypePtr) { nextTypePtr = typePtr->nextPtr; for (listPtr = typePtr->listPtr; listPtr; listPtr = nextListPtr) { nextListPtr = listPtr->nextPtr; if ((typePtr->export.basetype == SMI_BASETYPE_BITS) || (typePtr->export.basetype == SMI_BASETYPE_ENUM)) { smiFree(((NamedNumber *)(listPtr->ptr))->export.name); smiFree((NamedNumber *)(listPtr->ptr)); } else if ((typePtr->export.basetype == SMI_BASETYPE_INTEGER32) || (typePtr->export.basetype == SMI_BASETYPE_INTEGER64) || (typePtr->export.basetype == SMI_BASETYPE_UNSIGNED32) || (typePtr->export.basetype == SMI_BASETYPE_UNSIGNED64) || (typePtr->export.basetype == SMI_BASETYPE_FLOAT32) || (typePtr->export.basetype == SMI_BASETYPE_FLOAT64) || (typePtr->export.basetype == SMI_BASETYPE_FLOAT128) || (typePtr->export.basetype == SMI_BASETYPE_OCTETSTRING)) { smiFree((Range *)(listPtr->ptr)); } smiFree(listPtr); } smiFree(typePtr->export.name); smiFree(typePtr->export.format); smiFree(typePtr->export.units); smiFree(typePtr->export.description); smiFree(typePtr->export.reference); smiFree(typePtr); } smiFree(modulePtr->export.name); smiFree(modulePtr->export.path); smiFree(modulePtr->export.organization); smiFree(modulePtr->export.contactinfo); smiFree(modulePtr->export.description); smiFree(modulePtr->export.reference); smiFree(modulePtr); } freeNodeTree(smiHandle->rootNodePtr); smiFree(smiHandle->rootNodePtr); return; } /* *---------------------------------------------------------------------- * * loadModule -- * * Load a MIB module. If modulename is a plain name, the file is * search along the SMIPATH environment variable. If modulename * contains a `.' or DIR_SEPARATOR it is assumed to be the path. * * Results: * 0 on success or -1 on an error. * * Side effects: * None. * *---------------------------------------------------------------------- */ __attribute__ ((visibility ("internal"))) Module *loadModule(const char *modulename, Parser *parserPtr) { Parser parser; Parser *parentParserPtr; char *path = NULL, *dir, *smipath; int sming = 0; int c, i; FILE *file; char sep[2]; static const char *ext[] = { "", ".my", ".smiv1", ".smiv2", ".sming", ".mib", ".txt", NULL }; if ((!modulename) || !strlen(modulename)) { return NULL; } if (!smiIsPath(modulename)) { /* * A plain modulename. Lookup the path along SMIPATH... */ if (!smiHandle->path) { return NULL; } smipath = smiStrdup(smiHandle->path); sep[0] = PATH_SEPARATOR; sep[1] = 0; for (dir = strtok(smipath, sep); dir; dir = strtok(NULL, sep)) { for (i = 0; ext[i]; i++) { smiAsprintf(&path, "%s%c%s%s", dir, DIR_SEPARATOR, modulename, ext[i]); if (! access(path, R_OK)) { break; } smiFree(path); } if (ext[i]) break; { char *newmodulename = smiStrdup(modulename); for (i = 0; newmodulename[i]; i++) { newmodulename[i] = tolower(newmodulename[i]); } for (i = 0; ext[i]; i++) { smiAsprintf(&path, "%s%c%s%s", dir, DIR_SEPARATOR, newmodulename, ext[i]); if (! access(path, R_OK)) { break; } smiFree(path); } smiFree(newmodulename); if (ext[i]) break; } path = NULL; } smiFree(smipath); } else { /* * A full path. Take it. */ path = smiStrdup(modulename); } #if !defined(_MSC_VER) && !defined(__MINGW32__) if (!path && smiHandle->cache && smiHandle->cacheProg) { /* Not found in the path; now try to fetch & cache the module. */ int pid; char *argv[4]; char *cmd; int status; smiAsprintf(&path, "%s%c%s", smiHandle->cache, DIR_SEPARATOR, modulename); if (access(path, R_OK)) { smiAsprintf(&cmd, "%s %s", smiHandle->cacheProg, modulename); pid = fork(); if (pid != -1) { if (!pid) { argv[0] = "sh"; argv[1] = "-c"; argv[2] = cmd; argv[3] = 0; execv("/bin/sh", argv); exit(127); } waitpid(pid, &status, 0); } smiFree(cmd); if (access(path, R_OK)) { smiFree(path); path = NULL; } } } #endif if (!path) { smiPrintError(parserPtr, ERR_MODULE_NOT_FOUND, modulename); return NULL; } parser.path = path; /* * Look into the file to determine whether it contains * SMIv1/SMIv2 or SMIng definitions. */ file = fopen(path, "r"); if (! file) { smiPrintError(parserPtr, ERR_OPENING_INPUTFILE, path, strerror(errno)); smiFree(path); return NULL; } while ((c = fgetc(file))) { if (c == '-' || isupper(c)) { sming = 0; break; } else if (c == '/' || c == 'm') { sming = 1; break; } else if (c == EOF || ! isspace(c)) { smiPrintError(parserPtr, ERR_ILLEGAL_INPUTFILE, path); smiFree(path); fclose(file); return NULL; } } rewind(file); if (sming == 0) { #ifdef BACKEND_SMI parentParserPtr = smiHandle->parserPtr; smiHandle->parserPtr = &parser; parser.path = path; parser.flags = smiHandle->flags; parser.modulePtr = NULL; parser.complianceModulePtr = NULL; parser.capabilitiesModulePtr = NULL; parser.currentDecl = SMI_DECL_UNKNOWN; parser.firstStatementLine = 0; parser.firstNestedStatementLine = 0; parser.firstRevisionLine = 0; parser.file = file; /* * Initialize a root Node for pending (forward referenced) nodes. */ parser.pendingNodePtr = addNode(NULL, 0, NODE_FLAG_ROOT, NULL); if (smiEnterLexRecursion(parser.file) < 0) { smiPrintError(&parser, ERR_MAX_LEX_DEPTH); fclose(parser.file); } smiDepth++; parser.line = 1; smiparse((void *)&parser); freeNodeTree(parser.pendingNodePtr); smiFree(parser.pendingNodePtr); smiLeaveLexRecursion(); smiDepth--; fclose(parser.file); smiFree(path); smiHandle->parserPtr = parentParserPtr; return parser.modulePtr; #else smiPrintError(parserPtr, ERR_SMI_NOT_SUPPORTED, path); smiFree(path); fclose(file); return NULL; #endif } if (sming == 1) { #ifdef BACKEND_SMING parentParserPtr = smiHandle->parserPtr; smiHandle->parserPtr = &parser; parser.path = path; parser.flags = smiHandle->flags; parser.modulePtr = NULL; parser.complianceModulePtr = NULL; parser.capabilitiesModulePtr = NULL; parser.currentDecl = SMI_DECL_UNKNOWN; parser.firstStatementLine = 0; parser.firstNestedStatementLine = 0; parser.firstRevisionLine = 0; parser.file = file; /* * Initialize a root Node for pending (forward referenced) nodes. */ parser.pendingNodePtr = addNode(NULL, 0, NODE_FLAG_ROOT, NULL); if (smingEnterLexRecursion(parser.file) < 0) { smiPrintError(&parser, ERR_MAX_LEX_DEPTH); fclose(parser.file); } smiDepth++; parser.line = 1; smingparse((void *)&parser); freeNodeTree(parser.pendingNodePtr); smiFree(parser.pendingNodePtr); smingLeaveLexRecursion(); smiDepth--; fclose(parser.file); smiFree(path); smiHandle->parserPtr = parentParserPtr; return parser.modulePtr; #else smiPrintError(parserPtr, ERR_SMING_NOT_SUPPORTED, path); smiFree(path); fclose(file); return NULL; #endif } smiFree(path); fclose(file); return NULL; }