4 * Interface Implementation of libsmi.
6 * Copyright (c) 1999 Frank Strauss, Technical University of Braunschweig.
8 * See the file "COPYING" for information on usage and redistribution
9 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11 * @(#) $Id: smi.c 8071 2008-04-17 11:14:46Z schoenw $
20 #include <sys/types.h>
35 #include "scanner-smi.h"
36 #include "parser-smi.h"
40 #include "scanner-sming.h"
41 #include "parser-sming.h"
51 #define MIN(a, b) ((a) < (b) ? (a) : (b))
52 #define MAX(a, b) ((a) < (b) ? (b) : (a))
57 const char *smi_library_version = SMI_LIBRARY_VERSION;
58 const char *smi_version_string = SMI_VERSION_STRING;
60 Handle *smiHandle = NULL;
68 static void getModulenameAndName(const char *arg1, const char *arg2,
69 char **module, char **name)
74 if ((!arg1) && (!arg2)) {
78 if (isupper((int)arg1[0])) {
79 if ((p = strstr(arg1, "::"))) {
80 /* SMIng style module/label separator */
81 *name = smiStrdup(&p[2]);
82 l = strcspn(arg1, "::");
83 *module = smiStrndup(arg1, l);
84 } else if ((p = strchr(arg1, '!'))) {
85 /* old scotty style module/label separator */
86 *name = smiStrdup(&p[1]);
87 l = strcspn(arg1, "!");
88 *module = smiStrndup(arg1, l);
89 } else if ((p = strchr(arg1, '.'))) {
90 /* SMIv1/v2 style module/label separator */
91 *name = smiStrdup(&p[1]);
92 l = strcspn(arg1, ".");
93 *module = smiStrndup(arg1, l);
95 *name = smiStrdup(arg1);
96 *module = smiStrdup("");
99 *name = smiStrdup(arg1);
100 *module = smiStrdup("");
103 if (isupper((int)arg2[0])) {
104 if ((p = strstr(arg2, "::"))) {
105 /* SMIng style module/label separator */
106 *name = smiStrdup(&p[2]);
107 l = strcspn(arg2, "::");
108 *module = smiStrndup(arg2, l);
109 } else if ((p = strchr(arg2, '!'))) {
110 /* old scotty style module/label separator */
111 *name = smiStrdup(&p[1]);
112 l = strcspn(arg2, "!");
113 *module = smiStrndup(arg2, l);
114 } else if ((p = strchr(arg2, '.'))) {
115 /* SMIv1/v2 style module/label separator */
116 *name = smiStrdup(&p[1]);
117 l = strcspn(arg2, ".");
118 *module = smiStrndup(arg2, l);
120 *name = smiStrdup(arg2);
121 *module = smiStrdup("");
124 *name = smiStrdup(arg2);
125 *module = smiStrdup("");
128 *module = smiStrdup(arg1);
129 *name = smiStrdup(arg2);
135 static Node *getNode(unsigned int oidlen, SmiSubid oid[])
137 Node *nodePtr, *parentPtr;
140 for(nodePtr = smiHandle->rootNodePtr, i=0; i < oidlen; i++) {
142 nodePtr = findNodeByParentAndSubid(parentPtr, oid[i]);
153 static Object *getNextChildObject(Node *startNodePtr, Module *modulePtr,
154 SmiNodekind nodekind)
157 Object *objectPtr = NULL;
159 if (!startNodePtr || !modulePtr)
162 for (nodePtr = startNodePtr; nodePtr; nodePtr = nodePtr->nextPtr) {
163 for (objectPtr = nodePtr->firstObjectPtr; objectPtr;
164 objectPtr = objectPtr->nextSameNodePtr) {
165 if (((!modulePtr) || (objectPtr->modulePtr == modulePtr)) &&
166 ((nodekind == SMI_NODEKIND_ANY) ||
167 (nodekind & objectPtr->export.nodekind))) {
171 if (objectPtr) break;
172 objectPtr = getNextChildObject(nodePtr->firstChildPtr,
173 modulePtr, nodekind);
174 if (objectPtr) break;
183 * Interface Functions.
186 int smiInit(const char *tag)
193 smiHandle = findHandleByName(tag);
197 smiHandle = addHandle(tag);
201 smiHandle->errorLevel = DEFAULT_ERRORLEVEL;
202 smiHandle->errorHandler = smiErrorHandler;
203 #if !defined(_MSC_VER)
204 smiHandle->cache = NULL;
205 smiHandle->cacheProg = NULL;
213 * Setup the SMI MIB module search path:
214 * 1. set to builtin DEFAULT_SMIPATH
215 * 2. read global config file if present (append/prepend/replace)
216 * 3. read user config file if present (append/prepend/replace)
217 * 4. evaluate SMIPATH env-var if set (append/prepend/replace)
220 /* 1. set to builtin DEFAULT_SMIPATH */
221 smiHandle->path = smiStrdup(DEFAULT_SMIPATH);
223 tag2 = smiStrdup(tag);
224 if (tag2) tag2 = strtok(tag2, ":");
226 /* 2. read global config file if present (append/prepend/replace) */
227 smiReadConfig(DEFAULT_GLOBALCONFIG, tag2);
229 pw = getpwuid(getuid());
230 if (pw && pw->pw_dir) {
231 /* 3. read user config file if present (append/prepend/replace) */
232 smiAsprintf(&p, "%s%c%s",
233 pw->pw_dir, DIR_SEPARATOR, DEFAULT_USERCONFIG);
234 smiReadConfig(p, tag2);
241 /* 4. evaluate SMIPATH env-var if set (append/prepend/replace) */
242 p = getenv("SMIPATH");
244 if (p[0] == PATH_SEPARATOR) {
245 smiAsprintf(&pp, "%s%s", smiHandle->path, p);
246 smiFree(smiHandle->path);
247 smiHandle->path = pp;
248 } else if (p[strlen(p)-1] == PATH_SEPARATOR) {
249 smiAsprintf(&pp, "%s%s", p, smiHandle->path);
250 smiFree(smiHandle->path);
251 smiHandle->path = pp;
253 smiHandle->path = smiStrdup(p);
257 if (!smiHandle->path) {
273 smiFree(smiHandle->path);
274 #if !defined(_MSC_VER)
275 smiFree(smiHandle->cache);
276 smiFree(smiHandle->cacheProg);
279 removeHandle(smiHandle);
289 if (smiHandle->path) {
290 return smiStrdup(smiHandle->path);
298 int smiSetPath(const char *s)
302 if (!smiHandle) smiInit(NULL);
305 smiFree(smiHandle->path);
306 smiHandle->path = NULL;
312 smiFree(smiHandle->path);
313 smiHandle->path = s2;
323 void smiSetSeverity(char *pattern, int severity)
325 smiSetErrorSeverity(pattern, severity);
330 int smiReadConfig(const char *filename, const char *tag)
336 file = fopen(filename, "r");
338 while (!feof(file)) {
339 if (!fgets(buf, 200, file)) continue;
340 if ((!strlen(buf)) || (buf[0] == '#')) continue;
341 cmd = strtok(buf, " \t\n\r");
343 if (cmd[0] == '#') continue;
344 if (cmd[strlen(cmd)-1] == ':') {
346 cmd[strlen(cmd)-1] = 0;
347 if (strcmp(cmd, tag)) continue;
348 cmd = strtok(NULL, " \t\n\r");
350 arg = strtok(NULL, " \t\n\r");
351 if (!strcmp(cmd, "load")) {
353 } else if (!strcmp(cmd, "path")) {
355 if (arg[0] == PATH_SEPARATOR) {
356 smiAsprintf(&s, "%s%s", smiHandle->path, arg);
357 smiFree(smiHandle->path);
359 } else if (arg[strlen(arg)-1] == PATH_SEPARATOR) {
360 smiAsprintf(&s, "%s%s", arg, smiHandle->path);
361 smiFree(smiHandle->path);
364 smiHandle->path = smiStrdup(arg);
367 } else if (!strcmp(cmd, "cache")) {
368 #if !defined(_MSC_VER)
369 smiFree(smiHandle->cache);
370 smiFree(smiHandle->cacheProg);
372 if (arg && strcmp(arg, "off")) {
373 #if !defined(_MSC_VER)
374 smiHandle->cache = smiStrdup(arg);
375 arg = strtok(NULL, "\n\r");
376 smiHandle->cacheProg = smiStrdup(arg);
378 smiPrintError(NULL, ERR_CACHE_CONFIG_NOT_SUPPORTED,
382 } else if (!strcmp(cmd, "level")) {
383 smiSetErrorLevel(atoi(arg));
384 } else if (!strcmp(cmd, "hide")) {
385 smiSetSeverity(arg, 9);
387 smiPrintError(NULL, ERR_UNKNOWN_CONFIG_CMD, cmd, filename);
398 int smiIsLoaded(const char *module)
403 return isInView(module);
408 char *smiLoadModule(const char *module)
412 if (!smiHandle) smiInit(NULL);
414 if (smiIsPath(module)) {
416 modulePtr = loadModule(module, NULL);
419 if (!isInView(modulePtr->export.name)) {
420 addView(modulePtr->export.name);
422 return modulePtr->export.name;
429 if ((modulePtr = findModuleByName(module))) {
430 /* already loaded. */
431 if (!isInView(module)) {
434 return modulePtr->export.name;
436 if ((modulePtr = loadModule(module, NULL))) {
437 if (!isInView(module)) {
440 return modulePtr->export.name;
450 void smiSetErrorLevel(int level)
452 if (!smiHandle) smiInit(NULL);
454 smiHandle->errorLevel = level;
459 void smiSetFlags(int userflags)
461 if (!smiHandle) smiInit(NULL);
463 smiHandle->flags = (smiHandle->flags & ~SMI_FLAG_MASK) | userflags;
470 if (!smiHandle) smiInit(NULL);
472 return smiHandle->flags & SMI_FLAG_MASK;
477 SmiModule *smiGetModule(const char *module)
485 modulePtr = findModuleByName(module);
488 modulePtr = loadModule(module, NULL);
491 return &modulePtr->export;
496 SmiModule *smiGetFirstModule()
500 for (modulePtr = smiHandle->firstModulePtr;
501 modulePtr && modulePtr->export.name &&
502 (strlen(modulePtr->export.name) == 0);
503 modulePtr = modulePtr->nextPtr);
505 return &modulePtr->export;
510 SmiModule *smiGetNextModule(SmiModule *smiModulePtr)
519 for (modulePtr = ((Module *)smiModulePtr)->nextPtr;
520 modulePtr && modulePtr->export.name &&
521 (strlen(modulePtr->export.name) == 0);
522 modulePtr = modulePtr->nextPtr);
524 return &modulePtr->export;
529 SmiImport *smiGetFirstImport(SmiModule *smiModulePtr)
535 return &((Module *)smiModulePtr)->firstImportPtr->export;
540 SmiImport *smiGetNextImport(SmiImport *smiImportPtr)
546 return &((Import *)smiImportPtr)->nextPtr->export;
551 int smiIsImported(SmiModule *smiModulePtr,
552 SmiModule *importedModulePtr,
557 char *importedModule;
559 if ((!smiModulePtr) || (!importedName)) {
563 modulePtr = (Module *)smiModulePtr;
565 if (importedModulePtr) {
566 importedModule = importedModulePtr->name;
568 importedModule = NULL;
571 for (importPtr = modulePtr->firstImportPtr; importPtr;
572 importPtr = importPtr->nextPtr) {
573 if ((!strcmp(importedName, importPtr->export.name)) &&
574 ((!importedModule) ||
575 (!strcmp(importedModule, importPtr->export.module)))) {
585 SmiRevision *smiGetFirstRevision(SmiModule *smiModulePtr)
591 return &((Module *)smiModulePtr)->firstRevisionPtr->export;
596 SmiRevision *smiGetNextRevision(SmiRevision *smiRevisionPtr)
598 if (!smiRevisionPtr) {
602 return &((Revision *)smiRevisionPtr)->nextPtr->export;
607 int smiGetRevisionLine(SmiRevision *smiRevisionPtr)
609 return ((Revision *)smiRevisionPtr)->line;
614 SmiType *smiGetType(SmiModule *smiModulePtr, char *type)
616 Type *typePtr = NULL;
617 Module *modulePtr = NULL;
618 char *module2, *type2;
624 modulePtr = (Module *)smiModulePtr;
626 getModulenameAndName(smiModulePtr ? smiModulePtr->name : NULL, type,
629 if (!modulePtr && module2 && strlen(module2)) {
630 if (!(modulePtr = findModuleByName(module2))) {
631 modulePtr = loadModule(module2, NULL);
636 typePtr = findTypeByModuleAndName(modulePtr, type2);
638 typePtr = findTypeByName(type2);
645 typePtr->export.basetype == SMI_BASETYPE_UNKNOWN) {
649 return &typePtr->export;
654 SmiType *smiGetFirstType(SmiModule *smiModulePtr)
662 for (typePtr = ((Module *)smiModulePtr)->firstTypePtr; typePtr;
663 typePtr = typePtr->nextPtr) {
664 /* loop until we found a `real' type */
665 if (typePtr->export.name &&
666 typePtr->export.basetype != SMI_BASETYPE_UNKNOWN) {
671 return &typePtr->export;
676 SmiType *smiGetNextType(SmiType *smiTypePtr)
684 for (typePtr = ((Type *)smiTypePtr)->nextPtr; typePtr;
685 typePtr = typePtr->nextPtr) {
686 /* loop until we found a `real' type */
687 if (typePtr->export.name &&
688 typePtr->export.basetype != SMI_BASETYPE_UNKNOWN) {
693 return &typePtr->export;
697 SmiType *smiGetParentType(SmiType *smiTypePtr)
705 typePtr = ((Type *)smiTypePtr)->parentPtr;
708 typePtr->export.basetype == SMI_BASETYPE_UNKNOWN) {
712 return &typePtr->export;
717 SmiModule *smiGetTypeModule(SmiType *smiTypePtr)
719 return &((Type *)smiTypePtr)->modulePtr->export;
722 int smiGetTypeLine(SmiType *smiTypePtr)
724 return ((Type *)smiTypePtr)->line;
729 SmiNamedNumber *smiGetFirstNamedNumber(SmiType *smiTypePtr)
733 typePtr = (Type *)smiTypePtr;
735 if ((!typePtr) || (!typePtr->listPtr) ||
736 ((typePtr->export.basetype != SMI_BASETYPE_ENUM) &&
737 (typePtr->export.basetype != SMI_BASETYPE_BITS) &&
738 (typePtr->export.basetype != SMI_BASETYPE_POINTER))) {
742 return &((NamedNumber *)typePtr->listPtr->ptr)->export;
747 SmiNamedNumber *smiGetNextNamedNumber(SmiNamedNumber *smiNamedNumberPtr)
752 if (!smiNamedNumberPtr) {
756 typePtr = ((NamedNumber *)smiNamedNumberPtr)->typePtr;
759 if ((!typePtr) || (!typePtr->listPtr) ||
760 ((typePtr->export.basetype != SMI_BASETYPE_ENUM) &&
761 (typePtr->export.basetype != SMI_BASETYPE_BITS))) {
765 for (listPtr = typePtr->listPtr; listPtr; listPtr = listPtr->nextPtr) {
766 if (((NamedNumber *)(listPtr->ptr))->export.name ==
767 smiNamedNumberPtr->name)
771 if ((!listPtr) || (!listPtr->nextPtr)) {
775 return &((NamedNumber *)listPtr->nextPtr->ptr)->export;
778 SmiNamedNumber *smiGetAttributeFirstNamedNumber(SmiAttribute *smiAttributePtr)
780 Attribute *attributePtr;
782 attributePtr = (Attribute *)smiAttributePtr;
784 if ((!attributePtr) || (!attributePtr->listPtr) ||
785 ((attributePtr->export.basetype != SMI_BASETYPE_ENUM) &&
786 (attributePtr->export.basetype != SMI_BASETYPE_BITS) &&
787 (attributePtr->export.basetype != SMI_BASETYPE_POINTER))) {
791 return &((NamedNumber *)attributePtr->listPtr->ptr)->export;
796 SmiNamedNumber *smiGetAttributeNextNamedNumber(SmiNamedNumber *smiNamedNumberPtr)
798 Attribute *attributePtr;
801 if (!smiNamedNumberPtr) {
805 attributePtr = (Attribute*)(((NamedNumber *)smiNamedNumberPtr)->typePtr);
808 if ((!attributePtr) || (!attributePtr->listPtr) ||
809 ((attributePtr->export.basetype != SMI_BASETYPE_ENUM) &&
810 (attributePtr->export.basetype != SMI_BASETYPE_BITS))) {
814 for (listPtr = attributePtr->listPtr; listPtr; listPtr = listPtr->nextPtr) {
815 if (((NamedNumber *)(listPtr->ptr))->export.name ==
816 smiNamedNumberPtr->name)
820 if ((!listPtr) || (!listPtr->nextPtr)) {
824 return &((NamedNumber *)listPtr->nextPtr->ptr)->export;
827 SmiRange *smiGetFirstRange(SmiType *smiTypePtr)
831 typePtr = (Type *)smiTypePtr;
833 if ((!typePtr) || (!typePtr->listPtr) ||
834 (typePtr->export.basetype == SMI_BASETYPE_ENUM) ||
835 (typePtr->export.basetype == SMI_BASETYPE_BITS)) {
839 return &((Range *)typePtr->listPtr->ptr)->export;
844 SmiRange *smiGetNextRange(SmiRange *smiRangePtr)
853 typePtr = ((Range *)smiRangePtr)->typePtr;
855 if ((!typePtr) || (!typePtr->listPtr) ||
856 (typePtr->export.basetype == SMI_BASETYPE_ENUM) ||
857 (typePtr->export.basetype == SMI_BASETYPE_BITS)) {
861 for (listPtr = typePtr->listPtr; listPtr; listPtr = listPtr->nextPtr) {
862 if (!memcmp(&((Range *)listPtr->ptr)->export.minValue,
863 &smiRangePtr->minValue, sizeof(struct SmiValue)))
867 if ((!listPtr) || (!listPtr->nextPtr)) {
871 return &((Range *)listPtr->nextPtr->ptr)->export;
874 SmiRange *smiGetAttributeFirstRange(SmiAttribute *smiAttributePtr)
876 Attribute *attributePtr;
878 attributePtr = (Attribute *)smiAttributePtr;
880 if ((!attributePtr) || (!attributePtr->listPtr) ||
881 (attributePtr->export.basetype == SMI_BASETYPE_ENUM) ||
882 (attributePtr->export.basetype == SMI_BASETYPE_BITS)) {
886 return &((Range *)attributePtr->listPtr->ptr)->export;
891 SmiRange *smiGetAttributeNextRange(SmiRange *smiRangePtr)
893 Attribute *attributePtr;
900 attributePtr = (Attribute*)((Range *)smiRangePtr)->typePtr;
902 if ((!attributePtr) || (!attributePtr->listPtr) ||
903 (attributePtr->export.basetype == SMI_BASETYPE_ENUM) ||
904 (attributePtr->export.basetype == SMI_BASETYPE_BITS)) {
908 for (listPtr = attributePtr->listPtr; listPtr; listPtr = listPtr->nextPtr) {
909 if (!memcmp(&((Range *)listPtr->ptr)->export.minValue,
910 &smiRangePtr->minValue, sizeof(struct SmiValue)))
914 if ((!listPtr) || (!listPtr->nextPtr)) {
918 return &((Range *)listPtr->nextPtr->ptr)->export;
922 SmiIdentity *smiGetFirstIdentity(SmiModule *smiModulePtr)
928 return ((Module *)smiModulePtr)->firstIdentityPtr ?
929 &((Module *)smiModulePtr)->firstIdentityPtr->export : NULL;
933 SmiIdentity *smiGetNextIdentity(SmiIdentity *smiIdentityPtr)
935 if (!smiIdentityPtr) {
939 return ((Identity *)smiIdentityPtr)->nextPtr ?
940 &((Identity *)smiIdentityPtr)->nextPtr->export : NULL;
943 SmiModule *smiGetIdentityModule(SmiIdentity *smiIdentityPtr)
945 return &((Identity *)smiIdentityPtr)->modulePtr->export;
948 SmiIdentity *smiGetParentIdentity(SmiIdentity *smiIdentityPtr)
950 return (SmiIdentity*)(((Identity *)smiIdentityPtr)->parentPtr);
953 SmiIdentity *smiGetIdentity(SmiModule *smiModulePtr, char *identity)
963 for(ide = smiGetFirstIdentity(smiModulePtr);
965 ide = smiGetNextIdentity(ide))
966 if(!strncmp(ide->name,identity,64))return ide;
973 int smiGetIdentityLine(SmiIdentity *smiIdentityPtr)
975 return ((Identity *)smiIdentityPtr)->line;
979 SmiClass *smiGetFirstClass(SmiModule *smiModulePtr)
985 return ((Module *)smiModulePtr)->firstClassPtr ?
986 &((Module *)smiModulePtr)->firstClassPtr->export : NULL;
990 SmiClass *smiGetNextClass(SmiClass *smiClassPtr)
996 return ((Class *)smiClassPtr)->nextPtr ?
997 &((Class *)smiClassPtr)->nextPtr->export : NULL;
1000 SmiModule *smiGetClassModule(SmiClass *smiClassPtr)
1002 return &((Class *)smiClassPtr)->modulePtr->export;
1005 SmiClass *smiGetParentClass(SmiClass *smiClassPtr)
1007 return (SmiClass*)(((Class *)smiClassPtr)->parentPtr);
1010 SmiClass *smiGetClass(SmiModule *smiModulePtr, char *class)
1013 if (!smiModulePtr) {
1020 for(cl = smiGetFirstClass(smiModulePtr);
1022 cl = smiGetNextClass(cl))
1023 if(!strncmp(cl->name,class,64))return cl;
1030 int smiGetClassLine(SmiClass *smiClassPtr)
1032 return ((Class *)smiClassPtr)->line;
1035 SmiAttribute *smiGetFirstAttribute(SmiClass *smiClassPtr)
1037 Attribute *attributePtr;
1043 attributePtr = ((Class *)smiClassPtr)->firstAttributePtr;
1045 return &attributePtr->export;
1048 SmiAttribute *smiGetNextAttribute( SmiAttribute *smiTypePtr)
1050 Attribute *attributePtr;
1056 attributePtr = ((Attribute *)smiTypePtr)->nextPtr;
1058 return &attributePtr->export;
1061 SmiAttribute *smiGetAttribute(SmiClass *smiClassPtr, char *attribute)
1063 Attribute *attributePtr;
1065 if (! smiClassPtr) {
1069 attributePtr = ((Class *)smiClassPtr)->firstAttributePtr;
1071 for (attributePtr = ((Class *)smiClassPtr)->firstAttributePtr;
1072 attributePtr; attributePtr = attributePtr->nextPtr)
1074 if (!strncmp(attributePtr->export.name, attribute,64)) {
1075 return &attributePtr->export;
1080 * attribute might belong to the parent so check parent if
1081 * attribute not found
1084 smiClassPtr = smiGetParentClass(smiClassPtr);
1085 attributePtr = (Attribute*)smiGetAttribute(smiClassPtr , attribute);
1087 return &attributePtr->export;
1090 SmiType *smiGetAttributeParentType(SmiAttribute *smiAttributePtr)
1092 Type *parentTypePtr;
1094 if (! smiAttributePtr) {
1098 parentTypePtr = ((Attribute*)smiAttributePtr)->parentTypePtr;
1100 return (parentTypePtr) ? &parentTypePtr->export : NULL;
1103 SmiClass *smiGetAttributeParentClass( SmiAttribute *smiAttributePtr)
1105 Class *parentClassPtr;
1107 if (! smiAttributePtr) {
1111 parentClassPtr = ((Attribute*)smiAttributePtr)->parentClassPtr;
1113 return parentClassPtr ? &parentClassPtr->export : NULL;
1116 SmiAttribute *smiGetFirstUniqueAttribute(SmiClass *smiClassPtr)
1120 if (! smiClassPtr) {
1124 classPtr = (Class*)smiClassPtr;
1126 if (! classPtr->uniqueList) {
1130 if (classPtr->uniqueList->ptr == classPtr) {
1131 return NULL; /* scalar class */
1134 return (SmiAttribute*)(classPtr->uniqueList->ptr);
1137 SmiAttribute *smiGetNextUniqueAttribute( SmiAttribute *smiTypePtr)
1146 classPtr = ((Attribute*)smiTypePtr)->classPtr;
1148 if (classPtr && classPtr->uniqueList) {
1149 for (listPtr=classPtr->uniqueList;listPtr; listPtr=listPtr->nextPtr) {
1150 if (&((Attribute*)(listPtr->ptr))->export == smiTypePtr) {
1151 if (listPtr->nextPtr) {
1152 return &((Attribute*)(listPtr->nextPtr->ptr))->export;
1162 int smiGetAttributeLine(SmiAttribute *smiAttributePtr)
1164 return ((Attribute *)smiAttributePtr)->line;
1169 int smiIsClassScalar(SmiClass *smiClassPtr)
1173 if (! smiClassPtr) {
1177 classPtr = (Class*)smiClassPtr;
1179 if (! classPtr->uniqueList) {
1183 return (classPtr->uniqueList->ptr == classPtr);
1188 SmiEvent *smiGetFirstEvent(SmiClass *smiClassPtr)
1192 if (! smiClassPtr) {
1196 eventPtr = ((Class *)smiClassPtr)->firstEventPtr;
1197 return &(eventPtr->export);
1202 SmiEvent *smiGetNextEvent(SmiEvent *smiEventPtr)
1206 if (! smiEventPtr) {
1210 eventPtr = ((Event *)smiEventPtr)->nextPtr;
1211 return &eventPtr->export;
1216 int smiGetEventLine(SmiEvent *smiEventPtr)
1218 return ((Event *)smiEventPtr)->line;
1223 SmiMacro *smiGetMacro(SmiModule *smiModulePtr, char *macro)
1225 Macro *macroPtr = NULL;
1226 Module *modulePtr = NULL;
1227 char *module2, *macro2;
1233 modulePtr = (Module *)smiModulePtr;
1235 getModulenameAndName(smiModulePtr ? smiModulePtr->name : NULL, macro,
1238 if (!modulePtr && module2 && strlen(module2)) {
1239 if (!(modulePtr = findModuleByName(module2))) {
1240 modulePtr = loadModule(module2, NULL);
1245 macroPtr = findMacroByModuleAndName(modulePtr, macro2);
1247 macroPtr = findMacroByName(macro2);
1252 return macroPtr ? ¯oPtr->export : NULL;
1257 SmiMacro *smiGetFirstMacro(SmiModule *smiModulePtr)
1259 if (!smiModulePtr) {
1263 return ((Module *)smiModulePtr)->firstMacroPtr ?
1264 &((Module *)smiModulePtr)->firstMacroPtr->export : NULL;
1269 SmiMacro *smiGetNextMacro(SmiMacro *smiMacroPtr)
1275 return ((Macro *)smiMacroPtr)->nextPtr ?
1276 &((Macro *)smiMacroPtr)->nextPtr->export : NULL;
1280 SmiModule *smiGetMacroModule(SmiMacro *smiMacroPtr)
1282 return &((Macro *)smiMacroPtr)->modulePtr->export;
1286 int smiGetMacroLine(SmiMacro *smiMacroPtr)
1288 return ((Macro *)smiMacroPtr)->line;
1292 SmiNode *smiGetNode(SmiModule *smiModulePtr, const char *node)
1294 Object *objectPtr = NULL;
1295 Module *modulePtr = NULL;
1297 char *module2, *node2, *p;
1298 unsigned int oidlen;
1305 modulePtr = (Module *)smiModulePtr;
1307 getModulenameAndName(smiModulePtr ? smiModulePtr->name : NULL, node,
1310 if (!modulePtr && module2 && strlen(module2)) {
1311 if (!(modulePtr = findModuleByName(module2))) {
1312 modulePtr = loadModule(module2, NULL);
1316 if (isdigit((int)node2[0])) {
1317 for (oidlen = 0, p = strtok(node2, ". "); p;
1318 oidlen++, p = strtok(NULL, ". ")) {
1319 oid[oidlen] = strtoul(p, NULL, 0);
1321 nodePtr = getNode(oidlen, oid);
1324 objectPtr = findObjectByModuleAndNode(modulePtr, nodePtr);
1326 objectPtr = findObjectByNode(nodePtr);
1330 p = strtok(node2, ". ");
1332 objectPtr = findObjectByModuleAndName(modulePtr, p);
1334 objectPtr = findObjectByName(p);
1340 return objectPtr ? &objectPtr->export : NULL;
1345 SmiNode *smiGetNodeByOID(unsigned int oidlen, SmiSubid oid[])
1354 nodePtr = getNode(oidlen, oid);
1360 objectPtr = findObjectByNode(nodePtr);
1362 return objectPtr ? &objectPtr->export : NULL;
1367 SmiNode *smiGetFirstNode(SmiModule *smiModulePtr, SmiNodekind nodekind)
1370 Node *nodePtr = NULL;
1373 if (!smiModulePtr) {
1377 modulePtr = (Module *)smiModulePtr;
1379 if (modulePtr && modulePtr->prefixNodePtr) {
1380 /* start at the common oid prefix of this module */
1381 nodePtr = modulePtr->prefixNodePtr;
1383 nodePtr = smiHandle->rootNodePtr->firstChildPtr;
1387 objectPtr = getNextChildObject(nodePtr, modulePtr, nodekind);
1390 return &objectPtr->export;
1392 if (nodePtr->firstChildPtr) {
1393 nodePtr = nodePtr->firstChildPtr;
1394 } else if (nodePtr->nextPtr) {
1395 nodePtr = nodePtr->nextPtr;
1397 for (nodePtr = nodePtr->parentPtr;
1398 nodePtr && (nodePtr->parentPtr) && (!nodePtr->nextPtr);
1399 nodePtr = nodePtr->parentPtr);
1400 if (nodePtr) nodePtr = nodePtr->nextPtr;
1409 SmiNode *smiGetNextNode(SmiNode *smiNodePtr, SmiNodekind nodekind)
1420 objectPtr = (Object *)smiNodePtr;
1421 nodePtr = objectPtr->nodePtr;
1422 modulePtr = objectPtr->modulePtr;
1433 if (nodePtr->firstChildPtr) {
1434 nodePtr = nodePtr->firstChildPtr;
1435 } else if (nodePtr->nextPtr) {
1436 nodePtr = nodePtr->nextPtr;
1438 for (nodePtr = nodePtr->parentPtr;
1439 (nodePtr->parentPtr) && (!nodePtr->nextPtr);
1440 nodePtr = nodePtr->parentPtr);
1441 nodePtr = nodePtr->nextPtr;
1442 /* did we move outside the common oid prefix of this module? */
1443 for (i = 0; i < modulePtr->prefixNodePtr->oidlen; i++)
1444 if ((!nodePtr) || (!nodePtr->oid) ||
1445 (nodePtr->oid[i] != modulePtr->prefixNodePtr->oid[i]))
1449 objectPtr = getNextChildObject(nodePtr, modulePtr, nodekind);
1452 return &objectPtr->export;
1461 SmiNode *smiGetParentNode(SmiNode *smiNodePtr)
1472 objectPtr = (Object *)smiNodePtr;
1473 nodePtr = objectPtr->nodePtr;
1474 modulePtr = objectPtr->modulePtr;
1480 if (nodePtr == smiHandle->rootNodePtr) {
1484 nodePtr = nodePtr->parentPtr;
1490 * First, try to find a definition in the same module.
1494 objectPtr = findObjectByModuleAndNode(modulePtr, nodePtr);
1498 * If found, check if it's imported. In case, get the original definition.
1501 importPtr = findImportByName(objectPtr->export.name,
1502 objectPtr->modulePtr);
1504 objectPtr = findObjectByModulenameAndNode(importPtr->export.module,
1512 * If not yet found, try to find any definition.
1515 objectPtr = findObjectByNode(nodePtr);
1517 if ((!objectPtr) && (nodePtr->parentPtr)) {
1518 /* an implicitly created node, e.g. gaga.0 in an object
1519 * definition with oid == gaga.0.1.
1521 objectPtr = addObject(SMI_UNKNOWN_LABEL,
1522 nodePtr->parentPtr, nodePtr->subid,
1524 objectPtr->nodePtr = nodePtr;
1525 objectPtr->modulePtr = modulePtr;
1529 return objectPtr ? &objectPtr->export : NULL;
1534 SmiNode *smiGetRelatedNode(SmiNode *smiNodePtr)
1540 return &((Object *)smiNodePtr)->relatedPtr->export;
1545 SmiNode *smiGetFirstChildNode(SmiNode *smiNodePtr)
1555 objectPtr = (Object *)smiNodePtr;
1556 nodePtr = objectPtr->nodePtr;
1557 modulePtr = objectPtr->modulePtr;
1563 nodePtr = nodePtr->firstChildPtr;
1569 objectPtr = findObjectByModuleAndNode(modulePtr, nodePtr);
1570 if (!objectPtr) objectPtr = findObjectByNode(nodePtr);
1572 return objectPtr ? &objectPtr->export : NULL;
1577 SmiNode *smiGetNextChildNode(SmiNode *smiNodePtr)
1587 objectPtr = (Object *)smiNodePtr;
1588 nodePtr = objectPtr->nodePtr;
1589 modulePtr = objectPtr->modulePtr;
1595 nodePtr = nodePtr->nextPtr;
1601 objectPtr = findObjectByModuleAndNode(modulePtr, nodePtr);
1602 if (!objectPtr) objectPtr = findObjectByNode(nodePtr);
1604 return objectPtr ? &objectPtr->export : NULL;
1609 SmiNode *smiGetModuleIdentityNode(SmiModule *smiModulePtr)
1611 if (!smiModulePtr) {
1615 return &((Module *)smiModulePtr)->objectPtr->export;
1620 SmiModule *smiGetNodeModule(SmiNode *smiNodePtr)
1622 return &((Object *)smiNodePtr)->modulePtr->export;
1627 SmiType *smiGetNodeType(SmiNode *smiNodePtr)
1631 typePtr = ((Object *)smiNodePtr)->typePtr;
1634 typePtr->export.basetype == SMI_BASETYPE_UNKNOWN) {
1638 return &typePtr->export;
1643 int smiGetNodeLine(SmiNode *smiNodePtr)
1645 return ((Object *)smiNodePtr)->line;
1650 SmiElement *smiGetFirstElement(SmiNode *smiNodePtr)
1658 listPtr = ((Object *)smiNodePtr)->listPtr;
1660 return (SmiElement *)listPtr;
1665 SmiElement *smiGetNextElement(SmiElement *smiElementPtr)
1669 if (!smiElementPtr) {
1673 listPtr = ((List *)smiElementPtr)->nextPtr;
1675 return (SmiElement *)listPtr;
1680 SmiNode *smiGetElementNode(SmiElement *smiElementPtr)
1682 if ((Object *)((List *)smiElementPtr)->ptr)
1683 return &((Object *)((List *)smiElementPtr)->ptr)->export;
1690 SmiOption *smiGetFirstOption(SmiNode *smiComplianceNodePtr)
1694 if (!smiComplianceNodePtr) {
1698 objectPtr = (Object *)smiComplianceNodePtr;
1700 if (!objectPtr->optionlistPtr) {
1704 if (objectPtr->export.nodekind != SMI_NODEKIND_COMPLIANCE) {
1708 return &((Option *)objectPtr->optionlistPtr->ptr)->export;
1713 SmiOption *smiGetNextOption(SmiOption *smiOptionPtr)
1717 if (!smiOptionPtr) {
1722 ((Option *)smiOptionPtr)->compliancePtr->optionlistPtr;
1724 listPtr = listPtr->nextPtr) {
1725 if ((Option *)(listPtr->ptr) == (Option *)smiOptionPtr) {
1726 if (listPtr->nextPtr) {
1727 return &((Option *)listPtr->nextPtr->ptr)->export;
1739 SmiNode *smiGetOptionNode(SmiOption *smiOptionPtr)
1741 return &((Option *)smiOptionPtr)->objectPtr->export;
1746 int smiGetOptionLine(SmiOption *smiOptionPtr)
1748 return ((Option *)smiOptionPtr)->line;
1753 SmiRefinement *smiGetFirstRefinement(SmiNode *smiComplianceNodePtr)
1757 if (!smiComplianceNodePtr) {
1761 objectPtr = (Object *)smiComplianceNodePtr;
1763 if (!objectPtr->refinementlistPtr) {
1767 if (objectPtr->export.nodekind != SMI_NODEKIND_COMPLIANCE) {
1771 return &((Refinement *)objectPtr->refinementlistPtr->ptr)->export;
1776 SmiRefinement *smiGetNextRefinement(SmiRefinement *smiRefinementPtr)
1780 if (!smiRefinementPtr) {
1785 ((Refinement *)smiRefinementPtr)->compliancePtr->refinementlistPtr;
1787 listPtr = listPtr->nextPtr) {
1788 if ((Refinement *)(listPtr->ptr) == (Refinement *)smiRefinementPtr) {
1789 if (listPtr->nextPtr) {
1790 return &((Refinement *)listPtr->nextPtr->ptr)->export;
1802 SmiNode *smiGetRefinementNode(SmiRefinement *smiRefinementPtr)
1804 return &((Refinement *)smiRefinementPtr)->objectPtr->export;
1809 SmiType *smiGetRefinementType(SmiRefinement *smiRefinementPtr)
1813 typePtr = ((Refinement *)smiRefinementPtr)->typePtr;
1816 typePtr->export.basetype == SMI_BASETYPE_UNKNOWN) {
1820 return &typePtr->export;
1825 SmiType *smiGetRefinementWriteType(SmiRefinement *smiRefinementPtr)
1829 typePtr = ((Refinement *)smiRefinementPtr)->writetypePtr;
1832 typePtr->export.basetype == SMI_BASETYPE_UNKNOWN) {
1836 return &typePtr->export;
1841 int smiGetRefinementLine(SmiRefinement *smiRefinementPtr)
1843 return ((Refinement *)smiRefinementPtr)->line;
1848 SmiElement *smiGetFirstUniquenessElement(SmiNode *smiNodePtr)
1856 listPtr = ((Object *)smiNodePtr)->uniquenessPtr;
1858 return (SmiElement *)listPtr;
1863 char *smiRenderOID(unsigned int oidlen, SmiSubid *oid, int flags)
1865 SmiNode *nodePtr = NULL;
1866 SmiModule *modulePtr = NULL;
1868 char *ss, *s = NULL;
1871 if (flags & SMI_RENDER_UNKNOWN) {
1872 smiAsprintf(&s, SMI_UNKNOWN_LABEL);
1879 if (flags & (SMI_RENDER_NAME | SMI_RENDER_QUALIFIED)) {
1881 for (len = oidlen; len; len--) {
1882 nodePtr = smiGetNodeByOID(len, oid);
1883 if (! nodePtr || nodePtr->name) break;
1885 if (nodePtr && nodePtr->name) {
1886 i = nodePtr->oidlen;
1887 if (flags & SMI_RENDER_QUALIFIED) {
1888 modulePtr = smiGetNodeModule(nodePtr);
1891 smiAsprintf(&s, "%s::%s",
1892 modulePtr->name, nodePtr->name);
1894 smiAsprintf(&s, "%s", nodePtr->name);
1899 for (; i < oidlen; i++) {
1901 smiAsprintf(&s, "%s%s%u", ss ? ss : "", i ? "." : "", oid[i]);
1905 if ((!s) && (flags & SMI_RENDER_UNKNOWN)) {
1906 smiAsprintf(&s, SMI_UNKNOWN_LABEL);
1914 char *smiRenderValue(SmiValue *smiValuePtr, SmiType *smiTypePtr, int flags)
1916 unsigned int i, pfx;
1917 int j, k, n, have_pfx;
1918 char *last_fmt, *fmt;
1928 if (flags & SMI_RENDER_UNKNOWN) {
1929 smiAsprintf(&s, SMI_UNKNOWN_LABEL);
1936 switch (smiValuePtr->basetype) {
1937 case SMI_BASETYPE_UNSIGNED32:
1938 if (!(flags & SMI_RENDER_FORMAT) ||
1939 !smiTypePtr || !smiTypePtr->format ||
1940 !strlen(smiTypePtr->format) || smiTypePtr->format[0] == 'd') {
1941 if (smiTypePtr->format && (strlen(smiTypePtr->format) >= 3) &&
1942 (smiTypePtr->format[1] == '-')) {
1943 i = atoi(&smiTypePtr->format[2]);
1946 smiAsprintf(&s, "%0*lu.",
1948 smiValuePtr->value.unsigned32);
1950 for (j = strlen(s) - 1; i > 0; i--, j--) {
1956 smiAsprintf(&s, "%lu", smiValuePtr->value.unsigned32);
1958 } else if (smiTypePtr->format[0] == 'x') {
1959 smiAsprintf(&s, "%lx", smiValuePtr->value.unsigned32);
1960 } else if (smiTypePtr->format[0] == 'o') {
1961 smiAsprintf(&s, "%lo", smiValuePtr->value.unsigned32);
1962 } else if (smiTypePtr->format[0] == 'b') {
1964 i > 0 && !(smiValuePtr->value.unsigned32 & (1 << i)); i--);
1965 s = smiMalloc(i + 1 + 1);
1967 for (j = 0; i >= 0; i--, j++) {
1968 s[j] = smiValuePtr->value.unsigned32 & (1<<i) ? '1' : '0';
1974 case SMI_BASETYPE_UNSIGNED64:
1975 if (!(flags & SMI_RENDER_FORMAT) ||
1976 !smiTypePtr || !smiTypePtr->format ||
1977 !strlen(smiTypePtr->format) || smiTypePtr->format[0] == 'd') {
1978 if (smiTypePtr->format && (strlen(smiTypePtr->format) >= 3) &&
1979 (smiTypePtr->format[1] == '-')) {
1980 i = atoi(&smiTypePtr->format[2]);
1983 sprintf(f, "%%0%s.", UINT64_FORMAT);
1987 smiValuePtr->value.unsigned64);
1989 for (j = strlen(s) - 1; i > 0; i--, j--) {
1995 smiAsprintf(&s, UINT64_FORMAT, smiValuePtr->value.unsigned64);
1997 } else if (smiTypePtr->format[0] == 'x') {
1998 strcpy(f, UINT64_FORMAT);
1999 f[strlen(f)-1] = 'x';
2000 smiAsprintf(&s, f, smiValuePtr->value.unsigned64);
2001 } else if (smiTypePtr->format[0] == 'o') {
2002 strcpy(f, UINT64_FORMAT);
2003 f[strlen(f)-1] = 'o';
2004 smiAsprintf(&s, f, smiValuePtr->value.unsigned64);
2005 } else if (smiTypePtr->format[0] == 'b') {
2007 i > 0 && !(smiValuePtr->value.unsigned64 & (1 << i)); i--);
2008 s = smiMalloc(i + 1 + 1);
2010 for (j = 0; i >= 0; i--, j++) {
2011 s[j] = smiValuePtr->value.unsigned64 & (1<<i) ? '1' : '0';
2017 case SMI_BASETYPE_INTEGER32:
2018 if (!(flags & SMI_RENDER_FORMAT) ||
2019 !smiTypePtr || !smiTypePtr->format ||
2020 !strlen(smiTypePtr->format) || smiTypePtr->format[0] == 'd') {
2021 if (smiTypePtr->format && (strlen(smiTypePtr->format) >= 3) &&
2022 (smiTypePtr->format[1] == '-')) {
2023 i = atoi(&smiTypePtr->format[2]);
2026 smiAsprintf(&s, "%0*ld.",
2027 1 + i + (smiValuePtr->value.integer32 < 0 ? 1 : 0),
2028 smiValuePtr->value.integer32);
2030 for (j = strlen(s) - 1; i > 0; i--, j--) {
2036 smiAsprintf(&s, "%ld", smiValuePtr->value.integer32);
2038 } else if (smiTypePtr->format[0] == 'x') {
2039 if (smiValuePtr->value.integer32 >= 0) {
2040 smiAsprintf(&s, "%lx", smiValuePtr->value.integer32);
2042 smiAsprintf(&s, "-%lx", - smiValuePtr->value.integer32);
2044 } else if (smiTypePtr->format[0] == 'o') {
2045 if (smiValuePtr->value.integer32 >= 0) {
2046 smiAsprintf(&s, "%lo", smiValuePtr->value.integer32);
2048 smiAsprintf(&s, "-%lo", - smiValuePtr->value.integer32);
2050 } else if (smiTypePtr->format[0] == 'b') {
2051 if (smiValuePtr->value.integer32 >= 0) {
2052 v32 = smiValuePtr->value.integer32;
2055 v32 = - smiValuePtr->value.integer32;
2059 i > 0 && !(v32 & (1 << i)); i--);
2060 s = smiMalloc(i + j + 1 + 1);
2063 for (; i >= 0; i--, j++) {
2064 s[j] = v32 & (1<<i) ? '1' : '0';
2070 case SMI_BASETYPE_INTEGER64:
2071 if (!(flags & SMI_RENDER_FORMAT) ||
2072 !smiTypePtr || !smiTypePtr->format ||
2073 !strlen(smiTypePtr->format) || smiTypePtr->format[0] == 'd') {
2074 if (smiTypePtr->format && (strlen(smiTypePtr->format) >= 3) &&
2075 (smiTypePtr->format[1] == '-')) {
2076 i = atoi(&smiTypePtr->format[2]);
2079 sprintf(f, "%%0%s.", INT64_FORMAT);
2082 1 + i + (smiValuePtr->value.integer64 < 0 ? 1 : 0),
2083 smiValuePtr->value.integer64);
2085 for (j = strlen(s) - 1; i > 0; i--, j--) {
2091 smiAsprintf(&s, INT64_FORMAT, smiValuePtr->value.integer64);
2093 } else if (smiTypePtr->format[0] == 'x') {
2094 if (smiValuePtr->value.integer64 >= 0) {
2095 strcpy(f, UINT64_FORMAT);
2096 f[strlen(f)-1] = 'x';
2097 smiAsprintf(&s, f, smiValuePtr->value.integer64);
2099 sprintf(f, "-%s", UINT64_FORMAT);
2100 f[strlen(f)-1] = 'x';
2101 smiAsprintf(&s, f, - smiValuePtr->value.integer64);
2103 } else if (smiTypePtr->format[0] == 'o') {
2104 if (smiValuePtr->value.integer64 >= 0) {
2105 strcpy(f, UINT64_FORMAT);
2106 sprintf(f, "-%s", UINT64_FORMAT);
2107 f[strlen(f)-1] = 'o';
2108 smiAsprintf(&s, f, smiValuePtr->value.integer64);
2110 smiAsprintf(&s, f, - smiValuePtr->value.integer64);
2112 } else if (smiTypePtr->format[0] == 'b') {
2113 if (smiValuePtr->value.integer64 >= 0) {
2114 v64 = smiValuePtr->value.integer64;
2117 v64 = - smiValuePtr->value.integer64;
2121 i > 0 && !(v64 & (1 << i)); i--);
2122 s = smiMalloc(i + j + 1 + 1);
2125 for (; i >= 0; i--, j++) {
2126 s[j] = v64 & (1<<i) ? '1' : '0';
2132 case SMI_BASETYPE_OBJECTIDENTIFIER:
2133 s = smiRenderOID(smiValuePtr->len, smiValuePtr->value.oid, flags);
2135 case SMI_BASETYPE_OCTETSTRING:
2136 if (!(flags & SMI_RENDER_FORMAT) ||
2137 (!smiTypePtr->format &&
2138 (smiTypePtr->name && strcmp( smiTypePtr->name, "IpAddress")) ) ) {
2139 for (i = 0; i < smiValuePtr->len; i++) {
2140 if (!isprint((int)smiValuePtr->value.ptr[i])) break;
2142 if ((i < smiValuePtr->len) ||
2143 !(flags & SMI_RENDER_PRINTABLE)) {
2144 smiAsprintf(&s, "");
2145 for (i=0; i < smiValuePtr->len; i++) {
2147 smiAsprintf(&s, "%s%02x", ss, smiValuePtr->value.ptr[i]);
2151 smiAsprintf(&s, "%s", smiValuePtr->value.ptr);
2155 smiAsprintf(&s, "");
2156 /* SNMPv2-SMI:IpAddress does not have a display hint.
2157 ==> let's use this one: "1d." if we have an IpAddress here */
2158 fmt = (smiTypePtr->name &&
2159 strcmp( smiTypePtr->name, "IpAddress" ) ) ?
2160 smiTypePtr->format : "1d.";
2161 while (*fmt && i < smiValuePtr->len) {
2163 have_pfx = pfx = 0; /* scan prefix: */
2164 while (*fmt && isdigit((int)*fmt)) {
2165 pfx = pfx * 10 + *fmt - '0', have_pfx = 1, fmt++;
2172 /* XXX UTF-8 not implemented, fall through to ASCII (a) */
2174 n = (pfx < (smiValuePtr->len - i)) ?
2175 pfx : smiValuePtr->len - i;
2176 for (k = 0; k < n; k++) {
2177 if (! isascii((int) smiValuePtr->value.ptr[i+k])) {
2179 if (flags & SMI_RENDER_UNKNOWN) {
2180 smiAsprintf(&s, SMI_UNKNOWN_LABEL);
2187 smiAsprintf(&s, "%s%c", ss, smiValuePtr->value.ptr[i+k]);
2196 /* XXX: limited to no more than
2197 sizeof(SmiUnsigned64) octets */
2200 while (pfx > 0 && i < smiValuePtr->len) {
2202 ((unsigned char)smiValuePtr->value.ptr[i]);
2209 sprintf(f, "%%s%s", UINT64_FORMAT);
2210 smiAsprintf(&s, f, ss, vv);
2215 sprintf(f, "%%s%s", UINT64_FORMAT);
2216 f[strlen(f)-1] = 'o';
2217 smiAsprintf(&s, f, ss, vv);
2222 sprintf(f, "%%s%%0%s", UINT64_FORMAT);
2224 f[strlen(f)-1] = 'x';
2225 smiAsprintf(&s, f, ss, xlen, vv);
2230 if (k > sizeof(SmiUnsigned64) * 8 - 1)
2231 k = sizeof(SmiUnsigned64) * 8 - 1;
2232 for (j = 0; k >= 0; k--, j++) {
2234 smiAsprintf(&s, "%s%c",
2235 ss, vv & (1 << k) ? '1' : '0');
2243 if (flags & SMI_RENDER_UNKNOWN) {
2244 smiAsprintf(&s, SMI_UNKNOWN_LABEL);
2253 * Check for a separator and repeat with last format if
2254 * data is still available.
2256 if (*fmt && ! isdigit((int) *fmt) && *fmt != '*') {
2257 if (i < smiValuePtr->len) {
2259 smiAsprintf(&s, "%s%c", ss, fmt[0]);
2265 if (! *fmt && (i < smiValuePtr->len)) {
2271 case SMI_BASETYPE_ENUM:
2272 if ((flags & SMI_RENDER_NAME) && (smiTypePtr)) {
2273 for (nn = smiGetFirstNamedNumber(smiTypePtr); nn;
2274 nn = smiGetNextNamedNumber(nn)) {
2275 if (nn->value.value.integer32 == smiValuePtr->value.integer32)
2279 if (flags & SMI_RENDER_NUMERIC) {
2280 smiAsprintf(&s, "%s(%ld)",
2281 nn->name, nn->value.value.integer32);
2283 smiAsprintf(&s, "%s", nn->name);
2286 smiAsprintf(&s, "%ld", smiValuePtr->value.integer32);
2289 smiAsprintf(&s, "%ld", smiValuePtr->value.integer32);
2292 case SMI_BASETYPE_BITS:
2293 smiAsprintf(&s, "");
2294 for (i = 0, nn = NULL; i < smiValuePtr->len * 8; i++) {
2295 if (smiValuePtr->value.ptr[i/8] & (1 << (7-(i%8)))) {
2296 if ((flags & SMI_RENDER_NAME) && (smiTypePtr)) {
2297 for (nn = smiGetFirstNamedNumber(smiTypePtr); nn;
2298 nn = smiGetNextNamedNumber(nn)) {
2299 if (nn->value.value.unsigned32 == i)
2304 if ((flags & SMI_RENDER_NAME) &&
2305 (flags & SMI_RENDER_NUMERIC) && nn) {
2306 smiAsprintf(&s, "%s%s%s(%d)",
2307 ss, strlen(ss) ? " " : "", nn->name, i);
2309 smiAsprintf(&s, "%s%s%s",
2310 ss, strlen(ss) ? " " : "", nn->name);
2312 smiAsprintf(&s, "%s%s%d",
2313 ss, strlen(ss) ? " " : "", i);
2319 case SMI_BASETYPE_FLOAT32:
2320 case SMI_BASETYPE_FLOAT64:
2321 case SMI_BASETYPE_FLOAT128:
2322 case SMI_BASETYPE_UNKNOWN:
2324 if (flags & SMI_RENDER_UNKNOWN) {
2325 smiAsprintf(&s, SMI_UNKNOWN_LABEL);
2335 char *smiRenderNode(SmiNode *smiNodePtr, int flags)
2338 SmiModule *modulePtr;
2340 if ((!smiNodePtr) || (smiNodePtr->name == NULL)) {
2341 if (flags & SMI_RENDER_UNKNOWN) {
2342 smiAsprintf(&s, SMI_UNKNOWN_LABEL);
2347 modulePtr = smiGetNodeModule(smiNodePtr);
2348 if ((!(flags & SMI_RENDER_QUALIFIED)) ||
2350 (!strlen(modulePtr->name))) {
2351 smiAsprintf(&s, "%s", smiNodePtr->name);
2353 smiAsprintf(&s, "%s::%s", modulePtr->name, smiNodePtr->name);
2361 char *smiRenderType(SmiType *smiTypePtr, int flags)
2364 SmiModule *modulePtr;
2366 if ((!smiTypePtr) || (smiTypePtr->name == NULL)) {
2367 if (flags & SMI_RENDER_UNKNOWN) {
2368 smiAsprintf(&s, SMI_UNKNOWN_LABEL);
2373 modulePtr = smiGetTypeModule(smiTypePtr);
2374 if ((!(flags & SMI_RENDER_QUALIFIED)) ||
2376 (!strlen(modulePtr->name))) {
2377 smiAsprintf(&s, "%s", smiTypePtr->name);
2379 smiAsprintf(&s, "%s::%s", modulePtr->name, smiTypePtr->name);
2387 unsigned int smiGetMinSize(SmiType *smiType)
2390 SmiType *parentType;
2391 unsigned int min = 65535, size;
2393 switch (smiType->basetype) {
2394 case SMI_BASETYPE_BITS:
2396 case SMI_BASETYPE_OCTETSTRING:
2397 case SMI_BASETYPE_OBJECTIDENTIFIER:
2404 for (smiRange = smiGetFirstRange(smiType);
2405 smiRange ; smiRange = smiGetNextRange(smiRange)) {
2406 if (smiRange->minValue.value.unsigned32 < min) {
2407 min = smiRange->minValue.value.unsigned32;
2410 if (min < 65535 && min > size) {
2414 parentType = smiGetParentType(smiType);
2416 unsigned int psize = smiGetMinSize(parentType);
2427 unsigned int smiGetMaxSize(SmiType *smiType)
2430 SmiType *parentType;
2432 unsigned int max = 0, size;
2434 switch (smiType->basetype) {
2435 case SMI_BASETYPE_BITS:
2436 case SMI_BASETYPE_OCTETSTRING:
2439 case SMI_BASETYPE_OBJECTIDENTIFIER:
2446 if (smiType->basetype == SMI_BASETYPE_BITS) {
2447 for (nn = smiGetFirstNamedNumber(smiType);
2449 nn = smiGetNextNamedNumber(nn)) {
2450 if (nn->value.value.unsigned32 > max) {
2451 max = nn->value.value.unsigned32;
2454 size = (max / 8) + 1;
2458 for (smiRange = smiGetFirstRange(smiType);
2459 smiRange ; smiRange = smiGetNextRange(smiRange)) {
2460 if (smiRange->maxValue.value.unsigned32 > max) {
2461 max = smiRange->maxValue.value.unsigned32;
2464 if (max > 0 && max < size) {
2468 parentType = smiGetParentType(smiType);
2470 unsigned int psize = smiGetMaxSize(parentType);
2481 int smiUnpack(SmiNode *row, SmiSubid *oid, unsigned int oidlen,
2482 SmiValue **vals, int *valslen)
2484 SmiNode *indexNode = NULL;
2485 SmiElement *smiElement;
2490 if (!vals || !valslen || !row || !oid) {
2494 switch (row->indexkind) {
2495 case SMI_INDEX_INDEX:
2496 case SMI_INDEX_REORDER:
2499 case SMI_INDEX_EXPAND: /* TODO: we have to do more work here! */
2502 case SMI_INDEX_AUGMENT:
2503 case SMI_INDEX_SPARSE:
2504 indexNode = smiGetRelatedNode(row);
2506 case SMI_INDEX_UNKNOWN:
2512 for (smiElement = smiGetFirstElement(indexNode);
2513 smiElement; smiElement = smiGetNextElement(smiElement)) {
2514 iNode = smiGetElementNode(smiElement);
2516 iType = smiGetNodeType(iNode);
2525 *vals = smiMalloc(*valslen * sizeof(SmiValue));
2527 for (smiElement = smiGetFirstElement(indexNode), i = 0, j = 0;
2528 smiElement; smiElement = smiGetNextElement(smiElement), i++) {
2529 iNode = smiGetElementNode(smiElement);
2530 last = (smiGetNextElement(smiElement) == NULL);
2531 iType = smiGetNodeType(iNode);
2532 fprintf(stderr, "** %s (%s)\n", iNode->name, iType->name);
2533 (*vals)[i].basetype = iType->basetype;
2534 switch (iType->basetype) {
2535 case SMI_BASETYPE_ENUM:
2536 case SMI_BASETYPE_INTEGER32:
2537 (*vals)[i].value.integer32 = oid[j]; j++;
2539 case SMI_BASETYPE_UNSIGNED32:
2540 (*vals)[i].value.unsigned32 = oid[j]; j++;
2542 case SMI_BASETYPE_OCTETSTRING:
2543 /* need to know whether implied/fixed length or not */
2545 case SMI_BASETYPE_OBJECTIDENTIFIER:
2546 /* need to know whether implied/fixed length or not */
2558 int smiAsprintf(char **strp, const char *format, ...)
2563 va_start(ap, format);
2564 rc = vasprintf(strp, format, ap);
2567 smiPrintError(NULL, ERR_OUT_OF_MEMORY);
2574 int smiVasprintf(char **strp, const char *format, va_list ap)
2578 rc = vasprintf(strp, format, ap);
2580 smiPrintError(NULL, ERR_OUT_OF_MEMORY);
2586 int smiGetMinMaxRange(SmiType *smiType, SmiValue *min, SmiValue *max)
2588 SmiBasetype basetype = SMI_BASETYPE_UNKNOWN;
2591 min->basetype = max->basetype = SMI_BASETYPE_UNKNOWN;
2592 min->len = max->len = 0;
2594 range = smiGetFirstRange(smiType);
2599 basetype = range->minValue.basetype;
2600 min->basetype = max->basetype = basetype;
2603 case SMI_BASETYPE_INTEGER32:
2604 min->value.integer32 = SMI_BASETYPE_INTEGER32_MAX;
2605 max->value.integer32 = SMI_BASETYPE_INTEGER32_MIN;
2607 case SMI_BASETYPE_INTEGER64:
2608 min->value.integer64 = SMI_BASETYPE_INTEGER64_MAX;
2609 max->value.integer64 = SMI_BASETYPE_INTEGER64_MIN;
2611 case SMI_BASETYPE_UNSIGNED32:
2612 min->value.unsigned32 = SMI_BASETYPE_UNSIGNED32_MAX;
2613 max->value.unsigned32 = SMI_BASETYPE_UNSIGNED32_MIN;
2615 case SMI_BASETYPE_UNSIGNED64:
2616 min->value.unsigned64 = SMI_BASETYPE_UNSIGNED64_MAX;
2617 max->value.unsigned64 = SMI_BASETYPE_UNSIGNED32_MIN;
2620 fprintf(stderr, "smidump: unexpected basetype %d\n", basetype);
2624 for (range = smiGetFirstRange(smiType);
2626 range = smiGetNextRange(range)) {
2628 case SMI_BASETYPE_INTEGER32:
2629 if (range->minValue.value.integer32 < min->value.integer32) {
2630 min->value.integer32 = range->minValue.value.integer32;
2632 if (range->maxValue.value.integer32 > max->value.integer32) {
2633 max->value.integer32 = range->maxValue.value.integer32;
2636 case SMI_BASETYPE_INTEGER64:
2637 if (range->minValue.value.integer64 < min->value.integer64) {
2638 min->value.integer64 = range->minValue.value.integer64;
2640 if (range->maxValue.value.integer64 > max->value.integer64) {
2641 max->value.integer64 = range->maxValue.value.integer64;
2644 case SMI_BASETYPE_UNSIGNED32:
2645 if (range->minValue.value.unsigned32 < min->value.unsigned32) {
2646 min->value.unsigned32 = range->minValue.value.unsigned32;
2648 if (range->maxValue.value.unsigned32 > max->value.unsigned32) {
2649 max->value.unsigned32 = range->maxValue.value.unsigned32;
2652 case SMI_BASETYPE_UNSIGNED64:
2653 if (range->minValue.value.unsigned64 < min->value.unsigned64) {
2654 min->value.unsigned64 = range->minValue.value.unsigned64;
2656 if (range->maxValue.value.unsigned64 > max->value.unsigned64) {
2657 max->value.unsigned64 = range->maxValue.value.unsigned64;
2661 fprintf(stderr, "smidump: unexpected basetype %d\n", basetype);