1 /*
2 * smi.c --
3 *
4 * Interface Implementation of libsmi.
5 *
6 * Copyright (c) 1999 Frank Strauss, Technical University of Braunschweig.
7 *
8 * See the file "COPYING" for information on usage and redistribution
9 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10 *
11 * @(#) $Id: smi.c 8071 2008-04-17 11:14:46Z schoenw $
12 */
13
14 #include <config.h>
15
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <ctype.h>
20 #include <sys/types.h>
21 #ifdef HAVE_UNISTD_H
22 #include <unistd.h>
23 #endif
24 #ifdef HAVE_PWD_H
25 #include <pwd.h>
26 #endif
27
28 #include "smi.h"
29 #include "data.h"
30 #include "error.h"
31 #include "util.h"
32 #include "snprintf.h"
33
34 #ifdef BACKEND_SMI
35 #include "scanner-smi.h"
36 #include "parser-smi.h"
37 #endif
38
39 #ifdef BACKEND_SMING
40 #include "scanner-sming.h"
41 #include "parser-sming.h"
42 #endif
43
44 #ifdef HAVE_DMALLOC_H
45 #include <dmalloc.h>
46 #endif
47
48
49
50 #ifndef MIN
51 #define MIN(a, b) ((a) < (b) ? (a) : (b))
52 #define MAX(a, b) ((a) < (b) ? (b) : (a))
53 #endif
54
55
56
57 const char *smi_library_version = SMI_LIBRARY_VERSION;
58 const char *smi_version_string = SMI_VERSION_STRING;
59
60 Handle *smiHandle = NULL;
61
62
63
64 /*
65 * Internal functions.
66 */
67
getModulenameAndName(const char * arg1,const char * arg2,char ** module,char ** name)68 static void getModulenameAndName(const char *arg1, const char *arg2,
69 char **module, char **name)
70 {
71 char *p;
72 int l;
73
74 if ((!arg1) && (!arg2)) {
75 *module = NULL;
76 *name = NULL;
77 } else if (!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);
94 } else {
95 *name = smiStrdup(arg1);
96 *module = smiStrdup("");
97 }
98 } else {
99 *name = smiStrdup(arg1);
100 *module = smiStrdup("");
101 }
102 } else if (!arg1) {
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);
119 } else {
120 *name = smiStrdup(arg2);
121 *module = smiStrdup("");
122 }
123 } else {
124 *name = smiStrdup(arg2);
125 *module = smiStrdup("");
126 }
127 } else {
128 *module = smiStrdup(arg1);
129 *name = smiStrdup(arg2);
130 }
131 }
132
133
134
getNode(unsigned int oidlen,SmiSubid oid[])135 static Node *getNode(unsigned int oidlen, SmiSubid oid[])
136 {
137 Node *nodePtr, *parentPtr;
138 unsigned int i;
139
140 for(nodePtr = smiHandle->rootNodePtr, i=0; i < oidlen; i++) {
141 parentPtr = nodePtr;
142 nodePtr = findNodeByParentAndSubid(parentPtr, oid[i]);
143 if (!nodePtr) {
144 return parentPtr;
145 }
146 }
147
148 return nodePtr;
149 }
150
151
152
getNextChildObject(Node * startNodePtr,Module * modulePtr,SmiNodekind nodekind)153 static Object *getNextChildObject(Node *startNodePtr, Module *modulePtr,
154 SmiNodekind nodekind)
155 {
156 Node *nodePtr;
157 Object *objectPtr = NULL;
158
159 if (!startNodePtr || !modulePtr)
160 return NULL;
161
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))) {
168 break;
169 }
170 }
171 if (objectPtr) break;
172 objectPtr = getNextChildObject(nodePtr->firstChildPtr,
173 modulePtr, nodekind);
174 if (objectPtr) break;
175 }
176
177 return objectPtr;
178 }
179
180
181
182 /*
183 * Interface Functions.
184 */
185
smiInit(const char * tag)186 int smiInit(const char *tag)
187 {
188 char *p, *pp, *tag2;
189 #ifdef HAVE_PWD_H
190 struct passwd *pw;
191 #endif
192
193 smiHandle = findHandleByName(tag);
194 if (smiHandle) {
195 return 0;
196 }
197 smiHandle = addHandle(tag);
198
199 smiDepth = 0;
200
201 smiHandle->errorLevel = DEFAULT_ERRORLEVEL;
202 smiHandle->errorHandler = smiErrorHandler;
203 #if !defined(_MSC_VER)
204 smiHandle->cache = NULL;
205 smiHandle->cacheProg = NULL;
206 #endif
207
208 if (smiInitData()) {
209 return -1;
210 }
211
212 /*
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)
218 */
219
220 /* 1. set to builtin DEFAULT_SMIPATH */
221 smiHandle->path = smiStrdup(DEFAULT_SMIPATH);
222
223 tag2 = smiStrdup(tag);
224 if (tag2) tag2 = strtok(tag2, ":");
225 if (tag2) {
226 /* 2. read global config file if present (append/prepend/replace) */
227 smiReadConfig(DEFAULT_GLOBALCONFIG, tag2);
228 #ifdef HAVE_PWD_H
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);
235 smiFree(p);
236 }
237 #endif
238 }
239 smiFree(tag2);
240
241 /* 4. evaluate SMIPATH env-var if set (append/prepend/replace) */
242 p = getenv("SMIPATH");
243 if (p) {
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;
252 } else {
253 smiHandle->path = smiStrdup(p);
254 }
255 }
256
257 if (!smiHandle->path) {
258 return -1;
259 }
260
261 return 0;
262 }
263
264
265
smiExit()266 void smiExit()
267 {
268 if (!smiHandle)
269 return;
270
271 smiFreeData();
272
273 smiFree(smiHandle->path);
274 #if !defined(_MSC_VER)
275 smiFree(smiHandle->cache);
276 smiFree(smiHandle->cacheProg);
277 #endif
278
279 removeHandle(smiHandle);
280
281 smiHandle = NULL;
282 return;
283 }
284
285
286
smiGetPath()287 char *smiGetPath()
288 {
289 if (smiHandle->path) {
290 return smiStrdup(smiHandle->path);
291 } else {
292 return NULL;
293 }
294 }
295
296
297
smiSetPath(const char * s)298 int smiSetPath(const char *s)
299 {
300 char *s2;
301
302 if (!smiHandle) smiInit(NULL);
303
304 if (!s) {
305 smiFree(smiHandle->path);
306 smiHandle->path = NULL;
307 return 0;
308 }
309
310 s2 = smiStrdup(s);
311 if (s2) {
312 smiFree(smiHandle->path);
313 smiHandle->path = s2;
314 return 0;
315 } else {
316 return -1;
317 }
318
319 }
320
321
322
smiSetSeverity(char * pattern,int severity)323 void smiSetSeverity(char *pattern, int severity)
324 {
325 smiSetErrorSeverity(pattern, severity);
326 }
327
328
329
smiReadConfig(const char * filename,const char * tag)330 int smiReadConfig(const char *filename, const char *tag)
331 {
332 FILE *file;
333 char buf[201];
334 char *cmd, *arg, *s;
335
336 file = fopen(filename, "r");
337 if (file) {
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");
342 if (!cmd) continue;
343 if (cmd[0] == '#') continue;
344 if (cmd[strlen(cmd)-1] == ':') {
345 if (!tag) continue;
346 cmd[strlen(cmd)-1] = 0;
347 if (strcmp(cmd, tag)) continue;
348 cmd = strtok(NULL, " \t\n\r");
349 }
350 arg = strtok(NULL, " \t\n\r");
351 if (!strcmp(cmd, "load")) {
352 smiLoadModule(arg);
353 } else if (!strcmp(cmd, "path")) {
354 if (arg) {
355 if (arg[0] == PATH_SEPARATOR) {
356 smiAsprintf(&s, "%s%s", smiHandle->path, arg);
357 smiFree(smiHandle->path);
358 smiHandle->path = s;
359 } else if (arg[strlen(arg)-1] == PATH_SEPARATOR) {
360 smiAsprintf(&s, "%s%s", arg, smiHandle->path);
361 smiFree(smiHandle->path);
362 smiHandle->path = s;
363 } else {
364 smiHandle->path = smiStrdup(arg);
365 }
366 }
367 } else if (!strcmp(cmd, "cache")) {
368 #if !defined(_MSC_VER)
369 smiFree(smiHandle->cache);
370 smiFree(smiHandle->cacheProg);
371 #endif
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);
377 #else
378 smiPrintError(NULL, ERR_CACHE_CONFIG_NOT_SUPPORTED,
379 filename);
380 #endif
381 }
382 } else if (!strcmp(cmd, "level")) {
383 smiSetErrorLevel(atoi(arg));
384 } else if (!strcmp(cmd, "hide")) {
385 smiSetSeverity(arg, 9);
386 } else {
387 smiPrintError(NULL, ERR_UNKNOWN_CONFIG_CMD, cmd, filename);
388 }
389 }
390 fclose(file);
391 return 0;
392 }
393 return -1;
394 }
395
396
397
smiIsLoaded(const char * module)398 int smiIsLoaded(const char *module)
399 {
400 if (!module)
401 return 0;
402
403 return isInView(module);
404 }
405
406
407
smiLoadModule(const char * module)408 char *smiLoadModule(const char *module)
409 {
410 Module *modulePtr;
411
412 if (!smiHandle) smiInit(NULL);
413
414 if (smiIsPath(module)) {
415
416 modulePtr = loadModule(module, NULL);
417
418 if (modulePtr) {
419 if (!isInView(modulePtr->export.name)) {
420 addView(modulePtr->export.name);
421 }
422 return modulePtr->export.name;
423 } else {
424 return NULL;
425 }
426
427 } else {
428
429 if ((modulePtr = findModuleByName(module))) {
430 /* already loaded. */
431 if (!isInView(module)) {
432 addView(module);
433 }
434 return modulePtr->export.name;
435 } else {
436 if ((modulePtr = loadModule(module, NULL))) {
437 if (!isInView(module)) {
438 addView(module);
439 }
440 return modulePtr->export.name;
441 } else {
442 return NULL;
443 }
444 }
445 }
446 }
447
448
449
smiSetErrorLevel(int level)450 void smiSetErrorLevel(int level)
451 {
452 if (!smiHandle) smiInit(NULL);
453
454 smiHandle->errorLevel = level;
455 }
456
457
458
smiSetFlags(int userflags)459 void smiSetFlags(int userflags)
460 {
461 if (!smiHandle) smiInit(NULL);
462
463 smiHandle->flags = (smiHandle->flags & ~SMI_FLAG_MASK) | userflags;
464 }
465
466
467
smiGetFlags()468 int smiGetFlags()
469 {
470 if (!smiHandle) smiInit(NULL);
471
472 return smiHandle->flags & SMI_FLAG_MASK;
473 }
474
475
476
smiGetModule(const char * module)477 SmiModule *smiGetModule(const char *module)
478 {
479 Module *modulePtr;
480
481 if (!module) {
482 return NULL;
483 }
484
485 modulePtr = findModuleByName(module);
486
487 if (!modulePtr) {
488 modulePtr = loadModule(module, NULL);
489 }
490
491 return &modulePtr->export;
492 }
493
494
495
smiGetFirstModule()496 SmiModule *smiGetFirstModule()
497 {
498 Module *modulePtr;
499
500 for (modulePtr = smiHandle->firstModulePtr;
501 modulePtr && modulePtr->export.name &&
502 (strlen(modulePtr->export.name) == 0);
503 modulePtr = modulePtr->nextPtr);
504
505 return &modulePtr->export;
506 }
507
508
509
smiGetNextModule(SmiModule * smiModulePtr)510 SmiModule *smiGetNextModule(SmiModule *smiModulePtr)
511 {
512 Module *modulePtr;
513
514 if (!smiModulePtr) {
515 return NULL;
516 }
517
518
519 for (modulePtr = ((Module *)smiModulePtr)->nextPtr;
520 modulePtr && modulePtr->export.name &&
521 (strlen(modulePtr->export.name) == 0);
522 modulePtr = modulePtr->nextPtr);
523
524 return &modulePtr->export;
525 }
526
527
528
smiGetFirstImport(SmiModule * smiModulePtr)529 SmiImport *smiGetFirstImport(SmiModule *smiModulePtr)
530 {
531 if (!smiModulePtr) {
532 return NULL;
533 }
534
535 return &((Module *)smiModulePtr)->firstImportPtr->export;
536 }
537
538
539
smiGetNextImport(SmiImport * smiImportPtr)540 SmiImport *smiGetNextImport(SmiImport *smiImportPtr)
541 {
542 if (!smiImportPtr) {
543 return NULL;
544 }
545
546 return &((Import *)smiImportPtr)->nextPtr->export;
547 }
548
549
550
smiIsImported(SmiModule * smiModulePtr,SmiModule * importedModulePtr,char * importedName)551 int smiIsImported(SmiModule *smiModulePtr,
552 SmiModule *importedModulePtr,
553 char *importedName)
554 {
555 Import *importPtr;
556 Module *modulePtr;
557 char *importedModule;
558
559 if ((!smiModulePtr) || (!importedName)) {
560 return 0;
561 }
562
563 modulePtr = (Module *)smiModulePtr;
564
565 if (importedModulePtr) {
566 importedModule = importedModulePtr->name;
567 } else {
568 importedModule = NULL;
569 }
570
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)))) {
576 return 1;
577 }
578 }
579
580 return 0;
581 }
582
583
584
smiGetFirstRevision(SmiModule * smiModulePtr)585 SmiRevision *smiGetFirstRevision(SmiModule *smiModulePtr)
586 {
587 if (!smiModulePtr) {
588 return NULL;
589 }
590
591 return &((Module *)smiModulePtr)->firstRevisionPtr->export;
592 }
593
594
595
smiGetNextRevision(SmiRevision * smiRevisionPtr)596 SmiRevision *smiGetNextRevision(SmiRevision *smiRevisionPtr)
597 {
598 if (!smiRevisionPtr) {
599 return NULL;
600 }
601
602 return &((Revision *)smiRevisionPtr)->nextPtr->export;
603 }
604
605
606
smiGetRevisionLine(SmiRevision * smiRevisionPtr)607 int smiGetRevisionLine(SmiRevision *smiRevisionPtr)
608 {
609 return ((Revision *)smiRevisionPtr)->line;
610 }
611
612
613
smiGetType(SmiModule * smiModulePtr,char * type)614 SmiType *smiGetType(SmiModule *smiModulePtr, char *type)
615 {
616 Type *typePtr = NULL;
617 Module *modulePtr = NULL;
618 char *module2, *type2;
619
620 if (!type) {
621 return NULL;
622 }
623
624 modulePtr = (Module *)smiModulePtr;
625
626 getModulenameAndName(smiModulePtr ? smiModulePtr->name : NULL, type,
627 &module2, &type2);
628
629 if (!modulePtr && module2 && strlen(module2)) {
630 if (!(modulePtr = findModuleByName(module2))) {
631 modulePtr = loadModule(module2, NULL);
632 }
633 }
634
635 if (modulePtr) {
636 typePtr = findTypeByModuleAndName(modulePtr, type2);
637 } else {
638 typePtr = findTypeByName(type2);
639 }
640
641 smiFree(module2);
642 smiFree(type2);
643
644 if (!typePtr ||
645 typePtr->export.basetype == SMI_BASETYPE_UNKNOWN) {
646 return NULL;
647 }
648
649 return &typePtr->export;
650 }
651
652
653
smiGetFirstType(SmiModule * smiModulePtr)654 SmiType *smiGetFirstType(SmiModule *smiModulePtr)
655 {
656 Type *typePtr;
657
658 if (!smiModulePtr) {
659 return NULL;
660 }
661
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) {
667 break;
668 }
669 }
670
671 return &typePtr->export;
672 }
673
674
675
smiGetNextType(SmiType * smiTypePtr)676 SmiType *smiGetNextType(SmiType *smiTypePtr)
677 {
678 Type *typePtr;
679
680 if (!smiTypePtr) {
681 return NULL;
682 }
683
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) {
689 break;
690 }
691 }
692
693 return &typePtr->export;
694 }
695
696
smiGetParentType(SmiType * smiTypePtr)697 SmiType *smiGetParentType(SmiType *smiTypePtr)
698 {
699 Type *typePtr;
700
701 if (!smiTypePtr) {
702 return NULL;
703 }
704
705 typePtr = ((Type *)smiTypePtr)->parentPtr;
706
707 if (!typePtr ||
708 typePtr->export.basetype == SMI_BASETYPE_UNKNOWN) {
709 return NULL;
710 }
711
712 return &typePtr->export;
713 }
714
715
716
smiGetTypeModule(SmiType * smiTypePtr)717 SmiModule *smiGetTypeModule(SmiType *smiTypePtr)
718 {
719 return &((Type *)smiTypePtr)->modulePtr->export;
720 }
721
smiGetTypeLine(SmiType * smiTypePtr)722 int smiGetTypeLine(SmiType *smiTypePtr)
723 {
724 return ((Type *)smiTypePtr)->line;
725 }
726
727
728
smiGetFirstNamedNumber(SmiType * smiTypePtr)729 SmiNamedNumber *smiGetFirstNamedNumber(SmiType *smiTypePtr)
730 {
731 Type *typePtr;
732
733 typePtr = (Type *)smiTypePtr;
734
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))) {
739 return NULL;
740 }
741
742 return &((NamedNumber *)typePtr->listPtr->ptr)->export;
743 }
744
745
746
smiGetNextNamedNumber(SmiNamedNumber * smiNamedNumberPtr)747 SmiNamedNumber *smiGetNextNamedNumber(SmiNamedNumber *smiNamedNumberPtr)
748 {
749 Type *typePtr;
750 List *listPtr;
751
752 if (!smiNamedNumberPtr) {
753 return NULL;
754 }
755
756 typePtr = ((NamedNumber *)smiNamedNumberPtr)->typePtr;
757
758
759 if ((!typePtr) || (!typePtr->listPtr) ||
760 ((typePtr->export.basetype != SMI_BASETYPE_ENUM) &&
761 (typePtr->export.basetype != SMI_BASETYPE_BITS))) {
762 return NULL;
763 }
764
765 for (listPtr = typePtr->listPtr; listPtr; listPtr = listPtr->nextPtr) {
766 if (((NamedNumber *)(listPtr->ptr))->export.name ==
767 smiNamedNumberPtr->name)
768 break;
769 }
770
771 if ((!listPtr) || (!listPtr->nextPtr)) {
772 return NULL;
773 }
774
775 return &((NamedNumber *)listPtr->nextPtr->ptr)->export;
776 }
777
smiGetAttributeFirstNamedNumber(SmiAttribute * smiAttributePtr)778 SmiNamedNumber *smiGetAttributeFirstNamedNumber(SmiAttribute *smiAttributePtr)
779 {
780 Attribute *attributePtr;
781
782 attributePtr = (Attribute *)smiAttributePtr;
783
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))) {
788 return NULL;
789 }
790
791 return &((NamedNumber *)attributePtr->listPtr->ptr)->export;
792 }
793
794
795
smiGetAttributeNextNamedNumber(SmiNamedNumber * smiNamedNumberPtr)796 SmiNamedNumber *smiGetAttributeNextNamedNumber(SmiNamedNumber *smiNamedNumberPtr)
797 {
798 Attribute *attributePtr;
799 List *listPtr;
800
801 if (!smiNamedNumberPtr) {
802 return NULL;
803 }
804
805 attributePtr = (Attribute*)(((NamedNumber *)smiNamedNumberPtr)->typePtr);
806
807
808 if ((!attributePtr) || (!attributePtr->listPtr) ||
809 ((attributePtr->export.basetype != SMI_BASETYPE_ENUM) &&
810 (attributePtr->export.basetype != SMI_BASETYPE_BITS))) {
811 return NULL;
812 }
813
814 for (listPtr = attributePtr->listPtr; listPtr; listPtr = listPtr->nextPtr) {
815 if (((NamedNumber *)(listPtr->ptr))->export.name ==
816 smiNamedNumberPtr->name)
817 break;
818 }
819
820 if ((!listPtr) || (!listPtr->nextPtr)) {
821 return NULL;
822 }
823
824 return &((NamedNumber *)listPtr->nextPtr->ptr)->export;
825 }
826
smiGetFirstRange(SmiType * smiTypePtr)827 SmiRange *smiGetFirstRange(SmiType *smiTypePtr)
828 {
829 Type *typePtr;
830
831 typePtr = (Type *)smiTypePtr;
832
833 if ((!typePtr) || (!typePtr->listPtr) ||
834 (typePtr->export.basetype == SMI_BASETYPE_ENUM) ||
835 (typePtr->export.basetype == SMI_BASETYPE_BITS)) {
836 return NULL;
837 }
838
839 return &((Range *)typePtr->listPtr->ptr)->export;
840 }
841
842
843
smiGetNextRange(SmiRange * smiRangePtr)844 SmiRange *smiGetNextRange(SmiRange *smiRangePtr)
845 {
846 Type *typePtr;
847 List *listPtr;
848
849 if (!smiRangePtr) {
850 return NULL;
851 }
852
853 typePtr = ((Range *)smiRangePtr)->typePtr;
854
855 if ((!typePtr) || (!typePtr->listPtr) ||
856 (typePtr->export.basetype == SMI_BASETYPE_ENUM) ||
857 (typePtr->export.basetype == SMI_BASETYPE_BITS)) {
858 return NULL;
859 }
860
861 for (listPtr = typePtr->listPtr; listPtr; listPtr = listPtr->nextPtr) {
862 if (!memcmp(&((Range *)listPtr->ptr)->export.minValue,
863 &smiRangePtr->minValue, sizeof(struct SmiValue)))
864 break;
865 }
866
867 if ((!listPtr) || (!listPtr->nextPtr)) {
868 return NULL;
869 }
870
871 return &((Range *)listPtr->nextPtr->ptr)->export;
872 }
873
smiGetAttributeFirstRange(SmiAttribute * smiAttributePtr)874 SmiRange *smiGetAttributeFirstRange(SmiAttribute *smiAttributePtr)
875 {
876 Attribute *attributePtr;
877
878 attributePtr = (Attribute *)smiAttributePtr;
879
880 if ((!attributePtr) || (!attributePtr->listPtr) ||
881 (attributePtr->export.basetype == SMI_BASETYPE_ENUM) ||
882 (attributePtr->export.basetype == SMI_BASETYPE_BITS)) {
883 return NULL;
884 }
885
886 return &((Range *)attributePtr->listPtr->ptr)->export;
887 }
888
889
890
smiGetAttributeNextRange(SmiRange * smiRangePtr)891 SmiRange *smiGetAttributeNextRange(SmiRange *smiRangePtr)
892 {
893 Attribute *attributePtr;
894 List *listPtr;
895
896 if (!smiRangePtr) {
897 return NULL;
898 }
899
900 attributePtr = (Attribute*)((Range *)smiRangePtr)->typePtr;
901
902 if ((!attributePtr) || (!attributePtr->listPtr) ||
903 (attributePtr->export.basetype == SMI_BASETYPE_ENUM) ||
904 (attributePtr->export.basetype == SMI_BASETYPE_BITS)) {
905 return NULL;
906 }
907
908 for (listPtr = attributePtr->listPtr; listPtr; listPtr = listPtr->nextPtr) {
909 if (!memcmp(&((Range *)listPtr->ptr)->export.minValue,
910 &smiRangePtr->minValue, sizeof(struct SmiValue)))
911 break;
912 }
913
914 if ((!listPtr) || (!listPtr->nextPtr)) {
915 return NULL;
916 }
917
918 return &((Range *)listPtr->nextPtr->ptr)->export;
919 }
920
921
smiGetFirstIdentity(SmiModule * smiModulePtr)922 SmiIdentity *smiGetFirstIdentity(SmiModule *smiModulePtr)
923 {
924 if (!smiModulePtr) {
925 return NULL;
926 }
927
928 return ((Module *)smiModulePtr)->firstIdentityPtr ?
929 &((Module *)smiModulePtr)->firstIdentityPtr->export : NULL;
930
931 }
932
smiGetNextIdentity(SmiIdentity * smiIdentityPtr)933 SmiIdentity *smiGetNextIdentity(SmiIdentity *smiIdentityPtr)
934 {
935 if (!smiIdentityPtr) {
936 return NULL;
937 }
938
939 return ((Identity *)smiIdentityPtr)->nextPtr ?
940 &((Identity *)smiIdentityPtr)->nextPtr->export : NULL;
941 }
942
smiGetIdentityModule(SmiIdentity * smiIdentityPtr)943 SmiModule *smiGetIdentityModule(SmiIdentity *smiIdentityPtr)
944 {
945 return &((Identity *)smiIdentityPtr)->modulePtr->export;
946 }
947
smiGetParentIdentity(SmiIdentity * smiIdentityPtr)948 SmiIdentity *smiGetParentIdentity(SmiIdentity *smiIdentityPtr)
949 {
950 return (SmiIdentity*)(((Identity *)smiIdentityPtr)->parentPtr);
951 }
952
smiGetIdentity(SmiModule * smiModulePtr,char * identity)953 SmiIdentity *smiGetIdentity(SmiModule *smiModulePtr, char *identity)
954 {
955
956 if (!smiModulePtr) {
957 return NULL;
958 }
959 else
960 {
961 SmiIdentity *ide;
962
963 for(ide = smiGetFirstIdentity(smiModulePtr);
964 ide;
965 ide = smiGetNextIdentity(ide))
966 if(!strncmp(ide->name,identity,64))return ide;
967
968 return NULL;
969 }
970
971 }
972
smiGetIdentityLine(SmiIdentity * smiIdentityPtr)973 int smiGetIdentityLine(SmiIdentity *smiIdentityPtr)
974 {
975 return ((Identity *)smiIdentityPtr)->line;
976 }
977
978
smiGetFirstClass(SmiModule * smiModulePtr)979 SmiClass *smiGetFirstClass(SmiModule *smiModulePtr)
980 {
981 if (!smiModulePtr) {
982 return NULL;
983 }
984
985 return ((Module *)smiModulePtr)->firstClassPtr ?
986 &((Module *)smiModulePtr)->firstClassPtr->export : NULL;
987
988 }
989
smiGetNextClass(SmiClass * smiClassPtr)990 SmiClass *smiGetNextClass(SmiClass *smiClassPtr)
991 {
992 if (!smiClassPtr) {
993 return NULL;
994 }
995
996 return ((Class *)smiClassPtr)->nextPtr ?
997 &((Class *)smiClassPtr)->nextPtr->export : NULL;
998 }
999
smiGetClassModule(SmiClass * smiClassPtr)1000 SmiModule *smiGetClassModule(SmiClass *smiClassPtr)
1001 {
1002 return &((Class *)smiClassPtr)->modulePtr->export;
1003 }
1004
smiGetParentClass(SmiClass * smiClassPtr)1005 SmiClass *smiGetParentClass(SmiClass *smiClassPtr)
1006 {
1007 return (SmiClass*)(((Class *)smiClassPtr)->parentPtr);
1008 }
1009
smiGetClass(SmiModule * smiModulePtr,char * class)1010 SmiClass *smiGetClass(SmiModule *smiModulePtr, char *class)
1011 {
1012
1013 if (!smiModulePtr) {
1014 return NULL;
1015 }
1016 else
1017 {
1018 SmiClass *cl;
1019
1020 for(cl = smiGetFirstClass(smiModulePtr);
1021 cl;
1022 cl = smiGetNextClass(cl))
1023 if(!strncmp(cl->name,class,64))return cl;
1024
1025 return NULL;
1026 }
1027
1028 }
1029
smiGetClassLine(SmiClass * smiClassPtr)1030 int smiGetClassLine(SmiClass *smiClassPtr)
1031 {
1032 return ((Class *)smiClassPtr)->line;
1033 }
1034
smiGetFirstAttribute(SmiClass * smiClassPtr)1035 SmiAttribute *smiGetFirstAttribute(SmiClass *smiClassPtr)
1036 {
1037 Attribute *attributePtr;
1038
1039 if (!smiClassPtr) {
1040 return NULL;
1041 }
1042
1043 attributePtr = ((Class *)smiClassPtr)->firstAttributePtr;
1044
1045 return &attributePtr->export;
1046 }
1047
smiGetNextAttribute(SmiAttribute * smiTypePtr)1048 SmiAttribute *smiGetNextAttribute( SmiAttribute *smiTypePtr)
1049 {
1050 Attribute *attributePtr;
1051
1052 if (!smiTypePtr) {
1053 return NULL;
1054 }
1055
1056 attributePtr = ((Attribute *)smiTypePtr)->nextPtr;
1057
1058 return &attributePtr->export;
1059 }
1060
smiGetAttribute(SmiClass * smiClassPtr,char * attribute)1061 SmiAttribute *smiGetAttribute(SmiClass *smiClassPtr, char *attribute)
1062 {
1063 Attribute *attributePtr;
1064
1065 if (! smiClassPtr) {
1066 return NULL;
1067 }
1068
1069 attributePtr = ((Class *)smiClassPtr)->firstAttributePtr;
1070
1071 for (attributePtr = ((Class *)smiClassPtr)->firstAttributePtr;
1072 attributePtr; attributePtr = attributePtr->nextPtr)
1073 {
1074 if (!strncmp(attributePtr->export.name, attribute,64)) {
1075 return &attributePtr->export;
1076 }
1077 }
1078
1079 /*
1080 * attribute might belong to the parent so check parent if
1081 * attribute not found
1082 */
1083
1084 smiClassPtr = smiGetParentClass(smiClassPtr);
1085 attributePtr = (Attribute*)smiGetAttribute(smiClassPtr , attribute);
1086
1087 return &attributePtr->export;
1088 }
1089
smiGetAttributeParentType(SmiAttribute * smiAttributePtr)1090 SmiType *smiGetAttributeParentType(SmiAttribute *smiAttributePtr)
1091 {
1092 Type *parentTypePtr;
1093
1094 if (! smiAttributePtr) {
1095 return NULL;
1096 }
1097
1098 parentTypePtr = ((Attribute*)smiAttributePtr)->parentTypePtr;
1099
1100 return (parentTypePtr) ? &parentTypePtr->export : NULL;
1101 }
1102
smiGetAttributeParentClass(SmiAttribute * smiAttributePtr)1103 SmiClass *smiGetAttributeParentClass( SmiAttribute *smiAttributePtr)
1104 {
1105 Class *parentClassPtr;
1106
1107 if (! smiAttributePtr) {
1108 return NULL;
1109 }
1110
1111 parentClassPtr = ((Attribute*)smiAttributePtr)->parentClassPtr;
1112
1113 return parentClassPtr ? &parentClassPtr->export : NULL;
1114 }
1115
smiGetFirstUniqueAttribute(SmiClass * smiClassPtr)1116 SmiAttribute *smiGetFirstUniqueAttribute(SmiClass *smiClassPtr)
1117 {
1118 Class *classPtr;
1119
1120 if (! smiClassPtr) {
1121 return NULL;
1122 }
1123
1124 classPtr = (Class*)smiClassPtr;
1125
1126 if (! classPtr->uniqueList) {
1127 return NULL;
1128 }
1129
1130 if (classPtr->uniqueList->ptr == classPtr) {
1131 return NULL; /* scalar class */
1132 }
1133
1134 return (SmiAttribute*)(classPtr->uniqueList->ptr);
1135 }
1136
smiGetNextUniqueAttribute(SmiAttribute * smiTypePtr)1137 SmiAttribute *smiGetNextUniqueAttribute( SmiAttribute *smiTypePtr)
1138 {
1139 Class *classPtr;
1140 List *listPtr;
1141
1142 if (! smiTypePtr) {
1143 return NULL;
1144 }
1145
1146 classPtr = ((Attribute*)smiTypePtr)->classPtr;
1147
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;
1153 }
1154 }
1155 }
1156 }
1157 return NULL;
1158 }
1159
1160
1161
smiGetAttributeLine(SmiAttribute * smiAttributePtr)1162 int smiGetAttributeLine(SmiAttribute *smiAttributePtr)
1163 {
1164 return ((Attribute *)smiAttributePtr)->line;
1165 }
1166
1167
1168
smiIsClassScalar(SmiClass * smiClassPtr)1169 int smiIsClassScalar(SmiClass *smiClassPtr)
1170 {
1171 Class *classPtr;
1172
1173 if (! smiClassPtr) {
1174 return 0;
1175 }
1176
1177 classPtr = (Class*)smiClassPtr;
1178
1179 if (! classPtr->uniqueList) {
1180 return 0;
1181 }
1182
1183 return (classPtr->uniqueList->ptr == classPtr);
1184 }
1185
1186
1187
smiGetFirstEvent(SmiClass * smiClassPtr)1188 SmiEvent *smiGetFirstEvent(SmiClass *smiClassPtr)
1189 {
1190 Event *eventPtr;
1191
1192 if (! smiClassPtr) {
1193 return NULL;
1194 }
1195
1196 eventPtr = ((Class *)smiClassPtr)->firstEventPtr;
1197 return &(eventPtr->export);
1198 }
1199
1200
1201
smiGetNextEvent(SmiEvent * smiEventPtr)1202 SmiEvent *smiGetNextEvent(SmiEvent *smiEventPtr)
1203 {
1204 Event *eventPtr;
1205
1206 if (! smiEventPtr) {
1207 return NULL;
1208 }
1209
1210 eventPtr = ((Event *)smiEventPtr)->nextPtr;
1211 return &eventPtr->export;
1212 }
1213
1214
1215
smiGetEventLine(SmiEvent * smiEventPtr)1216 int smiGetEventLine(SmiEvent *smiEventPtr)
1217 {
1218 return ((Event *)smiEventPtr)->line;
1219 }
1220
1221
1222
smiGetMacro(SmiModule * smiModulePtr,char * macro)1223 SmiMacro *smiGetMacro(SmiModule *smiModulePtr, char *macro)
1224 {
1225 Macro *macroPtr = NULL;
1226 Module *modulePtr = NULL;
1227 char *module2, *macro2;
1228
1229 if (!macro) {
1230 return NULL;
1231 }
1232
1233 modulePtr = (Module *)smiModulePtr;
1234
1235 getModulenameAndName(smiModulePtr ? smiModulePtr->name : NULL, macro,
1236 &module2, ¯o2);
1237
1238 if (!modulePtr && module2 && strlen(module2)) {
1239 if (!(modulePtr = findModuleByName(module2))) {
1240 modulePtr = loadModule(module2, NULL);
1241 }
1242 }
1243
1244 if (modulePtr) {
1245 macroPtr = findMacroByModuleAndName(modulePtr, macro2);
1246 } else {
1247 macroPtr = findMacroByName(macro2);
1248 }
1249
1250 smiFree(module2);
1251 smiFree(macro2);
1252 return macroPtr ? ¯oPtr->export : NULL;
1253 }
1254
1255
1256
smiGetFirstMacro(SmiModule * smiModulePtr)1257 SmiMacro *smiGetFirstMacro(SmiModule *smiModulePtr)
1258 {
1259 if (!smiModulePtr) {
1260 return NULL;
1261 }
1262
1263 return ((Module *)smiModulePtr)->firstMacroPtr ?
1264 &((Module *)smiModulePtr)->firstMacroPtr->export : NULL;
1265 }
1266
1267
1268
smiGetNextMacro(SmiMacro * smiMacroPtr)1269 SmiMacro *smiGetNextMacro(SmiMacro *smiMacroPtr)
1270 {
1271 if (!smiMacroPtr) {
1272 return NULL;
1273 }
1274
1275 return ((Macro *)smiMacroPtr)->nextPtr ?
1276 &((Macro *)smiMacroPtr)->nextPtr->export : NULL;
1277 }
1278
1279
smiGetMacroModule(SmiMacro * smiMacroPtr)1280 SmiModule *smiGetMacroModule(SmiMacro *smiMacroPtr)
1281 {
1282 return &((Macro *)smiMacroPtr)->modulePtr->export;
1283 }
1284
1285
smiGetMacroLine(SmiMacro * smiMacroPtr)1286 int smiGetMacroLine(SmiMacro *smiMacroPtr)
1287 {
1288 return ((Macro *)smiMacroPtr)->line;
1289 }
1290
1291
smiGetNode(SmiModule * smiModulePtr,const char * node)1292 SmiNode *smiGetNode(SmiModule *smiModulePtr, const char *node)
1293 {
1294 Object *objectPtr = NULL;
1295 Module *modulePtr = NULL;
1296 Node *nodePtr;
1297 char *module2, *node2, *p;
1298 unsigned int oidlen;
1299 SmiSubid oid[128];
1300
1301 if (!node) {
1302 return NULL;
1303 }
1304
1305 modulePtr = (Module *)smiModulePtr;
1306
1307 getModulenameAndName(smiModulePtr ? smiModulePtr->name : NULL, node,
1308 &module2, &node2);
1309
1310 if (!modulePtr && module2 && strlen(module2)) {
1311 if (!(modulePtr = findModuleByName(module2))) {
1312 modulePtr = loadModule(module2, NULL);
1313 }
1314 }
1315
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);
1320 }
1321 nodePtr = getNode(oidlen, oid);
1322 if (nodePtr) {
1323 if (modulePtr) {
1324 objectPtr = findObjectByModuleAndNode(modulePtr, nodePtr);
1325 } else {
1326 objectPtr = findObjectByNode(nodePtr);
1327 }
1328 }
1329 } else {
1330 p = strtok(node2, ". ");
1331 if (modulePtr) {
1332 objectPtr = findObjectByModuleAndName(modulePtr, p);
1333 } else {
1334 objectPtr = findObjectByName(p);
1335 }
1336 }
1337
1338 smiFree(module2);
1339 smiFree(node2);
1340 return objectPtr ? &objectPtr->export : NULL;
1341 }
1342
1343
1344
smiGetNodeByOID(unsigned int oidlen,SmiSubid oid[])1345 SmiNode *smiGetNodeByOID(unsigned int oidlen, SmiSubid oid[])
1346 {
1347 Node *nodePtr;
1348 Object *objectPtr;
1349
1350 if (!oidlen) {
1351 return NULL;
1352 }
1353
1354 nodePtr = getNode(oidlen, oid);
1355
1356 if (!nodePtr) {
1357 return NULL;
1358 }
1359
1360 objectPtr = findObjectByNode(nodePtr);
1361
1362 return objectPtr ? &objectPtr->export : NULL;
1363 }
1364
1365
1366
smiGetFirstNode(SmiModule * smiModulePtr,SmiNodekind nodekind)1367 SmiNode *smiGetFirstNode(SmiModule *smiModulePtr, SmiNodekind nodekind)
1368 {
1369 Module *modulePtr;
1370 Node *nodePtr = NULL;
1371 Object *objectPtr;
1372
1373 if (!smiModulePtr) {
1374 return NULL;
1375 }
1376
1377 modulePtr = (Module *)smiModulePtr;
1378
1379 if (modulePtr && modulePtr->prefixNodePtr) {
1380 /* start at the common oid prefix of this module */
1381 nodePtr = modulePtr->prefixNodePtr;
1382 } else {
1383 nodePtr = smiHandle->rootNodePtr->firstChildPtr;
1384 }
1385
1386 do {
1387 objectPtr = getNextChildObject(nodePtr, modulePtr, nodekind);
1388
1389 if (objectPtr)
1390 return &objectPtr->export;
1391
1392 if (nodePtr->firstChildPtr) {
1393 nodePtr = nodePtr->firstChildPtr;
1394 } else if (nodePtr->nextPtr) {
1395 nodePtr = nodePtr->nextPtr;
1396 } else {
1397 for (nodePtr = nodePtr->parentPtr;
1398 nodePtr && (nodePtr->parentPtr) && (!nodePtr->nextPtr);
1399 nodePtr = nodePtr->parentPtr);
1400 if (nodePtr) nodePtr = nodePtr->nextPtr;
1401 }
1402 } while (nodePtr);
1403
1404 return NULL;
1405 }
1406
1407
1408
smiGetNextNode(SmiNode * smiNodePtr,SmiNodekind nodekind)1409 SmiNode *smiGetNextNode(SmiNode *smiNodePtr, SmiNodekind nodekind)
1410 {
1411 Module *modulePtr;
1412 Object *objectPtr;
1413 Node *nodePtr;
1414 int i;
1415
1416 if (!smiNodePtr) {
1417 return NULL;
1418 }
1419
1420 objectPtr = (Object *)smiNodePtr;
1421 nodePtr = objectPtr->nodePtr;
1422 modulePtr = objectPtr->modulePtr;
1423
1424 if (!modulePtr) {
1425 return NULL;
1426 }
1427
1428 if (!nodePtr) {
1429 return NULL;
1430 }
1431
1432 do {
1433 if (nodePtr->firstChildPtr) {
1434 nodePtr = nodePtr->firstChildPtr;
1435 } else if (nodePtr->nextPtr) {
1436 nodePtr = nodePtr->nextPtr;
1437 } else {
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]))
1446 return NULL;
1447 }
1448
1449 objectPtr = getNextChildObject(nodePtr, modulePtr, nodekind);
1450
1451 if (objectPtr)
1452 return &objectPtr->export;
1453
1454 } while (nodePtr);
1455
1456 return NULL;
1457 }
1458
1459
1460
smiGetParentNode(SmiNode * smiNodePtr)1461 SmiNode *smiGetParentNode(SmiNode *smiNodePtr)
1462 {
1463 Module *modulePtr;
1464 Object *objectPtr;
1465 Import *importPtr;
1466 Node *nodePtr;
1467
1468 if (!smiNodePtr) {
1469 return NULL;
1470 }
1471
1472 objectPtr = (Object *)smiNodePtr;
1473 nodePtr = objectPtr->nodePtr;
1474 modulePtr = objectPtr->modulePtr;
1475
1476 if (!nodePtr) {
1477 return NULL;
1478 }
1479
1480 if (nodePtr == smiHandle->rootNodePtr) {
1481 return NULL;
1482 }
1483
1484 nodePtr = nodePtr->parentPtr;
1485 if (! nodePtr) {
1486 return NULL;
1487 }
1488
1489 /*
1490 * First, try to find a definition in the same module.
1491 */
1492 objectPtr = NULL;
1493 if (modulePtr) {
1494 objectPtr = findObjectByModuleAndNode(modulePtr, nodePtr);
1495 }
1496
1497 /*
1498 * If found, check if it's imported. In case, get the original definition.
1499 */
1500 if (objectPtr) {
1501 importPtr = findImportByName(objectPtr->export.name,
1502 objectPtr->modulePtr);
1503 if (importPtr) {
1504 objectPtr = findObjectByModulenameAndNode(importPtr->export.module,
1505 nodePtr);
1506 } else {
1507 objectPtr = NULL;
1508 }
1509 }
1510
1511 /*
1512 * If not yet found, try to find any definition.
1513 */
1514 if (!objectPtr) {
1515 objectPtr = findObjectByNode(nodePtr);
1516
1517 if ((!objectPtr) && (nodePtr->parentPtr)) {
1518 /* an implicitly created node, e.g. gaga.0 in an object
1519 * definition with oid == gaga.0.1.
1520 */
1521 objectPtr = addObject(SMI_UNKNOWN_LABEL,
1522 nodePtr->parentPtr, nodePtr->subid,
1523 0, NULL);
1524 objectPtr->nodePtr = nodePtr;
1525 objectPtr->modulePtr = modulePtr;
1526 }
1527 }
1528
1529 return objectPtr ? &objectPtr->export : NULL;
1530 }
1531
1532
1533
smiGetRelatedNode(SmiNode * smiNodePtr)1534 SmiNode *smiGetRelatedNode(SmiNode *smiNodePtr)
1535 {
1536 if (!smiNodePtr) {
1537 return NULL;
1538 }
1539
1540 return &((Object *)smiNodePtr)->relatedPtr->export;
1541 }
1542
1543
1544
smiGetFirstChildNode(SmiNode * smiNodePtr)1545 SmiNode *smiGetFirstChildNode(SmiNode *smiNodePtr)
1546 {
1547 Module *modulePtr;
1548 Object *objectPtr;
1549 Node *nodePtr;
1550
1551 if (!smiNodePtr) {
1552 return NULL;
1553 }
1554
1555 objectPtr = (Object *)smiNodePtr;
1556 nodePtr = objectPtr->nodePtr;
1557 modulePtr = objectPtr->modulePtr;
1558
1559 if (!nodePtr) {
1560 return NULL;
1561 }
1562
1563 nodePtr = nodePtr->firstChildPtr;
1564
1565 if (!nodePtr) {
1566 return NULL;
1567 }
1568
1569 objectPtr = findObjectByModuleAndNode(modulePtr, nodePtr);
1570 if (!objectPtr) objectPtr = findObjectByNode(nodePtr);
1571
1572 return objectPtr ? &objectPtr->export : NULL;
1573 }
1574
1575
1576
smiGetNextChildNode(SmiNode * smiNodePtr)1577 SmiNode *smiGetNextChildNode(SmiNode *smiNodePtr)
1578 {
1579 Module *modulePtr;
1580 Object *objectPtr;
1581 Node *nodePtr;
1582
1583 if (!smiNodePtr) {
1584 return NULL;
1585 }
1586
1587 objectPtr = (Object *)smiNodePtr;
1588 nodePtr = objectPtr->nodePtr;
1589 modulePtr = objectPtr->modulePtr;
1590
1591 if (!nodePtr) {
1592 return NULL;
1593 }
1594
1595 nodePtr = nodePtr->nextPtr;
1596
1597 if (!nodePtr) {
1598 return NULL;
1599 }
1600
1601 objectPtr = findObjectByModuleAndNode(modulePtr, nodePtr);
1602 if (!objectPtr) objectPtr = findObjectByNode(nodePtr);
1603
1604 return objectPtr ? &objectPtr->export : NULL;
1605 }
1606
1607
1608
smiGetModuleIdentityNode(SmiModule * smiModulePtr)1609 SmiNode *smiGetModuleIdentityNode(SmiModule *smiModulePtr)
1610 {
1611 if (!smiModulePtr) {
1612 return NULL;
1613 }
1614
1615 return &((Module *)smiModulePtr)->objectPtr->export;
1616 }
1617
1618
1619
smiGetNodeModule(SmiNode * smiNodePtr)1620 SmiModule *smiGetNodeModule(SmiNode *smiNodePtr)
1621 {
1622 return &((Object *)smiNodePtr)->modulePtr->export;
1623 }
1624
1625
1626
smiGetNodeType(SmiNode * smiNodePtr)1627 SmiType *smiGetNodeType(SmiNode *smiNodePtr)
1628 {
1629 Type *typePtr;
1630
1631 typePtr = ((Object *)smiNodePtr)->typePtr;
1632
1633 if (!typePtr ||
1634 typePtr->export.basetype == SMI_BASETYPE_UNKNOWN) {
1635 return NULL;
1636 }
1637
1638 return &typePtr->export;
1639 }
1640
1641
1642
smiGetNodeLine(SmiNode * smiNodePtr)1643 int smiGetNodeLine(SmiNode *smiNodePtr)
1644 {
1645 return ((Object *)smiNodePtr)->line;
1646 }
1647
1648
1649
smiGetFirstElement(SmiNode * smiNodePtr)1650 SmiElement *smiGetFirstElement(SmiNode *smiNodePtr)
1651 {
1652 List *listPtr;
1653
1654 if (!smiNodePtr) {
1655 return NULL;
1656 }
1657
1658 listPtr = ((Object *)smiNodePtr)->listPtr;
1659
1660 return (SmiElement *)listPtr;
1661 }
1662
1663
1664
smiGetNextElement(SmiElement * smiElementPtr)1665 SmiElement *smiGetNextElement(SmiElement *smiElementPtr)
1666 {
1667 List *listPtr;
1668
1669 if (!smiElementPtr) {
1670 return NULL;
1671 }
1672
1673 listPtr = ((List *)smiElementPtr)->nextPtr;
1674
1675 return (SmiElement *)listPtr;
1676 }
1677
1678
1679
smiGetElementNode(SmiElement * smiElementPtr)1680 SmiNode *smiGetElementNode(SmiElement *smiElementPtr)
1681 {
1682 if ((Object *)((List *)smiElementPtr)->ptr)
1683 return &((Object *)((List *)smiElementPtr)->ptr)->export;
1684 else
1685 return NULL;
1686 }
1687
1688
1689
smiGetFirstOption(SmiNode * smiComplianceNodePtr)1690 SmiOption *smiGetFirstOption(SmiNode *smiComplianceNodePtr)
1691 {
1692 Object *objectPtr;
1693
1694 if (!smiComplianceNodePtr) {
1695 return NULL;
1696 }
1697
1698 objectPtr = (Object *)smiComplianceNodePtr;
1699
1700 if (!objectPtr->optionlistPtr) {
1701 return NULL;
1702 }
1703
1704 if (objectPtr->export.nodekind != SMI_NODEKIND_COMPLIANCE) {
1705 return NULL;
1706 }
1707
1708 return &((Option *)objectPtr->optionlistPtr->ptr)->export;
1709 }
1710
1711
1712
smiGetNextOption(SmiOption * smiOptionPtr)1713 SmiOption *smiGetNextOption(SmiOption *smiOptionPtr)
1714 {
1715 List *listPtr;
1716
1717 if (!smiOptionPtr) {
1718 return NULL;
1719 }
1720
1721 for (listPtr =
1722 ((Option *)smiOptionPtr)->compliancePtr->optionlistPtr;
1723 listPtr;
1724 listPtr = listPtr->nextPtr) {
1725 if ((Option *)(listPtr->ptr) == (Option *)smiOptionPtr) {
1726 if (listPtr->nextPtr) {
1727 return &((Option *)listPtr->nextPtr->ptr)->export;
1728 } else {
1729 return NULL;
1730 }
1731 }
1732 }
1733
1734 return NULL;
1735 }
1736
1737
1738
smiGetOptionNode(SmiOption * smiOptionPtr)1739 SmiNode *smiGetOptionNode(SmiOption *smiOptionPtr)
1740 {
1741 return &((Option *)smiOptionPtr)->objectPtr->export;
1742 }
1743
1744
1745
smiGetOptionLine(SmiOption * smiOptionPtr)1746 int smiGetOptionLine(SmiOption *smiOptionPtr)
1747 {
1748 return ((Option *)smiOptionPtr)->line;
1749 }
1750
1751
1752
smiGetFirstRefinement(SmiNode * smiComplianceNodePtr)1753 SmiRefinement *smiGetFirstRefinement(SmiNode *smiComplianceNodePtr)
1754 {
1755 Object *objectPtr;
1756
1757 if (!smiComplianceNodePtr) {
1758 return NULL;
1759 }
1760
1761 objectPtr = (Object *)smiComplianceNodePtr;
1762
1763 if (!objectPtr->refinementlistPtr) {
1764 return NULL;
1765 }
1766
1767 if (objectPtr->export.nodekind != SMI_NODEKIND_COMPLIANCE) {
1768 return NULL;
1769 }
1770
1771 return &((Refinement *)objectPtr->refinementlistPtr->ptr)->export;
1772 }
1773
1774
1775
smiGetNextRefinement(SmiRefinement * smiRefinementPtr)1776 SmiRefinement *smiGetNextRefinement(SmiRefinement *smiRefinementPtr)
1777 {
1778 List *listPtr;
1779
1780 if (!smiRefinementPtr) {
1781 return NULL;
1782 }
1783
1784 for (listPtr =
1785 ((Refinement *)smiRefinementPtr)->compliancePtr->refinementlistPtr;
1786 listPtr;
1787 listPtr = listPtr->nextPtr) {
1788 if ((Refinement *)(listPtr->ptr) == (Refinement *)smiRefinementPtr) {
1789 if (listPtr->nextPtr) {
1790 return &((Refinement *)listPtr->nextPtr->ptr)->export;
1791 } else {
1792 return NULL;
1793 }
1794 }
1795 }
1796
1797 return NULL;
1798 }
1799
1800
1801
smiGetRefinementNode(SmiRefinement * smiRefinementPtr)1802 SmiNode *smiGetRefinementNode(SmiRefinement *smiRefinementPtr)
1803 {
1804 return &((Refinement *)smiRefinementPtr)->objectPtr->export;
1805 }
1806
1807
1808
smiGetRefinementType(SmiRefinement * smiRefinementPtr)1809 SmiType *smiGetRefinementType(SmiRefinement *smiRefinementPtr)
1810 {
1811 Type *typePtr;
1812
1813 typePtr = ((Refinement *)smiRefinementPtr)->typePtr;
1814
1815 if (!typePtr ||
1816 typePtr->export.basetype == SMI_BASETYPE_UNKNOWN) {
1817 return NULL;
1818 }
1819
1820 return &typePtr->export;
1821 }
1822
1823
1824
smiGetRefinementWriteType(SmiRefinement * smiRefinementPtr)1825 SmiType *smiGetRefinementWriteType(SmiRefinement *smiRefinementPtr)
1826 {
1827 Type *typePtr;
1828
1829 typePtr = ((Refinement *)smiRefinementPtr)->writetypePtr;
1830
1831 if (!typePtr ||
1832 typePtr->export.basetype == SMI_BASETYPE_UNKNOWN) {
1833 return NULL;
1834 }
1835
1836 return &typePtr->export;
1837 }
1838
1839
1840
smiGetRefinementLine(SmiRefinement * smiRefinementPtr)1841 int smiGetRefinementLine(SmiRefinement *smiRefinementPtr)
1842 {
1843 return ((Refinement *)smiRefinementPtr)->line;
1844 }
1845
1846
1847
smiGetFirstUniquenessElement(SmiNode * smiNodePtr)1848 SmiElement *smiGetFirstUniquenessElement(SmiNode *smiNodePtr)
1849 {
1850 List *listPtr;
1851
1852 if (!smiNodePtr) {
1853 return NULL;
1854 }
1855
1856 listPtr = ((Object *)smiNodePtr)->uniquenessPtr;
1857
1858 return (SmiElement *)listPtr;
1859 }
1860
1861
1862
smiRenderOID(unsigned int oidlen,SmiSubid * oid,int flags)1863 char *smiRenderOID(unsigned int oidlen, SmiSubid *oid, int flags)
1864 {
1865 SmiNode *nodePtr = NULL;
1866 SmiModule *modulePtr = NULL;
1867 unsigned int i = 0;
1868 char *ss, *s = NULL;
1869
1870 if (!oid) {
1871 if (flags & SMI_RENDER_UNKNOWN) {
1872 smiAsprintf(&s, SMI_UNKNOWN_LABEL);
1873 } else {
1874 s = NULL;
1875 }
1876 return s;
1877 }
1878
1879 if (flags & (SMI_RENDER_NAME | SMI_RENDER_QUALIFIED)) {
1880 int len;
1881 for (len = oidlen; len; len--) {
1882 nodePtr = smiGetNodeByOID(len, oid);
1883 if (! nodePtr || nodePtr->name) break;
1884 }
1885 if (nodePtr && nodePtr->name) {
1886 i = nodePtr->oidlen;
1887 if (flags & SMI_RENDER_QUALIFIED) {
1888 modulePtr = smiGetNodeModule(nodePtr);
1889 }
1890 if (modulePtr) {
1891 smiAsprintf(&s, "%s::%s",
1892 modulePtr->name, nodePtr->name);
1893 } else {
1894 smiAsprintf(&s, "%s", nodePtr->name);
1895 }
1896 }
1897 }
1898
1899 for (; i < oidlen; i++) {
1900 ss = s;
1901 smiAsprintf(&s, "%s%s%u", ss ? ss : "", i ? "." : "", oid[i]);
1902 smiFree(ss);
1903 }
1904
1905 if ((!s) && (flags & SMI_RENDER_UNKNOWN)) {
1906 smiAsprintf(&s, SMI_UNKNOWN_LABEL);
1907 }
1908
1909 return s;
1910 }
1911
1912
1913
smiRenderValue(SmiValue * smiValuePtr,SmiType * smiTypePtr,int flags)1914 char *smiRenderValue(SmiValue *smiValuePtr, SmiType *smiTypePtr, int flags)
1915 {
1916 unsigned int i, pfx;
1917 int j, k, n, have_pfx;
1918 char *last_fmt, *fmt;
1919 SmiUnsigned64 vv;
1920 int xlen;
1921 SmiNamedNumber *nn;
1922 char *s, *ss;
1923 char f[8];
1924 SmiUnsigned32 v32;
1925 SmiUnsigned64 v64;
1926
1927 if (!smiValuePtr) {
1928 if (flags & SMI_RENDER_UNKNOWN) {
1929 smiAsprintf(&s, SMI_UNKNOWN_LABEL);
1930 } else {
1931 s = NULL;
1932 }
1933 return s;
1934 }
1935
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]);
1944 if (i < 0) i = 0;
1945 if (i > 20) i = 20;
1946 smiAsprintf(&s, "%0*lu.",
1947 1 + i,
1948 smiValuePtr->value.unsigned32);
1949 if (s) {
1950 for (j = strlen(s) - 1; i > 0; i--, j--) {
1951 s[j] = s[j-1];
1952 }
1953 s[j] = '.';
1954 }
1955 } else {
1956 smiAsprintf(&s, "%lu", smiValuePtr->value.unsigned32);
1957 }
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') {
1963 for (i = 32 - 1;
1964 i > 0 && !(smiValuePtr->value.unsigned32 & (1 << i)); i--);
1965 s = smiMalloc(i + 1 + 1);
1966 if (s) {
1967 for (j = 0; i >= 0; i--, j++) {
1968 s[j] = smiValuePtr->value.unsigned32 & (1<<i) ? '1' : '0';
1969 }
1970 s[j] = 0;
1971 }
1972 }
1973 break;
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]);
1981 if (i < 0) i = 0;
1982 if (i > 20) i = 20;
1983 sprintf(f, "%%0%s.", UINT64_FORMAT);
1984 f[2] = '*';
1985 smiAsprintf(&s, f,
1986 1 + i,
1987 smiValuePtr->value.unsigned64);
1988 if (s) {
1989 for (j = strlen(s) - 1; i > 0; i--, j--) {
1990 s[j] = s[j-1];
1991 }
1992 s[j] = '.';
1993 }
1994 } else {
1995 smiAsprintf(&s, UINT64_FORMAT, smiValuePtr->value.unsigned64);
1996 }
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') {
2006 for (i = 64 - 1;
2007 i > 0 && !(smiValuePtr->value.unsigned64 & (1 << i)); i--);
2008 s = smiMalloc(i + 1 + 1);
2009 if (s) {
2010 for (j = 0; i >= 0; i--, j++) {
2011 s[j] = smiValuePtr->value.unsigned64 & (1<<i) ? '1' : '0';
2012 }
2013 s[j] = 0;
2014 }
2015 }
2016 break;
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]);
2024 if (i < 0) i = 0;
2025 if (i > 20) i = 20;
2026 smiAsprintf(&s, "%0*ld.",
2027 1 + i + (smiValuePtr->value.integer32 < 0 ? 1 : 0),
2028 smiValuePtr->value.integer32);
2029 if (s) {
2030 for (j = strlen(s) - 1; i > 0; i--, j--) {
2031 s[j] = s[j-1];
2032 }
2033 s[j] = '.';
2034 }
2035 } else {
2036 smiAsprintf(&s, "%ld", smiValuePtr->value.integer32);
2037 }
2038 } else if (smiTypePtr->format[0] == 'x') {
2039 if (smiValuePtr->value.integer32 >= 0) {
2040 smiAsprintf(&s, "%lx", smiValuePtr->value.integer32);
2041 } else {
2042 smiAsprintf(&s, "-%lx", - smiValuePtr->value.integer32);
2043 }
2044 } else if (smiTypePtr->format[0] == 'o') {
2045 if (smiValuePtr->value.integer32 >= 0) {
2046 smiAsprintf(&s, "%lo", smiValuePtr->value.integer32);
2047 } else {
2048 smiAsprintf(&s, "-%lo", - smiValuePtr->value.integer32);
2049 }
2050 } else if (smiTypePtr->format[0] == 'b') {
2051 if (smiValuePtr->value.integer32 >= 0) {
2052 v32 = smiValuePtr->value.integer32;
2053 j = 0;
2054 } else {
2055 v32 = - smiValuePtr->value.integer32;
2056 j = 1;
2057 }
2058 for (i = 32 - 1;
2059 i > 0 && !(v32 & (1 << i)); i--);
2060 s = smiMalloc(i + j + 1 + 1);
2061 if (s) {
2062 s[0] = '-';
2063 for (; i >= 0; i--, j++) {
2064 s[j] = v32 & (1<<i) ? '1' : '0';
2065 }
2066 s[j] = 0;
2067 }
2068 }
2069 break;
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]);
2077 if (i < 0) i = 0;
2078 if (i > 20) i = 20;
2079 sprintf(f, "%%0%s.", INT64_FORMAT);
2080 f[2] = '*';
2081 smiAsprintf(&s, f,
2082 1 + i + (smiValuePtr->value.integer64 < 0 ? 1 : 0),
2083 smiValuePtr->value.integer64);
2084 if (s) {
2085 for (j = strlen(s) - 1; i > 0; i--, j--) {
2086 s[j] = s[j-1];
2087 }
2088 s[j] = '.';
2089 }
2090 } else {
2091 smiAsprintf(&s, INT64_FORMAT, smiValuePtr->value.integer64);
2092 }
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);
2098 } else {
2099 sprintf(f, "-%s", UINT64_FORMAT);
2100 f[strlen(f)-1] = 'x';
2101 smiAsprintf(&s, f, - smiValuePtr->value.integer64);
2102 }
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);
2109 } else {
2110 smiAsprintf(&s, f, - smiValuePtr->value.integer64);
2111 }
2112 } else if (smiTypePtr->format[0] == 'b') {
2113 if (smiValuePtr->value.integer64 >= 0) {
2114 v64 = smiValuePtr->value.integer64;
2115 j = 0;
2116 } else {
2117 v64 = - smiValuePtr->value.integer64;
2118 j = 1;
2119 }
2120 for (i = 64 - 1;
2121 i > 0 && !(v64 & (1 << i)); i--);
2122 s = smiMalloc(i + j + 1 + 1);
2123 if (s) {
2124 s[0] = '-';
2125 for (; i >= 0; i--, j++) {
2126 s[j] = v64 & (1<<i) ? '1' : '0';
2127 }
2128 s[j] = 0;
2129 }
2130 }
2131 break;
2132 case SMI_BASETYPE_OBJECTIDENTIFIER:
2133 s = smiRenderOID(smiValuePtr->len, smiValuePtr->value.oid, flags);
2134 break;
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;
2141 }
2142 if ((i < smiValuePtr->len) ||
2143 !(flags & SMI_RENDER_PRINTABLE)) {
2144 smiAsprintf(&s, "");
2145 for (i=0; i < smiValuePtr->len; i++) {
2146 ss = s;
2147 smiAsprintf(&s, "%s%02x", ss, smiValuePtr->value.ptr[i]);
2148 smiFree(ss);
2149 }
2150 } else {
2151 smiAsprintf(&s, "%s", smiValuePtr->value.ptr);
2152 }
2153 } else {
2154 i = 0;
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) {
2162 last_fmt = fmt;
2163 have_pfx = pfx = 0; /* scan prefix: */
2164 while (*fmt && isdigit((int)*fmt)) {
2165 pfx = pfx * 10 + *fmt - '0', have_pfx = 1, fmt++;
2166 }
2167 if (! have_pfx) {
2168 pfx = 1;
2169 }
2170 switch (*fmt) {
2171 case 't':
2172 /* XXX UTF-8 not implemented, fall through to ASCII (a) */
2173 case '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])) {
2178 smiFree(s);
2179 if (flags & SMI_RENDER_UNKNOWN) {
2180 smiAsprintf(&s, SMI_UNKNOWN_LABEL);
2181 } else {
2182 s = NULL;
2183 }
2184 return s;
2185 }
2186 ss = s;
2187 smiAsprintf(&s, "%s%c", ss, smiValuePtr->value.ptr[i+k]);
2188 smiFree(ss);
2189 }
2190 i += n;
2191 break;
2192 case 'b':
2193 case 'd':
2194 case 'o':
2195 case 'x':
2196 /* XXX: limited to no more than
2197 sizeof(SmiUnsigned64) octets */
2198 vv = 0;
2199 xlen = pfx * 2;
2200 while (pfx > 0 && i < smiValuePtr->len) {
2201 vv = vv * 256 +
2202 ((unsigned char)smiValuePtr->value.ptr[i]);
2203 i++;
2204 pfx--;
2205 }
2206 switch (*fmt) {
2207 case 'd':
2208 ss = s;
2209 sprintf(f, "%%s%s", UINT64_FORMAT);
2210 smiAsprintf(&s, f, ss, vv);
2211 smiFree(ss);
2212 break;
2213 case 'o':
2214 ss = s;
2215 sprintf(f, "%%s%s", UINT64_FORMAT);
2216 f[strlen(f)-1] = 'o';
2217 smiAsprintf(&s, f, ss, vv);
2218 smiFree(ss);
2219 break;
2220 case 'x':
2221 ss = s;
2222 sprintf(f, "%%s%%0%s", UINT64_FORMAT);
2223 f[4] = '*';
2224 f[strlen(f)-1] = 'x';
2225 smiAsprintf(&s, f, ss, xlen, vv);
2226 smiFree(ss);
2227 break;
2228 case 'b':
2229 k = pfx * 8 - 1;
2230 if (k > sizeof(SmiUnsigned64) * 8 - 1)
2231 k = sizeof(SmiUnsigned64) * 8 - 1;
2232 for (j = 0; k >= 0; k--, j++) {
2233 ss = s;
2234 smiAsprintf(&s, "%s%c",
2235 ss, vv & (1 << k) ? '1' : '0');
2236 smiFree(ss);
2237 }
2238 break;
2239 }
2240 break;
2241 default:
2242 smiFree(s);
2243 if (flags & SMI_RENDER_UNKNOWN) {
2244 smiAsprintf(&s, SMI_UNKNOWN_LABEL);
2245 } else {
2246 s = NULL;
2247 }
2248 return s;
2249 }
2250 fmt++;
2251
2252 /*
2253 * Check for a separator and repeat with last format if
2254 * data is still available.
2255 */
2256 if (*fmt && ! isdigit((int) *fmt) && *fmt != '*') {
2257 if (i < smiValuePtr->len) {
2258 ss = s;
2259 smiAsprintf(&s, "%s%c", ss, fmt[0]);
2260 smiFree(ss);
2261 }
2262 fmt++;
2263 }
2264
2265 if (! *fmt && (i < smiValuePtr->len)) {
2266 fmt = last_fmt;
2267 }
2268 }
2269 }
2270 break;
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)
2276 break;
2277 }
2278 if (nn) {
2279 if (flags & SMI_RENDER_NUMERIC) {
2280 smiAsprintf(&s, "%s(%ld)",
2281 nn->name, nn->value.value.integer32);
2282 } else {
2283 smiAsprintf(&s, "%s", nn->name);
2284 }
2285 } else {
2286 smiAsprintf(&s, "%ld", smiValuePtr->value.integer32);
2287 }
2288 } else {
2289 smiAsprintf(&s, "%ld", smiValuePtr->value.integer32);
2290 }
2291 break;
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)
2300 break;
2301 }
2302 }
2303 ss = s;
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);
2308 } else if (nn) {
2309 smiAsprintf(&s, "%s%s%s",
2310 ss, strlen(ss) ? " " : "", nn->name);
2311 } else {
2312 smiAsprintf(&s, "%s%s%d",
2313 ss, strlen(ss) ? " " : "", i);
2314 }
2315 smiFree(ss);
2316 }
2317 }
2318 break;
2319 case SMI_BASETYPE_FLOAT32:
2320 case SMI_BASETYPE_FLOAT64:
2321 case SMI_BASETYPE_FLOAT128:
2322 case SMI_BASETYPE_UNKNOWN:
2323 default:
2324 if (flags & SMI_RENDER_UNKNOWN) {
2325 smiAsprintf(&s, SMI_UNKNOWN_LABEL);
2326 } else {
2327 s = NULL;
2328 }
2329 break;
2330 }
2331
2332 return s;
2333 }
2334
smiRenderNode(SmiNode * smiNodePtr,int flags)2335 char *smiRenderNode(SmiNode *smiNodePtr, int flags)
2336 {
2337 char *s;
2338 SmiModule *modulePtr;
2339
2340 if ((!smiNodePtr) || (smiNodePtr->name == NULL)) {
2341 if (flags & SMI_RENDER_UNKNOWN) {
2342 smiAsprintf(&s, SMI_UNKNOWN_LABEL);
2343 } else {
2344 s = NULL;
2345 }
2346 } else {
2347 modulePtr = smiGetNodeModule(smiNodePtr);
2348 if ((!(flags & SMI_RENDER_QUALIFIED)) ||
2349 (!modulePtr) ||
2350 (!strlen(modulePtr->name))) {
2351 smiAsprintf(&s, "%s", smiNodePtr->name);
2352 } else {
2353 smiAsprintf(&s, "%s::%s", modulePtr->name, smiNodePtr->name);
2354 }
2355 }
2356 return s;
2357 }
2358
2359
2360
smiRenderType(SmiType * smiTypePtr,int flags)2361 char *smiRenderType(SmiType *smiTypePtr, int flags)
2362 {
2363 char *s;
2364 SmiModule *modulePtr;
2365
2366 if ((!smiTypePtr) || (smiTypePtr->name == NULL)) {
2367 if (flags & SMI_RENDER_UNKNOWN) {
2368 smiAsprintf(&s, SMI_UNKNOWN_LABEL);
2369 } else {
2370 s = NULL;
2371 }
2372 } else {
2373 modulePtr = smiGetTypeModule(smiTypePtr);
2374 if ((!(flags & SMI_RENDER_QUALIFIED)) ||
2375 (!modulePtr) ||
2376 (!strlen(modulePtr->name))) {
2377 smiAsprintf(&s, "%s", smiTypePtr->name);
2378 } else {
2379 smiAsprintf(&s, "%s::%s", modulePtr->name, smiTypePtr->name);
2380 }
2381 }
2382 return s;
2383 }
2384
2385
2386
smiGetMinSize(SmiType * smiType)2387 unsigned int smiGetMinSize(SmiType *smiType)
2388 {
2389 SmiRange *smiRange;
2390 SmiType *parentType;
2391 unsigned int min = 65535, size;
2392
2393 switch (smiType->basetype) {
2394 case SMI_BASETYPE_BITS:
2395 return 0;
2396 case SMI_BASETYPE_OCTETSTRING:
2397 case SMI_BASETYPE_OBJECTIDENTIFIER:
2398 size = 0;
2399 break;
2400 default:
2401 return 0;
2402 }
2403
2404 for (smiRange = smiGetFirstRange(smiType);
2405 smiRange ; smiRange = smiGetNextRange(smiRange)) {
2406 if (smiRange->minValue.value.unsigned32 < min) {
2407 min = smiRange->minValue.value.unsigned32;
2408 }
2409 }
2410 if (min < 65535 && min > size) {
2411 size = min;
2412 }
2413
2414 parentType = smiGetParentType(smiType);
2415 if (parentType) {
2416 unsigned int psize = smiGetMinSize(parentType);
2417 if (psize > size) {
2418 size = psize;
2419 }
2420 }
2421
2422 return size;
2423 }
2424
2425
2426
smiGetMaxSize(SmiType * smiType)2427 unsigned int smiGetMaxSize(SmiType *smiType)
2428 {
2429 SmiRange *smiRange;
2430 SmiType *parentType;
2431 SmiNamedNumber *nn;
2432 unsigned int max = 0, size;
2433
2434 switch (smiType->basetype) {
2435 case SMI_BASETYPE_BITS:
2436 case SMI_BASETYPE_OCTETSTRING:
2437 size = 65535;
2438 break;
2439 case SMI_BASETYPE_OBJECTIDENTIFIER:
2440 size = 128;
2441 break;
2442 default:
2443 return 0xffffffff;
2444 }
2445
2446 if (smiType->basetype == SMI_BASETYPE_BITS) {
2447 for (nn = smiGetFirstNamedNumber(smiType);
2448 nn;
2449 nn = smiGetNextNamedNumber(nn)) {
2450 if (nn->value.value.unsigned32 > max) {
2451 max = nn->value.value.unsigned32;
2452 }
2453 }
2454 size = (max / 8) + 1;
2455 return size;
2456 }
2457
2458 for (smiRange = smiGetFirstRange(smiType);
2459 smiRange ; smiRange = smiGetNextRange(smiRange)) {
2460 if (smiRange->maxValue.value.unsigned32 > max) {
2461 max = smiRange->maxValue.value.unsigned32;
2462 }
2463 }
2464 if (max > 0 && max < size) {
2465 size = max;
2466 }
2467
2468 parentType = smiGetParentType(smiType);
2469 if (parentType) {
2470 unsigned int psize = smiGetMaxSize(parentType);
2471 if (psize < size) {
2472 size = psize;
2473 }
2474 }
2475
2476 return size;
2477 }
2478
2479
2480
smiUnpack(SmiNode * row,SmiSubid * oid,unsigned int oidlen,SmiValue ** vals,int * valslen)2481 int smiUnpack(SmiNode *row, SmiSubid *oid, unsigned int oidlen,
2482 SmiValue **vals, int *valslen)
2483 {
2484 SmiNode *indexNode = NULL;
2485 SmiElement *smiElement;
2486 SmiNode *iNode;
2487 SmiType *iType;
2488 int i, j, last = 0;
2489
2490 if (!vals || !valslen || !row || !oid) {
2491 return 0;
2492 }
2493
2494 switch (row->indexkind) {
2495 case SMI_INDEX_INDEX:
2496 case SMI_INDEX_REORDER:
2497 indexNode = row;
2498 break;
2499 case SMI_INDEX_EXPAND: /* TODO: we have to do more work here! */
2500 indexNode = NULL;
2501 break;
2502 case SMI_INDEX_AUGMENT:
2503 case SMI_INDEX_SPARSE:
2504 indexNode = smiGetRelatedNode(row);
2505 break;
2506 case SMI_INDEX_UNKNOWN:
2507 indexNode = NULL;
2508 break;
2509 }
2510
2511 *valslen = 0;
2512 for (smiElement = smiGetFirstElement(indexNode);
2513 smiElement; smiElement = smiGetNextElement(smiElement)) {
2514 iNode = smiGetElementNode(smiElement);
2515 if (iNode) {
2516 iType = smiGetNodeType(iNode);
2517 if (! iType) break;
2518 (*valslen)++;
2519 }
2520 }
2521 if (smiElement) {
2522 return 0;
2523 }
2524
2525 *vals = smiMalloc(*valslen * sizeof(SmiValue));
2526
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++;
2538 break;
2539 case SMI_BASETYPE_UNSIGNED32:
2540 (*vals)[i].value.unsigned32 = oid[j]; j++;
2541 break;
2542 case SMI_BASETYPE_OCTETSTRING:
2543 /* need to know whether implied/fixed length or not */
2544 break;
2545 case SMI_BASETYPE_OBJECTIDENTIFIER:
2546 /* need to know whether implied/fixed length or not */
2547 break;
2548 default:
2549 return 0;
2550 }
2551 }
2552
2553 return *valslen;
2554 }
2555
2556
2557
smiAsprintf(char ** strp,const char * format,...)2558 int smiAsprintf(char **strp, const char *format, ...)
2559 {
2560 int rc;
2561 va_list ap;
2562
2563 va_start(ap, format);
2564 rc = vasprintf(strp, format, ap);
2565 va_end(ap);
2566 if (! strp) {
2567 smiPrintError(NULL, ERR_OUT_OF_MEMORY);
2568 }
2569 return rc;
2570 }
2571
2572
2573
smiVasprintf(char ** strp,const char * format,va_list ap)2574 int smiVasprintf(char **strp, const char *format, va_list ap)
2575 {
2576 int rc;
2577
2578 rc = vasprintf(strp, format, ap);
2579 if (! strp) {
2580 smiPrintError(NULL, ERR_OUT_OF_MEMORY);
2581 }
2582 return rc;
2583 }
2584
2585
smiGetMinMaxRange(SmiType * smiType,SmiValue * min,SmiValue * max)2586 int smiGetMinMaxRange(SmiType *smiType, SmiValue *min, SmiValue *max)
2587 {
2588 SmiBasetype basetype = SMI_BASETYPE_UNKNOWN;
2589 SmiRange *range;
2590
2591 min->basetype = max->basetype = SMI_BASETYPE_UNKNOWN;
2592 min->len = max->len = 0;
2593
2594 range = smiGetFirstRange(smiType);
2595 if (!range) {
2596 return 0;
2597 }
2598
2599 basetype = range->minValue.basetype;
2600 min->basetype = max->basetype = basetype;
2601
2602 switch (basetype) {
2603 case SMI_BASETYPE_INTEGER32:
2604 min->value.integer32 = SMI_BASETYPE_INTEGER32_MAX;
2605 max->value.integer32 = SMI_BASETYPE_INTEGER32_MIN;
2606 break;
2607 case SMI_BASETYPE_INTEGER64:
2608 min->value.integer64 = SMI_BASETYPE_INTEGER64_MAX;
2609 max->value.integer64 = SMI_BASETYPE_INTEGER64_MIN;
2610 break;
2611 case SMI_BASETYPE_UNSIGNED32:
2612 min->value.unsigned32 = SMI_BASETYPE_UNSIGNED32_MAX;
2613 max->value.unsigned32 = SMI_BASETYPE_UNSIGNED32_MIN;
2614 break;
2615 case SMI_BASETYPE_UNSIGNED64:
2616 min->value.unsigned64 = SMI_BASETYPE_UNSIGNED64_MAX;
2617 max->value.unsigned64 = SMI_BASETYPE_UNSIGNED32_MIN;
2618 break;
2619 default:
2620 fprintf(stderr, "smidump: unexpected basetype %d\n", basetype);
2621 return -1;
2622 }
2623
2624 for (range = smiGetFirstRange(smiType);
2625 range;
2626 range = smiGetNextRange(range)) {
2627 switch (basetype) {
2628 case SMI_BASETYPE_INTEGER32:
2629 if (range->minValue.value.integer32 < min->value.integer32) {
2630 min->value.integer32 = range->minValue.value.integer32;
2631 }
2632 if (range->maxValue.value.integer32 > max->value.integer32) {
2633 max->value.integer32 = range->maxValue.value.integer32;
2634 }
2635 break;
2636 case SMI_BASETYPE_INTEGER64:
2637 if (range->minValue.value.integer64 < min->value.integer64) {
2638 min->value.integer64 = range->minValue.value.integer64;
2639 }
2640 if (range->maxValue.value.integer64 > max->value.integer64) {
2641 max->value.integer64 = range->maxValue.value.integer64;
2642 }
2643 break;
2644 case SMI_BASETYPE_UNSIGNED32:
2645 if (range->minValue.value.unsigned32 < min->value.unsigned32) {
2646 min->value.unsigned32 = range->minValue.value.unsigned32;
2647 }
2648 if (range->maxValue.value.unsigned32 > max->value.unsigned32) {
2649 max->value.unsigned32 = range->maxValue.value.unsigned32;
2650 }
2651 break;
2652 case SMI_BASETYPE_UNSIGNED64:
2653 if (range->minValue.value.unsigned64 < min->value.unsigned64) {
2654 min->value.unsigned64 = range->minValue.value.unsigned64;
2655 }
2656 if (range->maxValue.value.unsigned64 > max->value.unsigned64) {
2657 max->value.unsigned64 = range->maxValue.value.unsigned64;
2658 }
2659 break;
2660 default:
2661 fprintf(stderr, "smidump: unexpected basetype %d\n", basetype);
2662 return -1;
2663 }
2664 }
2665
2666 return 0;
2667 }
2668