/* * smi.c -- * * Interface Implementation of libsmi. * * Copyright (c) 1999 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: smi.c 8071 2008-04-17 11:14:46Z schoenw $ */ #include #include #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_PWD_H #include #endif #include "smi.h" #include "data.h" #include "error.h" #include "util.h" #include "snprintf.h" #ifdef BACKEND_SMI #include "scanner-smi.h" #include "parser-smi.h" #endif #ifdef BACKEND_SMING #include "scanner-sming.h" #include "parser-sming.h" #endif #ifdef HAVE_DMALLOC_H #include #endif #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) < (b) ? (b) : (a)) #endif const char *smi_library_version = SMI_LIBRARY_VERSION; const char *smi_version_string = SMI_VERSION_STRING; Handle *smiHandle = NULL; /* * Internal functions. */ static void getModulenameAndName(const char *arg1, const char *arg2, char **module, char **name) { char *p; int l; if ((!arg1) && (!arg2)) { *module = NULL; *name = NULL; } else if (!arg2) { if (isupper((int)arg1[0])) { if ((p = strstr(arg1, "::"))) { /* SMIng style module/label separator */ *name = smiStrdup(&p[2]); l = strcspn(arg1, "::"); *module = smiStrndup(arg1, l); } else if ((p = strchr(arg1, '!'))) { /* old scotty style module/label separator */ *name = smiStrdup(&p[1]); l = strcspn(arg1, "!"); *module = smiStrndup(arg1, l); } else if ((p = strchr(arg1, '.'))) { /* SMIv1/v2 style module/label separator */ *name = smiStrdup(&p[1]); l = strcspn(arg1, "."); *module = smiStrndup(arg1, l); } else { *name = smiStrdup(arg1); *module = smiStrdup(""); } } else { *name = smiStrdup(arg1); *module = smiStrdup(""); } } else if (!arg1) { if (isupper((int)arg2[0])) { if ((p = strstr(arg2, "::"))) { /* SMIng style module/label separator */ *name = smiStrdup(&p[2]); l = strcspn(arg2, "::"); *module = smiStrndup(arg2, l); } else if ((p = strchr(arg2, '!'))) { /* old scotty style module/label separator */ *name = smiStrdup(&p[1]); l = strcspn(arg2, "!"); *module = smiStrndup(arg2, l); } else if ((p = strchr(arg2, '.'))) { /* SMIv1/v2 style module/label separator */ *name = smiStrdup(&p[1]); l = strcspn(arg2, "."); *module = smiStrndup(arg2, l); } else { *name = smiStrdup(arg2); *module = smiStrdup(""); } } else { *name = smiStrdup(arg2); *module = smiStrdup(""); } } else { *module = smiStrdup(arg1); *name = smiStrdup(arg2); } } static Node *getNode(unsigned int oidlen, SmiSubid oid[]) { Node *nodePtr, *parentPtr; unsigned int i; for(nodePtr = smiHandle->rootNodePtr, i=0; i < oidlen; i++) { parentPtr = nodePtr; nodePtr = findNodeByParentAndSubid(parentPtr, oid[i]); if (!nodePtr) { return parentPtr; } } return nodePtr; } static Object *getNextChildObject(Node *startNodePtr, Module *modulePtr, SmiNodekind nodekind) { Node *nodePtr; Object *objectPtr = NULL; if (!startNodePtr || !modulePtr) return NULL; for (nodePtr = startNodePtr; nodePtr; nodePtr = nodePtr->nextPtr) { for (objectPtr = nodePtr->firstObjectPtr; objectPtr; objectPtr = objectPtr->nextSameNodePtr) { if (((!modulePtr) || (objectPtr->modulePtr == modulePtr)) && ((nodekind == SMI_NODEKIND_ANY) || (nodekind & objectPtr->export.nodekind))) { break; } } if (objectPtr) break; objectPtr = getNextChildObject(nodePtr->firstChildPtr, modulePtr, nodekind); if (objectPtr) break; } return objectPtr; } /* * Interface Functions. */ int smiInit(const char *tag) { char *p, *pp, *tag2; #ifdef HAVE_PWD_H struct passwd *pw; #endif smiHandle = findHandleByName(tag); if (smiHandle) { return 0; } smiHandle = addHandle(tag); smiDepth = 0; smiHandle->errorLevel = DEFAULT_ERRORLEVEL; smiHandle->errorHandler = smiErrorHandler; #if !defined(_MSC_VER) smiHandle->cache = NULL; smiHandle->cacheProg = NULL; #endif if (smiInitData()) { return -1; } /* * Setup the SMI MIB module search path: * 1. set to builtin DEFAULT_SMIPATH * 2. read global config file if present (append/prepend/replace) * 3. read user config file if present (append/prepend/replace) * 4. evaluate SMIPATH env-var if set (append/prepend/replace) */ /* 1. set to builtin DEFAULT_SMIPATH */ smiHandle->path = smiStrdup(DEFAULT_SMIPATH); tag2 = smiStrdup(tag); if (tag2) tag2 = strtok(tag2, ":"); if (tag2) { /* 2. read global config file if present (append/prepend/replace) */ smiReadConfig(DEFAULT_GLOBALCONFIG, tag2); #ifdef HAVE_PWD_H pw = getpwuid(getuid()); if (pw && pw->pw_dir) { /* 3. read user config file if present (append/prepend/replace) */ smiAsprintf(&p, "%s%c%s", pw->pw_dir, DIR_SEPARATOR, DEFAULT_USERCONFIG); smiReadConfig(p, tag2); smiFree(p); } #endif } smiFree(tag2); /* 4. evaluate SMIPATH env-var if set (append/prepend/replace) */ p = getenv("SMIPATH"); if (p) { if (p[0] == PATH_SEPARATOR) { smiAsprintf(&pp, "%s%s", smiHandle->path, p); smiFree(smiHandle->path); smiHandle->path = pp; } else if (p[strlen(p)-1] == PATH_SEPARATOR) { smiAsprintf(&pp, "%s%s", p, smiHandle->path); smiFree(smiHandle->path); smiHandle->path = pp; } else { smiHandle->path = smiStrdup(p); } } if (!smiHandle->path) { return -1; } return 0; } void smiExit() { if (!smiHandle) return; smiFreeData(); smiFree(smiHandle->path); #if !defined(_MSC_VER) smiFree(smiHandle->cache); smiFree(smiHandle->cacheProg); #endif removeHandle(smiHandle); smiHandle = NULL; return; } char *smiGetPath() { if (smiHandle->path) { return smiStrdup(smiHandle->path); } else { return NULL; } } int smiSetPath(const char *s) { char *s2; if (!smiHandle) smiInit(NULL); if (!s) { smiFree(smiHandle->path); smiHandle->path = NULL; return 0; } s2 = smiStrdup(s); if (s2) { smiFree(smiHandle->path); smiHandle->path = s2; return 0; } else { return -1; } } void smiSetSeverity(char *pattern, int severity) { smiSetErrorSeverity(pattern, severity); } int smiReadConfig(const char *filename, const char *tag) { FILE *file; char buf[201]; char *cmd, *arg, *s; file = fopen(filename, "r"); if (file) { while (!feof(file)) { if (!fgets(buf, 200, file)) continue; if ((!strlen(buf)) || (buf[0] == '#')) continue; cmd = strtok(buf, " \t\n\r"); if (!cmd) continue; if (cmd[0] == '#') continue; if (cmd[strlen(cmd)-1] == ':') { if (!tag) continue; cmd[strlen(cmd)-1] = 0; if (strcmp(cmd, tag)) continue; cmd = strtok(NULL, " \t\n\r"); } arg = strtok(NULL, " \t\n\r"); if (!strcmp(cmd, "load")) { smiLoadModule(arg); } else if (!strcmp(cmd, "path")) { if (arg) { if (arg[0] == PATH_SEPARATOR) { smiAsprintf(&s, "%s%s", smiHandle->path, arg); smiFree(smiHandle->path); smiHandle->path = s; } else if (arg[strlen(arg)-1] == PATH_SEPARATOR) { smiAsprintf(&s, "%s%s", arg, smiHandle->path); smiFree(smiHandle->path); smiHandle->path = s; } else { smiHandle->path = smiStrdup(arg); } } } else if (!strcmp(cmd, "cache")) { #if !defined(_MSC_VER) smiFree(smiHandle->cache); smiFree(smiHandle->cacheProg); #endif if (arg && strcmp(arg, "off")) { #if !defined(_MSC_VER) smiHandle->cache = smiStrdup(arg); arg = strtok(NULL, "\n\r"); smiHandle->cacheProg = smiStrdup(arg); #else smiPrintError(NULL, ERR_CACHE_CONFIG_NOT_SUPPORTED, filename); #endif } } else if (!strcmp(cmd, "level")) { smiSetErrorLevel(atoi(arg)); } else if (!strcmp(cmd, "hide")) { smiSetSeverity(arg, 9); } else { smiPrintError(NULL, ERR_UNKNOWN_CONFIG_CMD, cmd, filename); } } fclose(file); return 0; } return -1; } int smiIsLoaded(const char *module) { if (!module) return 0; return isInView(module); } char *smiLoadModule(const char *module) { Module *modulePtr; if (!smiHandle) smiInit(NULL); if (smiIsPath(module)) { modulePtr = loadModule(module, NULL); if (modulePtr) { if (!isInView(modulePtr->export.name)) { addView(modulePtr->export.name); } return modulePtr->export.name; } else { return NULL; } } else { if ((modulePtr = findModuleByName(module))) { /* already loaded. */ if (!isInView(module)) { addView(module); } return modulePtr->export.name; } else { if ((modulePtr = loadModule(module, NULL))) { if (!isInView(module)) { addView(module); } return modulePtr->export.name; } else { return NULL; } } } } void smiSetErrorLevel(int level) { if (!smiHandle) smiInit(NULL); smiHandle->errorLevel = level; } void smiSetFlags(int userflags) { if (!smiHandle) smiInit(NULL); smiHandle->flags = (smiHandle->flags & ~SMI_FLAG_MASK) | userflags; } int smiGetFlags() { if (!smiHandle) smiInit(NULL); return smiHandle->flags & SMI_FLAG_MASK; } SmiModule *smiGetModule(const char *module) { Module *modulePtr; if (!module) { return NULL; } modulePtr = findModuleByName(module); if (!modulePtr) { modulePtr = loadModule(module, NULL); } return &modulePtr->export; } SmiModule *smiGetFirstModule() { Module *modulePtr; for (modulePtr = smiHandle->firstModulePtr; modulePtr && modulePtr->export.name && (strlen(modulePtr->export.name) == 0); modulePtr = modulePtr->nextPtr); return &modulePtr->export; } SmiModule *smiGetNextModule(SmiModule *smiModulePtr) { Module *modulePtr; if (!smiModulePtr) { return NULL; } for (modulePtr = ((Module *)smiModulePtr)->nextPtr; modulePtr && modulePtr->export.name && (strlen(modulePtr->export.name) == 0); modulePtr = modulePtr->nextPtr); return &modulePtr->export; } SmiImport *smiGetFirstImport(SmiModule *smiModulePtr) { if (!smiModulePtr) { return NULL; } return &((Module *)smiModulePtr)->firstImportPtr->export; } SmiImport *smiGetNextImport(SmiImport *smiImportPtr) { if (!smiImportPtr) { return NULL; } return &((Import *)smiImportPtr)->nextPtr->export; } int smiIsImported(SmiModule *smiModulePtr, SmiModule *importedModulePtr, char *importedName) { Import *importPtr; Module *modulePtr; char *importedModule; if ((!smiModulePtr) || (!importedName)) { return 0; } modulePtr = (Module *)smiModulePtr; if (importedModulePtr) { importedModule = importedModulePtr->name; } else { importedModule = NULL; } for (importPtr = modulePtr->firstImportPtr; importPtr; importPtr = importPtr->nextPtr) { if ((!strcmp(importedName, importPtr->export.name)) && ((!importedModule) || (!strcmp(importedModule, importPtr->export.module)))) { return 1; } } return 0; } SmiRevision *smiGetFirstRevision(SmiModule *smiModulePtr) { if (!smiModulePtr) { return NULL; } return &((Module *)smiModulePtr)->firstRevisionPtr->export; } SmiRevision *smiGetNextRevision(SmiRevision *smiRevisionPtr) { if (!smiRevisionPtr) { return NULL; } return &((Revision *)smiRevisionPtr)->nextPtr->export; } int smiGetRevisionLine(SmiRevision *smiRevisionPtr) { return ((Revision *)smiRevisionPtr)->line; } SmiType *smiGetType(SmiModule *smiModulePtr, char *type) { Type *typePtr = NULL; Module *modulePtr = NULL; char *module2, *type2; if (!type) { return NULL; } modulePtr = (Module *)smiModulePtr; getModulenameAndName(smiModulePtr ? smiModulePtr->name : NULL, type, &module2, &type2); if (!modulePtr && module2 && strlen(module2)) { if (!(modulePtr = findModuleByName(module2))) { modulePtr = loadModule(module2, NULL); } } if (modulePtr) { typePtr = findTypeByModuleAndName(modulePtr, type2); } else { typePtr = findTypeByName(type2); } smiFree(module2); smiFree(type2); if (!typePtr || typePtr->export.basetype == SMI_BASETYPE_UNKNOWN) { return NULL; } return &typePtr->export; } SmiType *smiGetFirstType(SmiModule *smiModulePtr) { Type *typePtr; if (!smiModulePtr) { return NULL; } for (typePtr = ((Module *)smiModulePtr)->firstTypePtr; typePtr; typePtr = typePtr->nextPtr) { /* loop until we found a `real' type */ if (typePtr->export.name && typePtr->export.basetype != SMI_BASETYPE_UNKNOWN) { break; } } return &typePtr->export; } SmiType *smiGetNextType(SmiType *smiTypePtr) { Type *typePtr; if (!smiTypePtr) { return NULL; } for (typePtr = ((Type *)smiTypePtr)->nextPtr; typePtr; typePtr = typePtr->nextPtr) { /* loop until we found a `real' type */ if (typePtr->export.name && typePtr->export.basetype != SMI_BASETYPE_UNKNOWN) { break; } } return &typePtr->export; } SmiType *smiGetParentType(SmiType *smiTypePtr) { Type *typePtr; if (!smiTypePtr) { return NULL; } typePtr = ((Type *)smiTypePtr)->parentPtr; if (!typePtr || typePtr->export.basetype == SMI_BASETYPE_UNKNOWN) { return NULL; } return &typePtr->export; } SmiModule *smiGetTypeModule(SmiType *smiTypePtr) { return &((Type *)smiTypePtr)->modulePtr->export; } int smiGetTypeLine(SmiType *smiTypePtr) { return ((Type *)smiTypePtr)->line; } SmiNamedNumber *smiGetFirstNamedNumber(SmiType *smiTypePtr) { Type *typePtr; typePtr = (Type *)smiTypePtr; if ((!typePtr) || (!typePtr->listPtr) || ((typePtr->export.basetype != SMI_BASETYPE_ENUM) && (typePtr->export.basetype != SMI_BASETYPE_BITS) && (typePtr->export.basetype != SMI_BASETYPE_POINTER))) { return NULL; } return &((NamedNumber *)typePtr->listPtr->ptr)->export; } SmiNamedNumber *smiGetNextNamedNumber(SmiNamedNumber *smiNamedNumberPtr) { Type *typePtr; List *listPtr; if (!smiNamedNumberPtr) { return NULL; } typePtr = ((NamedNumber *)smiNamedNumberPtr)->typePtr; if ((!typePtr) || (!typePtr->listPtr) || ((typePtr->export.basetype != SMI_BASETYPE_ENUM) && (typePtr->export.basetype != SMI_BASETYPE_BITS))) { return NULL; } for (listPtr = typePtr->listPtr; listPtr; listPtr = listPtr->nextPtr) { if (((NamedNumber *)(listPtr->ptr))->export.name == smiNamedNumberPtr->name) break; } if ((!listPtr) || (!listPtr->nextPtr)) { return NULL; } return &((NamedNumber *)listPtr->nextPtr->ptr)->export; } SmiNamedNumber *smiGetAttributeFirstNamedNumber(SmiAttribute *smiAttributePtr) { Attribute *attributePtr; attributePtr = (Attribute *)smiAttributePtr; if ((!attributePtr) || (!attributePtr->listPtr) || ((attributePtr->export.basetype != SMI_BASETYPE_ENUM) && (attributePtr->export.basetype != SMI_BASETYPE_BITS) && (attributePtr->export.basetype != SMI_BASETYPE_POINTER))) { return NULL; } return &((NamedNumber *)attributePtr->listPtr->ptr)->export; } SmiNamedNumber *smiGetAttributeNextNamedNumber(SmiNamedNumber *smiNamedNumberPtr) { Attribute *attributePtr; List *listPtr; if (!smiNamedNumberPtr) { return NULL; } attributePtr = (Attribute*)(((NamedNumber *)smiNamedNumberPtr)->typePtr); if ((!attributePtr) || (!attributePtr->listPtr) || ((attributePtr->export.basetype != SMI_BASETYPE_ENUM) && (attributePtr->export.basetype != SMI_BASETYPE_BITS))) { return NULL; } for (listPtr = attributePtr->listPtr; listPtr; listPtr = listPtr->nextPtr) { if (((NamedNumber *)(listPtr->ptr))->export.name == smiNamedNumberPtr->name) break; } if ((!listPtr) || (!listPtr->nextPtr)) { return NULL; } return &((NamedNumber *)listPtr->nextPtr->ptr)->export; } SmiRange *smiGetFirstRange(SmiType *smiTypePtr) { Type *typePtr; typePtr = (Type *)smiTypePtr; if ((!typePtr) || (!typePtr->listPtr) || (typePtr->export.basetype == SMI_BASETYPE_ENUM) || (typePtr->export.basetype == SMI_BASETYPE_BITS)) { return NULL; } return &((Range *)typePtr->listPtr->ptr)->export; } SmiRange *smiGetNextRange(SmiRange *smiRangePtr) { Type *typePtr; List *listPtr; if (!smiRangePtr) { return NULL; } typePtr = ((Range *)smiRangePtr)->typePtr; if ((!typePtr) || (!typePtr->listPtr) || (typePtr->export.basetype == SMI_BASETYPE_ENUM) || (typePtr->export.basetype == SMI_BASETYPE_BITS)) { return NULL; } for (listPtr = typePtr->listPtr; listPtr; listPtr = listPtr->nextPtr) { if (!memcmp(&((Range *)listPtr->ptr)->export.minValue, &smiRangePtr->minValue, sizeof(struct SmiValue))) break; } if ((!listPtr) || (!listPtr->nextPtr)) { return NULL; } return &((Range *)listPtr->nextPtr->ptr)->export; } SmiRange *smiGetAttributeFirstRange(SmiAttribute *smiAttributePtr) { Attribute *attributePtr; attributePtr = (Attribute *)smiAttributePtr; if ((!attributePtr) || (!attributePtr->listPtr) || (attributePtr->export.basetype == SMI_BASETYPE_ENUM) || (attributePtr->export.basetype == SMI_BASETYPE_BITS)) { return NULL; } return &((Range *)attributePtr->listPtr->ptr)->export; } SmiRange *smiGetAttributeNextRange(SmiRange *smiRangePtr) { Attribute *attributePtr; List *listPtr; if (!smiRangePtr) { return NULL; } attributePtr = (Attribute*)((Range *)smiRangePtr)->typePtr; if ((!attributePtr) || (!attributePtr->listPtr) || (attributePtr->export.basetype == SMI_BASETYPE_ENUM) || (attributePtr->export.basetype == SMI_BASETYPE_BITS)) { return NULL; } for (listPtr = attributePtr->listPtr; listPtr; listPtr = listPtr->nextPtr) { if (!memcmp(&((Range *)listPtr->ptr)->export.minValue, &smiRangePtr->minValue, sizeof(struct SmiValue))) break; } if ((!listPtr) || (!listPtr->nextPtr)) { return NULL; } return &((Range *)listPtr->nextPtr->ptr)->export; } SmiIdentity *smiGetFirstIdentity(SmiModule *smiModulePtr) { if (!smiModulePtr) { return NULL; } return ((Module *)smiModulePtr)->firstIdentityPtr ? &((Module *)smiModulePtr)->firstIdentityPtr->export : NULL; } SmiIdentity *smiGetNextIdentity(SmiIdentity *smiIdentityPtr) { if (!smiIdentityPtr) { return NULL; } return ((Identity *)smiIdentityPtr)->nextPtr ? &((Identity *)smiIdentityPtr)->nextPtr->export : NULL; } SmiModule *smiGetIdentityModule(SmiIdentity *smiIdentityPtr) { return &((Identity *)smiIdentityPtr)->modulePtr->export; } SmiIdentity *smiGetParentIdentity(SmiIdentity *smiIdentityPtr) { return (SmiIdentity*)(((Identity *)smiIdentityPtr)->parentPtr); } SmiIdentity *smiGetIdentity(SmiModule *smiModulePtr, char *identity) { if (!smiModulePtr) { return NULL; } else { SmiIdentity *ide; for(ide = smiGetFirstIdentity(smiModulePtr); ide; ide = smiGetNextIdentity(ide)) if(!strncmp(ide->name,identity,64))return ide; return NULL; } } int smiGetIdentityLine(SmiIdentity *smiIdentityPtr) { return ((Identity *)smiIdentityPtr)->line; } SmiClass *smiGetFirstClass(SmiModule *smiModulePtr) { if (!smiModulePtr) { return NULL; } return ((Module *)smiModulePtr)->firstClassPtr ? &((Module *)smiModulePtr)->firstClassPtr->export : NULL; } SmiClass *smiGetNextClass(SmiClass *smiClassPtr) { if (!smiClassPtr) { return NULL; } return ((Class *)smiClassPtr)->nextPtr ? &((Class *)smiClassPtr)->nextPtr->export : NULL; } SmiModule *smiGetClassModule(SmiClass *smiClassPtr) { return &((Class *)smiClassPtr)->modulePtr->export; } SmiClass *smiGetParentClass(SmiClass *smiClassPtr) { return (SmiClass*)(((Class *)smiClassPtr)->parentPtr); } SmiClass *smiGetClass(SmiModule *smiModulePtr, char *class) { if (!smiModulePtr) { return NULL; } else { SmiClass *cl; for(cl = smiGetFirstClass(smiModulePtr); cl; cl = smiGetNextClass(cl)) if(!strncmp(cl->name,class,64))return cl; return NULL; } } int smiGetClassLine(SmiClass *smiClassPtr) { return ((Class *)smiClassPtr)->line; } SmiAttribute *smiGetFirstAttribute(SmiClass *smiClassPtr) { Attribute *attributePtr; if (!smiClassPtr) { return NULL; } attributePtr = ((Class *)smiClassPtr)->firstAttributePtr; return &attributePtr->export; } SmiAttribute *smiGetNextAttribute( SmiAttribute *smiTypePtr) { Attribute *attributePtr; if (!smiTypePtr) { return NULL; } attributePtr = ((Attribute *)smiTypePtr)->nextPtr; return &attributePtr->export; } SmiAttribute *smiGetAttribute(SmiClass *smiClassPtr, char *attribute) { Attribute *attributePtr; if (! smiClassPtr) { return NULL; } attributePtr = ((Class *)smiClassPtr)->firstAttributePtr; for (attributePtr = ((Class *)smiClassPtr)->firstAttributePtr; attributePtr; attributePtr = attributePtr->nextPtr) { if (!strncmp(attributePtr->export.name, attribute,64)) { return &attributePtr->export; } } /* * attribute might belong to the parent so check parent if * attribute not found */ smiClassPtr = smiGetParentClass(smiClassPtr); attributePtr = (Attribute*)smiGetAttribute(smiClassPtr , attribute); return &attributePtr->export; } SmiType *smiGetAttributeParentType(SmiAttribute *smiAttributePtr) { Type *parentTypePtr; if (! smiAttributePtr) { return NULL; } parentTypePtr = ((Attribute*)smiAttributePtr)->parentTypePtr; return (parentTypePtr) ? &parentTypePtr->export : NULL; } SmiClass *smiGetAttributeParentClass( SmiAttribute *smiAttributePtr) { Class *parentClassPtr; if (! smiAttributePtr) { return NULL; } parentClassPtr = ((Attribute*)smiAttributePtr)->parentClassPtr; return parentClassPtr ? &parentClassPtr->export : NULL; } SmiAttribute *smiGetFirstUniqueAttribute(SmiClass *smiClassPtr) { Class *classPtr; if (! smiClassPtr) { return NULL; } classPtr = (Class*)smiClassPtr; if (! classPtr->uniqueList) { return NULL; } if (classPtr->uniqueList->ptr == classPtr) { return NULL; /* scalar class */ } return (SmiAttribute*)(classPtr->uniqueList->ptr); } SmiAttribute *smiGetNextUniqueAttribute( SmiAttribute *smiTypePtr) { Class *classPtr; List *listPtr; if (! smiTypePtr) { return NULL; } classPtr = ((Attribute*)smiTypePtr)->classPtr; if (classPtr && classPtr->uniqueList) { for (listPtr=classPtr->uniqueList;listPtr; listPtr=listPtr->nextPtr) { if (&((Attribute*)(listPtr->ptr))->export == smiTypePtr) { if (listPtr->nextPtr) { return &((Attribute*)(listPtr->nextPtr->ptr))->export; } } } } return NULL; } int smiGetAttributeLine(SmiAttribute *smiAttributePtr) { return ((Attribute *)smiAttributePtr)->line; } int smiIsClassScalar(SmiClass *smiClassPtr) { Class *classPtr; if (! smiClassPtr) { return 0; } classPtr = (Class*)smiClassPtr; if (! classPtr->uniqueList) { return 0; } return (classPtr->uniqueList->ptr == classPtr); } SmiEvent *smiGetFirstEvent(SmiClass *smiClassPtr) { Event *eventPtr; if (! smiClassPtr) { return NULL; } eventPtr = ((Class *)smiClassPtr)->firstEventPtr; return &(eventPtr->export); } SmiEvent *smiGetNextEvent(SmiEvent *smiEventPtr) { Event *eventPtr; if (! smiEventPtr) { return NULL; } eventPtr = ((Event *)smiEventPtr)->nextPtr; return &eventPtr->export; } int smiGetEventLine(SmiEvent *smiEventPtr) { return ((Event *)smiEventPtr)->line; } SmiMacro *smiGetMacro(SmiModule *smiModulePtr, char *macro) { Macro *macroPtr = NULL; Module *modulePtr = NULL; char *module2, *macro2; if (!macro) { return NULL; } modulePtr = (Module *)smiModulePtr; getModulenameAndName(smiModulePtr ? smiModulePtr->name : NULL, macro, &module2, ¯o2); if (!modulePtr && module2 && strlen(module2)) { if (!(modulePtr = findModuleByName(module2))) { modulePtr = loadModule(module2, NULL); } } if (modulePtr) { macroPtr = findMacroByModuleAndName(modulePtr, macro2); } else { macroPtr = findMacroByName(macro2); } smiFree(module2); smiFree(macro2); return macroPtr ? ¯oPtr->export : NULL; } SmiMacro *smiGetFirstMacro(SmiModule *smiModulePtr) { if (!smiModulePtr) { return NULL; } return ((Module *)smiModulePtr)->firstMacroPtr ? &((Module *)smiModulePtr)->firstMacroPtr->export : NULL; } SmiMacro *smiGetNextMacro(SmiMacro *smiMacroPtr) { if (!smiMacroPtr) { return NULL; } return ((Macro *)smiMacroPtr)->nextPtr ? &((Macro *)smiMacroPtr)->nextPtr->export : NULL; } SmiModule *smiGetMacroModule(SmiMacro *smiMacroPtr) { return &((Macro *)smiMacroPtr)->modulePtr->export; } int smiGetMacroLine(SmiMacro *smiMacroPtr) { return ((Macro *)smiMacroPtr)->line; } SmiNode *smiGetNode(SmiModule *smiModulePtr, const char *node) { Object *objectPtr = NULL; Module *modulePtr = NULL; Node *nodePtr; char *module2, *node2, *p; unsigned int oidlen; SmiSubid oid[128]; if (!node) { return NULL; } modulePtr = (Module *)smiModulePtr; getModulenameAndName(smiModulePtr ? smiModulePtr->name : NULL, node, &module2, &node2); if (!modulePtr && module2 && strlen(module2)) { if (!(modulePtr = findModuleByName(module2))) { modulePtr = loadModule(module2, NULL); } } if (isdigit((int)node2[0])) { for (oidlen = 0, p = strtok(node2, ". "); p; oidlen++, p = strtok(NULL, ". ")) { oid[oidlen] = strtoul(p, NULL, 0); } nodePtr = getNode(oidlen, oid); if (nodePtr) { if (modulePtr) { objectPtr = findObjectByModuleAndNode(modulePtr, nodePtr); } else { objectPtr = findObjectByNode(nodePtr); } } } else { p = strtok(node2, ". "); if (modulePtr) { objectPtr = findObjectByModuleAndName(modulePtr, p); } else { objectPtr = findObjectByName(p); } } smiFree(module2); smiFree(node2); return objectPtr ? &objectPtr->export : NULL; } SmiNode *smiGetNodeByOID(unsigned int oidlen, SmiSubid oid[]) { Node *nodePtr; Object *objectPtr; if (!oidlen) { return NULL; } nodePtr = getNode(oidlen, oid); if (!nodePtr) { return NULL; } objectPtr = findObjectByNode(nodePtr); return objectPtr ? &objectPtr->export : NULL; } SmiNode *smiGetFirstNode(SmiModule *smiModulePtr, SmiNodekind nodekind) { Module *modulePtr; Node *nodePtr = NULL; Object *objectPtr; if (!smiModulePtr) { return NULL; } modulePtr = (Module *)smiModulePtr; if (modulePtr && modulePtr->prefixNodePtr) { /* start at the common oid prefix of this module */ nodePtr = modulePtr->prefixNodePtr; } else { nodePtr = smiHandle->rootNodePtr->firstChildPtr; } do { objectPtr = getNextChildObject(nodePtr, modulePtr, nodekind); if (objectPtr) return &objectPtr->export; if (nodePtr->firstChildPtr) { nodePtr = nodePtr->firstChildPtr; } else if (nodePtr->nextPtr) { nodePtr = nodePtr->nextPtr; } else { for (nodePtr = nodePtr->parentPtr; nodePtr && (nodePtr->parentPtr) && (!nodePtr->nextPtr); nodePtr = nodePtr->parentPtr); if (nodePtr) nodePtr = nodePtr->nextPtr; } } while (nodePtr); return NULL; } SmiNode *smiGetNextNode(SmiNode *smiNodePtr, SmiNodekind nodekind) { Module *modulePtr; Object *objectPtr; Node *nodePtr; int i; if (!smiNodePtr) { return NULL; } objectPtr = (Object *)smiNodePtr; nodePtr = objectPtr->nodePtr; modulePtr = objectPtr->modulePtr; if (!modulePtr) { return NULL; } if (!nodePtr) { return NULL; } do { if (nodePtr->firstChildPtr) { nodePtr = nodePtr->firstChildPtr; } else if (nodePtr->nextPtr) { nodePtr = nodePtr->nextPtr; } else { for (nodePtr = nodePtr->parentPtr; (nodePtr->parentPtr) && (!nodePtr->nextPtr); nodePtr = nodePtr->parentPtr); nodePtr = nodePtr->nextPtr; /* did we move outside the common oid prefix of this module? */ for (i = 0; i < modulePtr->prefixNodePtr->oidlen; i++) if ((!nodePtr) || (!nodePtr->oid) || (nodePtr->oid[i] != modulePtr->prefixNodePtr->oid[i])) return NULL; } objectPtr = getNextChildObject(nodePtr, modulePtr, nodekind); if (objectPtr) return &objectPtr->export; } while (nodePtr); return NULL; } SmiNode *smiGetParentNode(SmiNode *smiNodePtr) { Module *modulePtr; Object *objectPtr; Import *importPtr; Node *nodePtr; if (!smiNodePtr) { return NULL; } objectPtr = (Object *)smiNodePtr; nodePtr = objectPtr->nodePtr; modulePtr = objectPtr->modulePtr; if (!nodePtr) { return NULL; } if (nodePtr == smiHandle->rootNodePtr) { return NULL; } nodePtr = nodePtr->parentPtr; if (! nodePtr) { return NULL; } /* * First, try to find a definition in the same module. */ objectPtr = NULL; if (modulePtr) { objectPtr = findObjectByModuleAndNode(modulePtr, nodePtr); } /* * If found, check if it's imported. In case, get the original definition. */ if (objectPtr) { importPtr = findImportByName(objectPtr->export.name, objectPtr->modulePtr); if (importPtr) { objectPtr = findObjectByModulenameAndNode(importPtr->export.module, nodePtr); } else { objectPtr = NULL; } } /* * If not yet found, try to find any definition. */ if (!objectPtr) { objectPtr = findObjectByNode(nodePtr); if ((!objectPtr) && (nodePtr->parentPtr)) { /* an implicitly created node, e.g. gaga.0 in an object * definition with oid == gaga.0.1. */ objectPtr = addObject(SMI_UNKNOWN_LABEL, nodePtr->parentPtr, nodePtr->subid, 0, NULL); objectPtr->nodePtr = nodePtr; objectPtr->modulePtr = modulePtr; } } return objectPtr ? &objectPtr->export : NULL; } SmiNode *smiGetRelatedNode(SmiNode *smiNodePtr) { if (!smiNodePtr) { return NULL; } return &((Object *)smiNodePtr)->relatedPtr->export; } SmiNode *smiGetFirstChildNode(SmiNode *smiNodePtr) { Module *modulePtr; Object *objectPtr; Node *nodePtr; if (!smiNodePtr) { return NULL; } objectPtr = (Object *)smiNodePtr; nodePtr = objectPtr->nodePtr; modulePtr = objectPtr->modulePtr; if (!nodePtr) { return NULL; } nodePtr = nodePtr->firstChildPtr; if (!nodePtr) { return NULL; } objectPtr = findObjectByModuleAndNode(modulePtr, nodePtr); if (!objectPtr) objectPtr = findObjectByNode(nodePtr); return objectPtr ? &objectPtr->export : NULL; } SmiNode *smiGetNextChildNode(SmiNode *smiNodePtr) { Module *modulePtr; Object *objectPtr; Node *nodePtr; if (!smiNodePtr) { return NULL; } objectPtr = (Object *)smiNodePtr; nodePtr = objectPtr->nodePtr; modulePtr = objectPtr->modulePtr; if (!nodePtr) { return NULL; } nodePtr = nodePtr->nextPtr; if (!nodePtr) { return NULL; } objectPtr = findObjectByModuleAndNode(modulePtr, nodePtr); if (!objectPtr) objectPtr = findObjectByNode(nodePtr); return objectPtr ? &objectPtr->export : NULL; } SmiNode *smiGetModuleIdentityNode(SmiModule *smiModulePtr) { if (!smiModulePtr) { return NULL; } return &((Module *)smiModulePtr)->objectPtr->export; } SmiModule *smiGetNodeModule(SmiNode *smiNodePtr) { return &((Object *)smiNodePtr)->modulePtr->export; } SmiType *smiGetNodeType(SmiNode *smiNodePtr) { Type *typePtr; typePtr = ((Object *)smiNodePtr)->typePtr; if (!typePtr || typePtr->export.basetype == SMI_BASETYPE_UNKNOWN) { return NULL; } return &typePtr->export; } int smiGetNodeLine(SmiNode *smiNodePtr) { return ((Object *)smiNodePtr)->line; } SmiElement *smiGetFirstElement(SmiNode *smiNodePtr) { List *listPtr; if (!smiNodePtr) { return NULL; } listPtr = ((Object *)smiNodePtr)->listPtr; return (SmiElement *)listPtr; } SmiElement *smiGetNextElement(SmiElement *smiElementPtr) { List *listPtr; if (!smiElementPtr) { return NULL; } listPtr = ((List *)smiElementPtr)->nextPtr; return (SmiElement *)listPtr; } SmiNode *smiGetElementNode(SmiElement *smiElementPtr) { if ((Object *)((List *)smiElementPtr)->ptr) return &((Object *)((List *)smiElementPtr)->ptr)->export; else return NULL; } SmiOption *smiGetFirstOption(SmiNode *smiComplianceNodePtr) { Object *objectPtr; if (!smiComplianceNodePtr) { return NULL; } objectPtr = (Object *)smiComplianceNodePtr; if (!objectPtr->optionlistPtr) { return NULL; } if (objectPtr->export.nodekind != SMI_NODEKIND_COMPLIANCE) { return NULL; } return &((Option *)objectPtr->optionlistPtr->ptr)->export; } SmiOption *smiGetNextOption(SmiOption *smiOptionPtr) { List *listPtr; if (!smiOptionPtr) { return NULL; } for (listPtr = ((Option *)smiOptionPtr)->compliancePtr->optionlistPtr; listPtr; listPtr = listPtr->nextPtr) { if ((Option *)(listPtr->ptr) == (Option *)smiOptionPtr) { if (listPtr->nextPtr) { return &((Option *)listPtr->nextPtr->ptr)->export; } else { return NULL; } } } return NULL; } SmiNode *smiGetOptionNode(SmiOption *smiOptionPtr) { return &((Option *)smiOptionPtr)->objectPtr->export; } int smiGetOptionLine(SmiOption *smiOptionPtr) { return ((Option *)smiOptionPtr)->line; } SmiRefinement *smiGetFirstRefinement(SmiNode *smiComplianceNodePtr) { Object *objectPtr; if (!smiComplianceNodePtr) { return NULL; } objectPtr = (Object *)smiComplianceNodePtr; if (!objectPtr->refinementlistPtr) { return NULL; } if (objectPtr->export.nodekind != SMI_NODEKIND_COMPLIANCE) { return NULL; } return &((Refinement *)objectPtr->refinementlistPtr->ptr)->export; } SmiRefinement *smiGetNextRefinement(SmiRefinement *smiRefinementPtr) { List *listPtr; if (!smiRefinementPtr) { return NULL; } for (listPtr = ((Refinement *)smiRefinementPtr)->compliancePtr->refinementlistPtr; listPtr; listPtr = listPtr->nextPtr) { if ((Refinement *)(listPtr->ptr) == (Refinement *)smiRefinementPtr) { if (listPtr->nextPtr) { return &((Refinement *)listPtr->nextPtr->ptr)->export; } else { return NULL; } } } return NULL; } SmiNode *smiGetRefinementNode(SmiRefinement *smiRefinementPtr) { return &((Refinement *)smiRefinementPtr)->objectPtr->export; } SmiType *smiGetRefinementType(SmiRefinement *smiRefinementPtr) { Type *typePtr; typePtr = ((Refinement *)smiRefinementPtr)->typePtr; if (!typePtr || typePtr->export.basetype == SMI_BASETYPE_UNKNOWN) { return NULL; } return &typePtr->export; } SmiType *smiGetRefinementWriteType(SmiRefinement *smiRefinementPtr) { Type *typePtr; typePtr = ((Refinement *)smiRefinementPtr)->writetypePtr; if (!typePtr || typePtr->export.basetype == SMI_BASETYPE_UNKNOWN) { return NULL; } return &typePtr->export; } int smiGetRefinementLine(SmiRefinement *smiRefinementPtr) { return ((Refinement *)smiRefinementPtr)->line; } SmiElement *smiGetFirstUniquenessElement(SmiNode *smiNodePtr) { List *listPtr; if (!smiNodePtr) { return NULL; } listPtr = ((Object *)smiNodePtr)->uniquenessPtr; return (SmiElement *)listPtr; } char *smiRenderOID(unsigned int oidlen, SmiSubid *oid, int flags) { SmiNode *nodePtr = NULL; SmiModule *modulePtr = NULL; unsigned int i = 0; char *ss, *s = NULL; if (!oid) { if (flags & SMI_RENDER_UNKNOWN) { smiAsprintf(&s, SMI_UNKNOWN_LABEL); } else { s = NULL; } return s; } if (flags & (SMI_RENDER_NAME | SMI_RENDER_QUALIFIED)) { int len; for (len = oidlen; len; len--) { nodePtr = smiGetNodeByOID(len, oid); if (! nodePtr || nodePtr->name) break; } if (nodePtr && nodePtr->name) { i = nodePtr->oidlen; if (flags & SMI_RENDER_QUALIFIED) { modulePtr = smiGetNodeModule(nodePtr); } if (modulePtr) { smiAsprintf(&s, "%s::%s", modulePtr->name, nodePtr->name); } else { smiAsprintf(&s, "%s", nodePtr->name); } } } for (; i < oidlen; i++) { ss = s; smiAsprintf(&s, "%s%s%u", ss ? ss : "", i ? "." : "", oid[i]); smiFree(ss); } if ((!s) && (flags & SMI_RENDER_UNKNOWN)) { smiAsprintf(&s, SMI_UNKNOWN_LABEL); } return s; } char *smiRenderValue(SmiValue *smiValuePtr, SmiType *smiTypePtr, int flags) { unsigned int i, pfx; int j, k, n, have_pfx; char *last_fmt, *fmt; SmiUnsigned64 vv; int xlen; SmiNamedNumber *nn; char *s, *ss; char f[8]; SmiUnsigned32 v32; SmiUnsigned64 v64; if (!smiValuePtr) { if (flags & SMI_RENDER_UNKNOWN) { smiAsprintf(&s, SMI_UNKNOWN_LABEL); } else { s = NULL; } return s; } switch (smiValuePtr->basetype) { case SMI_BASETYPE_UNSIGNED32: if (!(flags & SMI_RENDER_FORMAT) || !smiTypePtr || !smiTypePtr->format || !strlen(smiTypePtr->format) || smiTypePtr->format[0] == 'd') { if (smiTypePtr->format && (strlen(smiTypePtr->format) >= 3) && (smiTypePtr->format[1] == '-')) { i = atoi(&smiTypePtr->format[2]); if (i < 0) i = 0; if (i > 20) i = 20; smiAsprintf(&s, "%0*lu.", 1 + i, smiValuePtr->value.unsigned32); if (s) { for (j = strlen(s) - 1; i > 0; i--, j--) { s[j] = s[j-1]; } s[j] = '.'; } } else { smiAsprintf(&s, "%lu", smiValuePtr->value.unsigned32); } } else if (smiTypePtr->format[0] == 'x') { smiAsprintf(&s, "%lx", smiValuePtr->value.unsigned32); } else if (smiTypePtr->format[0] == 'o') { smiAsprintf(&s, "%lo", smiValuePtr->value.unsigned32); } else if (smiTypePtr->format[0] == 'b') { for (i = 32 - 1; i > 0 && !(smiValuePtr->value.unsigned32 & (1 << i)); i--); s = smiMalloc(i + 1 + 1); if (s) { for (j = 0; i >= 0; i--, j++) { s[j] = smiValuePtr->value.unsigned32 & (1<format || !strlen(smiTypePtr->format) || smiTypePtr->format[0] == 'd') { if (smiTypePtr->format && (strlen(smiTypePtr->format) >= 3) && (smiTypePtr->format[1] == '-')) { i = atoi(&smiTypePtr->format[2]); if (i < 0) i = 0; if (i > 20) i = 20; sprintf(f, "%%0%s.", UINT64_FORMAT); f[2] = '*'; smiAsprintf(&s, f, 1 + i, smiValuePtr->value.unsigned64); if (s) { for (j = strlen(s) - 1; i > 0; i--, j--) { s[j] = s[j-1]; } s[j] = '.'; } } else { smiAsprintf(&s, UINT64_FORMAT, smiValuePtr->value.unsigned64); } } else if (smiTypePtr->format[0] == 'x') { strcpy(f, UINT64_FORMAT); f[strlen(f)-1] = 'x'; smiAsprintf(&s, f, smiValuePtr->value.unsigned64); } else if (smiTypePtr->format[0] == 'o') { strcpy(f, UINT64_FORMAT); f[strlen(f)-1] = 'o'; smiAsprintf(&s, f, smiValuePtr->value.unsigned64); } else if (smiTypePtr->format[0] == 'b') { for (i = 64 - 1; i > 0 && !(smiValuePtr->value.unsigned64 & (1 << i)); i--); s = smiMalloc(i + 1 + 1); if (s) { for (j = 0; i >= 0; i--, j++) { s[j] = smiValuePtr->value.unsigned64 & (1<format || !strlen(smiTypePtr->format) || smiTypePtr->format[0] == 'd') { if (smiTypePtr->format && (strlen(smiTypePtr->format) >= 3) && (smiTypePtr->format[1] == '-')) { i = atoi(&smiTypePtr->format[2]); if (i < 0) i = 0; if (i > 20) i = 20; smiAsprintf(&s, "%0*ld.", 1 + i + (smiValuePtr->value.integer32 < 0 ? 1 : 0), smiValuePtr->value.integer32); if (s) { for (j = strlen(s) - 1; i > 0; i--, j--) { s[j] = s[j-1]; } s[j] = '.'; } } else { smiAsprintf(&s, "%ld", smiValuePtr->value.integer32); } } else if (smiTypePtr->format[0] == 'x') { if (smiValuePtr->value.integer32 >= 0) { smiAsprintf(&s, "%lx", smiValuePtr->value.integer32); } else { smiAsprintf(&s, "-%lx", - smiValuePtr->value.integer32); } } else if (smiTypePtr->format[0] == 'o') { if (smiValuePtr->value.integer32 >= 0) { smiAsprintf(&s, "%lo", smiValuePtr->value.integer32); } else { smiAsprintf(&s, "-%lo", - smiValuePtr->value.integer32); } } else if (smiTypePtr->format[0] == 'b') { if (smiValuePtr->value.integer32 >= 0) { v32 = smiValuePtr->value.integer32; j = 0; } else { v32 = - smiValuePtr->value.integer32; j = 1; } for (i = 32 - 1; i > 0 && !(v32 & (1 << i)); i--); s = smiMalloc(i + j + 1 + 1); if (s) { s[0] = '-'; for (; i >= 0; i--, j++) { s[j] = v32 & (1<format || !strlen(smiTypePtr->format) || smiTypePtr->format[0] == 'd') { if (smiTypePtr->format && (strlen(smiTypePtr->format) >= 3) && (smiTypePtr->format[1] == '-')) { i = atoi(&smiTypePtr->format[2]); if (i < 0) i = 0; if (i > 20) i = 20; sprintf(f, "%%0%s.", INT64_FORMAT); f[2] = '*'; smiAsprintf(&s, f, 1 + i + (smiValuePtr->value.integer64 < 0 ? 1 : 0), smiValuePtr->value.integer64); if (s) { for (j = strlen(s) - 1; i > 0; i--, j--) { s[j] = s[j-1]; } s[j] = '.'; } } else { smiAsprintf(&s, INT64_FORMAT, smiValuePtr->value.integer64); } } else if (smiTypePtr->format[0] == 'x') { if (smiValuePtr->value.integer64 >= 0) { strcpy(f, UINT64_FORMAT); f[strlen(f)-1] = 'x'; smiAsprintf(&s, f, smiValuePtr->value.integer64); } else { sprintf(f, "-%s", UINT64_FORMAT); f[strlen(f)-1] = 'x'; smiAsprintf(&s, f, - smiValuePtr->value.integer64); } } else if (smiTypePtr->format[0] == 'o') { if (smiValuePtr->value.integer64 >= 0) { strcpy(f, UINT64_FORMAT); sprintf(f, "-%s", UINT64_FORMAT); f[strlen(f)-1] = 'o'; smiAsprintf(&s, f, smiValuePtr->value.integer64); } else { smiAsprintf(&s, f, - smiValuePtr->value.integer64); } } else if (smiTypePtr->format[0] == 'b') { if (smiValuePtr->value.integer64 >= 0) { v64 = smiValuePtr->value.integer64; j = 0; } else { v64 = - smiValuePtr->value.integer64; j = 1; } for (i = 64 - 1; i > 0 && !(v64 & (1 << i)); i--); s = smiMalloc(i + j + 1 + 1); if (s) { s[0] = '-'; for (; i >= 0; i--, j++) { s[j] = v64 & (1<len, smiValuePtr->value.oid, flags); break; case SMI_BASETYPE_OCTETSTRING: if (!(flags & SMI_RENDER_FORMAT) || (!smiTypePtr->format && (smiTypePtr->name && strcmp( smiTypePtr->name, "IpAddress")) ) ) { for (i = 0; i < smiValuePtr->len; i++) { if (!isprint((int)smiValuePtr->value.ptr[i])) break; } if ((i < smiValuePtr->len) || !(flags & SMI_RENDER_PRINTABLE)) { smiAsprintf(&s, ""); for (i=0; i < smiValuePtr->len; i++) { ss = s; smiAsprintf(&s, "%s%02x", ss, smiValuePtr->value.ptr[i]); smiFree(ss); } } else { smiAsprintf(&s, "%s", smiValuePtr->value.ptr); } } else { i = 0; smiAsprintf(&s, ""); /* SNMPv2-SMI:IpAddress does not have a display hint. ==> let's use this one: "1d." if we have an IpAddress here */ fmt = (smiTypePtr->name && strcmp( smiTypePtr->name, "IpAddress" ) ) ? smiTypePtr->format : "1d."; while (*fmt && i < smiValuePtr->len) { last_fmt = fmt; have_pfx = pfx = 0; /* scan prefix: */ while (*fmt && isdigit((int)*fmt)) { pfx = pfx * 10 + *fmt - '0', have_pfx = 1, fmt++; } if (! have_pfx) { pfx = 1; } switch (*fmt) { case 't': /* XXX UTF-8 not implemented, fall through to ASCII (a) */ case 'a': n = (pfx < (smiValuePtr->len - i)) ? pfx : smiValuePtr->len - i; for (k = 0; k < n; k++) { if (! isascii((int) smiValuePtr->value.ptr[i+k])) { smiFree(s); if (flags & SMI_RENDER_UNKNOWN) { smiAsprintf(&s, SMI_UNKNOWN_LABEL); } else { s = NULL; } return s; } ss = s; smiAsprintf(&s, "%s%c", ss, smiValuePtr->value.ptr[i+k]); smiFree(ss); } i += n; break; case 'b': case 'd': case 'o': case 'x': /* XXX: limited to no more than sizeof(SmiUnsigned64) octets */ vv = 0; xlen = pfx * 2; while (pfx > 0 && i < smiValuePtr->len) { vv = vv * 256 + ((unsigned char)smiValuePtr->value.ptr[i]); i++; pfx--; } switch (*fmt) { case 'd': ss = s; sprintf(f, "%%s%s", UINT64_FORMAT); smiAsprintf(&s, f, ss, vv); smiFree(ss); break; case 'o': ss = s; sprintf(f, "%%s%s", UINT64_FORMAT); f[strlen(f)-1] = 'o'; smiAsprintf(&s, f, ss, vv); smiFree(ss); break; case 'x': ss = s; sprintf(f, "%%s%%0%s", UINT64_FORMAT); f[4] = '*'; f[strlen(f)-1] = 'x'; smiAsprintf(&s, f, ss, xlen, vv); smiFree(ss); break; case 'b': k = pfx * 8 - 1; if (k > sizeof(SmiUnsigned64) * 8 - 1) k = sizeof(SmiUnsigned64) * 8 - 1; for (j = 0; k >= 0; k--, j++) { ss = s; smiAsprintf(&s, "%s%c", ss, vv & (1 << k) ? '1' : '0'); smiFree(ss); } break; } break; default: smiFree(s); if (flags & SMI_RENDER_UNKNOWN) { smiAsprintf(&s, SMI_UNKNOWN_LABEL); } else { s = NULL; } return s; } fmt++; /* * Check for a separator and repeat with last format if * data is still available. */ if (*fmt && ! isdigit((int) *fmt) && *fmt != '*') { if (i < smiValuePtr->len) { ss = s; smiAsprintf(&s, "%s%c", ss, fmt[0]); smiFree(ss); } fmt++; } if (! *fmt && (i < smiValuePtr->len)) { fmt = last_fmt; } } } break; case SMI_BASETYPE_ENUM: if ((flags & SMI_RENDER_NAME) && (smiTypePtr)) { for (nn = smiGetFirstNamedNumber(smiTypePtr); nn; nn = smiGetNextNamedNumber(nn)) { if (nn->value.value.integer32 == smiValuePtr->value.integer32) break; } if (nn) { if (flags & SMI_RENDER_NUMERIC) { smiAsprintf(&s, "%s(%ld)", nn->name, nn->value.value.integer32); } else { smiAsprintf(&s, "%s", nn->name); } } else { smiAsprintf(&s, "%ld", smiValuePtr->value.integer32); } } else { smiAsprintf(&s, "%ld", smiValuePtr->value.integer32); } break; case SMI_BASETYPE_BITS: smiAsprintf(&s, ""); for (i = 0, nn = NULL; i < smiValuePtr->len * 8; i++) { if (smiValuePtr->value.ptr[i/8] & (1 << (7-(i%8)))) { if ((flags & SMI_RENDER_NAME) && (smiTypePtr)) { for (nn = smiGetFirstNamedNumber(smiTypePtr); nn; nn = smiGetNextNamedNumber(nn)) { if (nn->value.value.unsigned32 == i) break; } } ss = s; if ((flags & SMI_RENDER_NAME) && (flags & SMI_RENDER_NUMERIC) && nn) { smiAsprintf(&s, "%s%s%s(%d)", ss, strlen(ss) ? " " : "", nn->name, i); } else if (nn) { smiAsprintf(&s, "%s%s%s", ss, strlen(ss) ? " " : "", nn->name); } else { smiAsprintf(&s, "%s%s%d", ss, strlen(ss) ? " " : "", i); } smiFree(ss); } } break; case SMI_BASETYPE_FLOAT32: case SMI_BASETYPE_FLOAT64: case SMI_BASETYPE_FLOAT128: case SMI_BASETYPE_UNKNOWN: default: if (flags & SMI_RENDER_UNKNOWN) { smiAsprintf(&s, SMI_UNKNOWN_LABEL); } else { s = NULL; } break; } return s; } char *smiRenderNode(SmiNode *smiNodePtr, int flags) { char *s; SmiModule *modulePtr; if ((!smiNodePtr) || (smiNodePtr->name == NULL)) { if (flags & SMI_RENDER_UNKNOWN) { smiAsprintf(&s, SMI_UNKNOWN_LABEL); } else { s = NULL; } } else { modulePtr = smiGetNodeModule(smiNodePtr); if ((!(flags & SMI_RENDER_QUALIFIED)) || (!modulePtr) || (!strlen(modulePtr->name))) { smiAsprintf(&s, "%s", smiNodePtr->name); } else { smiAsprintf(&s, "%s::%s", modulePtr->name, smiNodePtr->name); } } return s; } char *smiRenderType(SmiType *smiTypePtr, int flags) { char *s; SmiModule *modulePtr; if ((!smiTypePtr) || (smiTypePtr->name == NULL)) { if (flags & SMI_RENDER_UNKNOWN) { smiAsprintf(&s, SMI_UNKNOWN_LABEL); } else { s = NULL; } } else { modulePtr = smiGetTypeModule(smiTypePtr); if ((!(flags & SMI_RENDER_QUALIFIED)) || (!modulePtr) || (!strlen(modulePtr->name))) { smiAsprintf(&s, "%s", smiTypePtr->name); } else { smiAsprintf(&s, "%s::%s", modulePtr->name, smiTypePtr->name); } } return s; } unsigned int smiGetMinSize(SmiType *smiType) { SmiRange *smiRange; SmiType *parentType; unsigned int min = 65535, size; switch (smiType->basetype) { case SMI_BASETYPE_BITS: return 0; case SMI_BASETYPE_OCTETSTRING: case SMI_BASETYPE_OBJECTIDENTIFIER: size = 0; break; default: return 0; } for (smiRange = smiGetFirstRange(smiType); smiRange ; smiRange = smiGetNextRange(smiRange)) { if (smiRange->minValue.value.unsigned32 < min) { min = smiRange->minValue.value.unsigned32; } } if (min < 65535 && min > size) { size = min; } parentType = smiGetParentType(smiType); if (parentType) { unsigned int psize = smiGetMinSize(parentType); if (psize > size) { size = psize; } } return size; } unsigned int smiGetMaxSize(SmiType *smiType) { SmiRange *smiRange; SmiType *parentType; SmiNamedNumber *nn; unsigned int max = 0, size; switch (smiType->basetype) { case SMI_BASETYPE_BITS: case SMI_BASETYPE_OCTETSTRING: size = 65535; break; case SMI_BASETYPE_OBJECTIDENTIFIER: size = 128; break; default: return 0xffffffff; } if (smiType->basetype == SMI_BASETYPE_BITS) { for (nn = smiGetFirstNamedNumber(smiType); nn; nn = smiGetNextNamedNumber(nn)) { if (nn->value.value.unsigned32 > max) { max = nn->value.value.unsigned32; } } size = (max / 8) + 1; return size; } for (smiRange = smiGetFirstRange(smiType); smiRange ; smiRange = smiGetNextRange(smiRange)) { if (smiRange->maxValue.value.unsigned32 > max) { max = smiRange->maxValue.value.unsigned32; } } if (max > 0 && max < size) { size = max; } parentType = smiGetParentType(smiType); if (parentType) { unsigned int psize = smiGetMaxSize(parentType); if (psize < size) { size = psize; } } return size; } int smiUnpack(SmiNode *row, SmiSubid *oid, unsigned int oidlen, SmiValue **vals, int *valslen) { SmiNode *indexNode = NULL; SmiElement *smiElement; SmiNode *iNode; SmiType *iType; int i, j, last = 0; if (!vals || !valslen || !row || !oid) { return 0; } switch (row->indexkind) { case SMI_INDEX_INDEX: case SMI_INDEX_REORDER: indexNode = row; break; case SMI_INDEX_EXPAND: /* TODO: we have to do more work here! */ indexNode = NULL; break; case SMI_INDEX_AUGMENT: case SMI_INDEX_SPARSE: indexNode = smiGetRelatedNode(row); break; case SMI_INDEX_UNKNOWN: indexNode = NULL; break; } *valslen = 0; for (smiElement = smiGetFirstElement(indexNode); smiElement; smiElement = smiGetNextElement(smiElement)) { iNode = smiGetElementNode(smiElement); if (iNode) { iType = smiGetNodeType(iNode); if (! iType) break; (*valslen)++; } } if (smiElement) { return 0; } *vals = smiMalloc(*valslen * sizeof(SmiValue)); for (smiElement = smiGetFirstElement(indexNode), i = 0, j = 0; smiElement; smiElement = smiGetNextElement(smiElement), i++) { iNode = smiGetElementNode(smiElement); last = (smiGetNextElement(smiElement) == NULL); iType = smiGetNodeType(iNode); fprintf(stderr, "** %s (%s)\n", iNode->name, iType->name); (*vals)[i].basetype = iType->basetype; switch (iType->basetype) { case SMI_BASETYPE_ENUM: case SMI_BASETYPE_INTEGER32: (*vals)[i].value.integer32 = oid[j]; j++; break; case SMI_BASETYPE_UNSIGNED32: (*vals)[i].value.unsigned32 = oid[j]; j++; break; case SMI_BASETYPE_OCTETSTRING: /* need to know whether implied/fixed length or not */ break; case SMI_BASETYPE_OBJECTIDENTIFIER: /* need to know whether implied/fixed length or not */ break; default: return 0; } } return *valslen; } int smiAsprintf(char **strp, const char *format, ...) { int rc; va_list ap; va_start(ap, format); rc = vasprintf(strp, format, ap); va_end(ap); if (! strp) { smiPrintError(NULL, ERR_OUT_OF_MEMORY); } return rc; } int smiVasprintf(char **strp, const char *format, va_list ap) { int rc; rc = vasprintf(strp, format, ap); if (! strp) { smiPrintError(NULL, ERR_OUT_OF_MEMORY); } return rc; } int smiGetMinMaxRange(SmiType *smiType, SmiValue *min, SmiValue *max) { SmiBasetype basetype = SMI_BASETYPE_UNKNOWN; SmiRange *range; min->basetype = max->basetype = SMI_BASETYPE_UNKNOWN; min->len = max->len = 0; range = smiGetFirstRange(smiType); if (!range) { return 0; } basetype = range->minValue.basetype; min->basetype = max->basetype = basetype; switch (basetype) { case SMI_BASETYPE_INTEGER32: min->value.integer32 = SMI_BASETYPE_INTEGER32_MAX; max->value.integer32 = SMI_BASETYPE_INTEGER32_MIN; break; case SMI_BASETYPE_INTEGER64: min->value.integer64 = SMI_BASETYPE_INTEGER64_MAX; max->value.integer64 = SMI_BASETYPE_INTEGER64_MIN; break; case SMI_BASETYPE_UNSIGNED32: min->value.unsigned32 = SMI_BASETYPE_UNSIGNED32_MAX; max->value.unsigned32 = SMI_BASETYPE_UNSIGNED32_MIN; break; case SMI_BASETYPE_UNSIGNED64: min->value.unsigned64 = SMI_BASETYPE_UNSIGNED64_MAX; max->value.unsigned64 = SMI_BASETYPE_UNSIGNED32_MIN; break; default: fprintf(stderr, "smidump: unexpected basetype %d\n", basetype); return -1; } for (range = smiGetFirstRange(smiType); range; range = smiGetNextRange(range)) { switch (basetype) { case SMI_BASETYPE_INTEGER32: if (range->minValue.value.integer32 < min->value.integer32) { min->value.integer32 = range->minValue.value.integer32; } if (range->maxValue.value.integer32 > max->value.integer32) { max->value.integer32 = range->maxValue.value.integer32; } break; case SMI_BASETYPE_INTEGER64: if (range->minValue.value.integer64 < min->value.integer64) { min->value.integer64 = range->minValue.value.integer64; } if (range->maxValue.value.integer64 > max->value.integer64) { max->value.integer64 = range->maxValue.value.integer64; } break; case SMI_BASETYPE_UNSIGNED32: if (range->minValue.value.unsigned32 < min->value.unsigned32) { min->value.unsigned32 = range->minValue.value.unsigned32; } if (range->maxValue.value.unsigned32 > max->value.unsigned32) { max->value.unsigned32 = range->maxValue.value.unsigned32; } break; case SMI_BASETYPE_UNSIGNED64: if (range->minValue.value.unsigned64 < min->value.unsigned64) { min->value.unsigned64 = range->minValue.value.unsigned64; } if (range->maxValue.value.unsigned64 > max->value.unsigned64) { max->value.unsigned64 = range->maxValue.value.unsigned64; } break; default: fprintf(stderr, "smidump: unexpected basetype %d\n", basetype); return -1; } } return 0; }