1 /*
2  * dump-corba.c --
3  *
4  *      Operations to dump CORBA IDL and OID definitions. This is based
5  *	on the JIDM Specification Translation developed by the JIDM task
6  *	force, published as Open Group <URL:http://www.opengroup.org/>
7  *	document C802 (ISBN 1-85912-256-6, January 2000).
8  *
9  * Copyright (c) 1999 Frank Strauss, Technical University of Braunschweig.
10  * Copyright (c) 1999 J. Schoenwaelder, Technical University of Braunschweig.
11  *
12  * See the file "COPYING" for information on usage and redistribution
13  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14  *
15  * @(#) $Id: dump-corba.c 8090 2008-04-18 12:56:29Z strauss $
16  */
17 
18 #include <config.h>
19 
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <string.h>
24 #include <ctype.h>
25 #include <time.h>
26 #ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29 #ifdef HAVE_WIN_H
30 #include "win.h"
31 #endif
32 
33 #include "smi.h"
34 #include "smidump.h"
35 
36 
37 
38 #define  INDENT		4    /* indent factor */
39 #define  INDENTVALUE	20   /* column to start values, except multiline */
40 #define  INDENTTEXTS	13   /* column to start multiline texts */
41 #define  INDENTMAX	72   /* max column to fill, break lines otherwise */
42 
43 
44 static int current_column = 0;
45 
46 static int silent = 0;
47 
48 
49 /*
50  * The following list of IDL keywords is taken from the CORBA
51  * 2.3.1 IDL specification section 3.2.4 (October 1999).
52  */
53 
54 
55 static char *idlKeywords[] = {
56     "abstract",
57     "any",		"attribute",	"boolean",	"case",
58     "char",		"const",	"context",	"custom",
59     "default",		"double",	"enum",		"exception",
60     "factory",		"FALSE",	"fixed",	"float",
61     "in",		"inout",	"interface",	"long",
62     "module",		"native",	"object",	"octet",
63     "oneway",		"out",		"private",	"public",
64     "raises",		"readonly",	"sequence",	"short",
65     "string",		"struct",	"supports",	"switch",
66     "TRUE",		"truncatable",	"typedef",	"unsigned",
67     "union",		"valuebase",	"valuetype",	"void",
68     "wchar",		"wstring",	NULL
69 };
70 
71 
72 /*
73  * Structure used to build a list of imported types.
74  */
75 
76 
77 typedef struct Import {
78     char          *module;
79     char          *name;
80     struct Import *nextPtr;
81 } Import;
82 
83 static Import *importList = NULL;
84 
85 
86 /*
87  * Structure used to build dictionaries that translate names
88  * into IDL names following the generic JIDM rules.
89  */
90 
91 
92 typedef struct IdlEntry {
93     char            *module;
94     char            *name;
95     char            *idlname;
96     struct IdlEntry *nextPtr;
97 } IdlEntry;
98 
99 static IdlEntry *idlModuleNameList = NULL;
100 static IdlEntry *idlNodeNameList = NULL;
101 static IdlEntry *idlTypeNameList = NULL;
102 static IdlEntry *idlVBTypeNameList = NULL;
103 
104 static IdlEntry **idlNameLists[] = {
105     &idlModuleNameList, &idlNodeNameList,
106     &idlTypeNameList, &idlVBTypeNameList,
107     NULL
108 };
109 
110 
111 
createFile(char * name,char * suffix)112 static FILE * createFile(char *name, char *suffix)
113 {
114     char *fullname;
115     FILE *f;
116 
117     fullname = xmalloc(strlen(name) + (suffix ? strlen(suffix) : 0) + 2);
118     strcpy(fullname, name);
119     if (suffix) {
120         strcat(fullname, suffix);
121     }
122     if (!access(fullname, R_OK)) {
123         fprintf(stderr, "smidump: %s already exists\n", fullname);
124         xfree(fullname);
125         return NULL;
126     }
127     f = fopen(fullname, "w");
128     if (!f) {
129         fprintf(stderr, "smidump: cannot open %s for writing: ", fullname);
130         perror(NULL);
131         xfree(fullname);
132         exit(1);
133     }
134     xfree(fullname);
135     return f;
136 }
137 
138 
139 
dictFindName(IdlEntry * list,char * module,char * name)140 static char* dictFindName(IdlEntry *list, char *module, char* name)
141 {
142     IdlEntry *p;
143 
144     for (p = list; p; p = p->nextPtr) {
145 	if (! strcasecmp(p->module, module)
146 	    && ((! p->name && ! name) || ! strcasecmp(p->name, name))) {
147 	    return p->idlname;
148 	}
149     }
150 
151     return NULL;
152 }
153 
154 
155 
dictAddName(IdlEntry ** listPtr,char * module,char * name)156 static char* dictAddName(IdlEntry **listPtr, char *module, char *name)
157 {
158     IdlEntry *p;
159     char *s, *idl;
160     int i;
161 
162     /*
163      * Create a new IDL identifier by translating hyphens
164      * to underscores.
165      */
166 
167     s = name ? name : module;
168     idl = xmalloc(strlen(s) + 1);
169     for (i = 0; s[i]; i++) {
170 	idl[i] = (s[i] == '-') ? '_' : s[i];
171     }
172     idl[i] = 0;
173 
174     /*
175      * Check for any collisions with IDL keywords or previously
176      * created IDL identifiers.
177      */
178 
179     for (i = 0; idlKeywords[i]; i++) {
180 	if (! strcasecmp(idlKeywords[i], idl)) {
181 	    fprintf(stderr, "smidump: "
182 		    "`%s' (%s%s%s) collides with IDL keyword `%s'\n",
183 		    idl, module, name ? "::" : "", name ? name : "",
184 		    idlKeywords[i]);
185 	}
186     }
187 
188     for (i = 0; idlNameLists[i]; i++) {
189 	IdlEntry *list = *(idlNameLists[i]);
190 	for (p = list; p; p = p->nextPtr) {
191 	    if (! strcasecmp(p->idlname, idl)) {
192 		fprintf(stderr, "smidump: "
193 			"`%s' (%s%s%s) collides with `%s' (%s%s%s)\n",
194 			idl, module,
195 			name ? "::" : "", name ? name : "",
196 			p->idlname, p->module,
197 			p->name ? "::" : "", p->name ? p->name : "");
198 	    }
199 	}
200     }
201 
202     /*
203      * Safe the translated identifier in the dictionary.
204      */
205 
206     p = xmalloc(sizeof(IdlEntry));
207     p->module = xstrdup(module);
208     p->name = name ? xstrdup(name) : NULL;
209     p->idlname = idl;
210     p->nextPtr = *listPtr;
211     *listPtr = p;
212 
213     return idl;
214 }
215 
216 
217 
dictFree(IdlEntry ** list)218 static void dictFree(IdlEntry **list)
219 {
220     IdlEntry *p, *q;
221 
222     for (p = *list; p; ) {
223 	q = p;
224 	p = p->nextPtr;
225 	xfree(q->module);
226 	if (q->name) xfree(q->name);
227 	xfree(q->idlname);
228 	xfree(q);
229     }
230 
231     *list = NULL;
232 }
233 
234 
235 
getIdlModuleName(char * module)236 static char* getIdlModuleName(char *module)
237 {
238     char *s;
239 
240     s = dictFindName(idlModuleNameList, module, NULL);
241     if (! s) {
242 	s = dictAddName(&idlModuleNameList, module, NULL);
243     }
244     return s;
245 }
246 
247 
248 
getIdlNodeName(char * module,char * name)249 static char *getIdlNodeName(char *module, char *name)
250 {
251     char *s;
252     s = dictFindName(idlNodeNameList, module, name);
253     if (! s) {
254 	s = dictAddName(&idlNodeNameList, module, name);
255     }
256     return s;
257 }
258 
259 
260 
getIdlTypeName(char * module,char * name)261 static char* getIdlTypeName(char *module, char *name)
262 {
263     char *s, *type_name;
264 
265     type_name = xmalloc(strlen(name) + 10);
266     sprintf(type_name, "%sType", name);
267     type_name[0] = toupper((int) type_name[0]);
268 
269     s = dictFindName(idlTypeNameList, module, type_name);
270     if (! s) {
271 	s = dictAddName(&idlTypeNameList, module, type_name);
272     }
273 
274     xfree(type_name);
275     return s;
276 }
277 
278 
279 
getIdlVBTypeName(char * module,char * name,int * isnew)280 static char* getIdlVBTypeName(char *module, char *name, int *isnew)
281 {
282     char *s, *vbTypeName;
283 
284     vbTypeName = xmalloc(strlen(name) + 10);
285     sprintf(vbTypeName, "%sVBType", name);
286     vbTypeName[0] = toupper((int) vbTypeName[0]);
287 
288     if (isnew) {
289 	*isnew = 0;
290     }
291     s = dictFindName(idlVBTypeNameList, module, vbTypeName);
292     if (! s) {
293 	if (isnew) {
294 	    *isnew = 1;
295 	}
296 	s = dictAddName(&idlVBTypeNameList, module, vbTypeName);
297     }
298 
299     xfree(vbTypeName);
300     return s;
301 }
302 
303 
304 
current(SmiStatus status)305 static int current(SmiStatus status)
306 {
307     switch (status) {
308     case SMI_STATUS_CURRENT:
309     case SMI_STATUS_UNKNOWN:
310     case SMI_STATUS_MANDATORY:
311     case SMI_STATUS_OPTIONAL:
312 	return 1;
313     default:
314 	return 0;
315     }
316 }
317 
318 
319 
getTimeString(time_t t)320 static char *getTimeString(time_t t)
321 {
322     static char   *s = NULL;
323     struct tm	  *tm;
324 
325     if (s) xfree(s);
326 
327     tm = gmtime(&t);
328     smiAsprintf(&s, "%04d%02d%02d%02d%02dZ",
329 		tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
330 		tm->tm_hour, tm->tm_min);
331     return s;
332 }
333 
334 
335 
getAccessString(SmiAccess access,int create)336 static char *getAccessString(SmiAccess access, int create)
337 {
338     if (create && (access == SMI_ACCESS_READ_WRITE)) {
339 	return "read-create";
340     } else {
341 	return
342 	    (access == SMI_ACCESS_NOT_ACCESSIBLE) ? "not-accessible" :
343 	    (access == SMI_ACCESS_NOTIFY)         ? "accessible-for-notify" :
344 	    (access == SMI_ACCESS_READ_ONLY)      ? "read-only" :
345 	    (access == SMI_ACCESS_READ_WRITE)     ? "read-write" :
346 					            "<unknown>";
347     }
348 }
349 
350 
351 
getBaseTypeString(SmiBasetype basetype)352 static char *getBaseTypeString(SmiBasetype basetype)
353 {
354     switch(basetype) {
355     case SMI_BASETYPE_UNKNOWN:
356 	return "ASN1_Null";
357     case SMI_BASETYPE_POINTER:
358 	return "ASN1_Null";
359     case SMI_BASETYPE_INTEGER32:
360     case SMI_BASETYPE_ENUM:
361 	return "ASN1_Integer";
362     case SMI_BASETYPE_OCTETSTRING:
363     case SMI_BASETYPE_BITS:
364 	return "ASN1_OctetString";
365     case SMI_BASETYPE_OBJECTIDENTIFIER:
366 	return "ASN1_ObjectIdentifier";
367     case SMI_BASETYPE_UNSIGNED32:
368 	return "ASN1_Unsigned";
369     case SMI_BASETYPE_INTEGER64:
370 	return "ASN1_Integer64";
371     case SMI_BASETYPE_UNSIGNED64:
372 	return "ASN1_Unsigned64";
373     case SMI_BASETYPE_FLOAT32:
374     case SMI_BASETYPE_FLOAT64:
375     case SMI_BASETYPE_FLOAT128:
376 	return "ASN1_Real";
377     }
378 
379     return NULL;
380 }
381 
382 
getIdlAnyTypeName(SmiNode * smiNode,SmiType * smiType)383 static char *getIdlAnyTypeName(SmiNode *smiNode, SmiType *smiType)
384 {
385     SmiModule *smiModule;
386     char *typeName;
387 
388     if (! smiType->name) {
389 	smiModule = smiGetNodeModule(smiNode);
390 	if (smiModule && strlen(smiModule->name)) {
391 	    typeName = getIdlTypeName(smiModule->name, smiNode->name);
392 	} else {
393 	    typeName = getBaseTypeString(smiType->basetype);
394 	}
395     } else {
396 	smiModule = smiGetTypeModule(smiType);
397 	if (smiModule && strlen(smiModule->name)) {
398 	    typeName = getIdlTypeName(smiModule->name, smiType->name);
399 	} else {
400 	    typeName = getBaseTypeString(smiType->basetype);
401 	}
402     }
403 
404     return typeName;
405 }
406 
407 
getValueString(SmiValue * valuePtr,SmiType * typePtr)408 static char *getValueString(SmiValue *valuePtr, SmiType *typePtr)
409 {
410     static char    s[1024];
411     char           ss[9];
412     int		   n;
413     unsigned int   i;
414     SmiNamedNumber *nn;
415     SmiNode        *nodePtr;
416 
417     s[0] = 0;
418 
419     switch (valuePtr->basetype) {
420     case SMI_BASETYPE_UNSIGNED32:
421 	sprintf(s, "%lu", valuePtr->value.unsigned32);
422 	break;
423     case SMI_BASETYPE_INTEGER32:
424 	sprintf(s, "%ld", valuePtr->value.integer32);
425 	break;
426     case SMI_BASETYPE_UNSIGNED64:
427 	sprintf(s, UINT64_FORMAT, valuePtr->value.unsigned64);
428 	break;
429     case SMI_BASETYPE_INTEGER64:
430 	sprintf(s, INT64_FORMAT, valuePtr->value.integer64);
431 	break;
432     case SMI_BASETYPE_FLOAT32:
433     case SMI_BASETYPE_FLOAT64:
434     case SMI_BASETYPE_FLOAT128:
435 	break;
436     case SMI_BASETYPE_ENUM:
437 	for (nn = smiGetFirstNamedNumber(typePtr); nn;
438 	     nn = smiGetNextNamedNumber(nn)) {
439 	    if (nn->value.value.unsigned32 == valuePtr->value.unsigned32)
440 		break;
441 	}
442 	if (nn) {
443 	    sprintf(s, "%s", nn->name);
444 	} else {
445 	    sprintf(s, "%ld", valuePtr->value.integer32);
446 	}
447 	break;
448     case SMI_BASETYPE_OCTETSTRING:
449 	for (i = 0; i < valuePtr->len; i++) {
450 	    if (!isprint((int)valuePtr->value.ptr[i])) break;
451 	}
452 	if (i == valuePtr->len) {
453 	    sprintf(s, "\"%s\"", valuePtr->value.ptr);
454 	} else {
455             sprintf(s, "'%*s'H", 2 * valuePtr->len, "");
456             for (i=0; i < valuePtr->len; i++) {
457                 sprintf(ss, "%02x", valuePtr->value.ptr[i]);
458                 strncpy(&s[1+2*i], ss, 2);
459             }
460 	}
461 	break;
462     case SMI_BASETYPE_BITS:
463 	sprintf(s, "{");
464 	for (i = 0, n = 0; i < valuePtr->len * 8; i++) {
465 	    if (valuePtr->value.ptr[i/8] & (1 << (7-(i%8)))) {
466 		for (nn = smiGetFirstNamedNumber(typePtr); nn;
467 		     nn = smiGetNextNamedNumber(nn)) {
468 		    if (nn->value.value.unsigned32 == i)
469 			break;
470 		}
471 		if (nn) {
472 		    if (n)
473 			sprintf(&s[strlen(s)], ", ");
474 		    n++;
475 		    sprintf(&s[strlen(s)], "%s", nn->name);
476 		}
477 	    }
478 	}
479 	sprintf(&s[strlen(s)], "}");
480 	break;
481     case SMI_BASETYPE_UNKNOWN:
482 	break;
483     case SMI_BASETYPE_POINTER:
484 	break;
485     case SMI_BASETYPE_OBJECTIDENTIFIER:
486 	/* TODO */
487 	nodePtr = smiGetNodeByOID(valuePtr->len, valuePtr->value.oid);
488 	if (nodePtr) {
489 	    sprintf(s, "%s", nodePtr->name);
490 	} else {
491 	    strcpy(s, "{");
492 	    for (i=0; i < valuePtr->len; i++) {
493 		if (i) strcat(s, " ");
494 		sprintf(&s[strlen(s)], "%u", valuePtr->value.oid[i]);
495 	    }
496 	    strcat(s, "}");
497 	}
498 	break;
499     }
500 
501     return s;
502 }
503 
504 
505 
addImport(char * module,char * name)506 static Import* addImport(char *module, char *name)
507 {
508     Import **import, *newImport;
509 
510     for (import = &importList; *import; import = &(*import)->nextPtr) {
511 	int c = strcmp((*import)->module, module);
512 	if (c < 0) continue;
513 	if (c == 0) {
514 	    int d = strcmp((*import)->name, name);
515 	    if (d < 0) continue;
516 	    if (d == 0) return *import;
517 	    if (d > 0) break;
518 	}
519 	if (c > 0) break;
520     }
521 
522     newImport = xmalloc(sizeof(Import));
523     newImport->module = module;
524     newImport->name = name;
525     newImport->nextPtr = *import;
526     *import = newImport;
527 
528     return *import;
529 }
530 
531 
532 
createImportList(SmiModule * smiModule)533 static void createImportList(SmiModule *smiModule)
534 {
535     SmiNode     *smiNode;
536     SmiType     *smiType;
537     SmiModule   *smiTypeModule;
538     SmiElement  *smiElement;
539     SmiNode     *smiNodeIndex;
540     SmiNodekind kind = SMI_NODEKIND_SCALAR
541 	 | SMI_NODEKIND_COLUMN | SMI_NODEKIND_ROW;
542 
543     for (smiNode = smiGetFirstNode(smiModule, kind);
544 	 smiNode;
545 	 smiNode = smiGetNextNode(smiNode, kind)) {
546 
547 	 switch (smiNode->nodekind) {
548 	 case SMI_NODEKIND_ROW:
549 	      for (smiElement = smiGetFirstElement(smiNode); smiElement;
550 		   smiElement = smiGetNextElement(smiElement)) {
551 		   smiNodeIndex = smiGetElementNode(smiElement);
552 		  smiType = smiGetNodeType(smiNodeIndex);
553 		  if (smiType) {
554 		      smiTypeModule = smiGetTypeModule(smiType);
555 		      if (smiTypeModule &&
556 			  strcmp(smiTypeModule->name, smiModule->name)) {
557 			  if (strlen(smiTypeModule->name)) {
558 			      addImport(smiTypeModule->name, smiType->name);
559 			  }
560 		      }
561 		      if (smiType->basetype == SMI_BASETYPE_INTEGER32) {
562 			   addImport("SNMPv2-SMI", "Integer32");
563 		      }
564 		  }
565 	      }
566 	      break;
567 	 case SMI_NODEKIND_SCALAR:
568 	 case SMI_NODEKIND_COLUMN:
569 	      smiType = smiGetNodeType(smiNode);
570 	      if (smiType) {
571 		   smiTypeModule = smiGetTypeModule(smiType);
572 		   if (smiTypeModule &&
573 		       strcmp(smiTypeModule->name, smiModule->name)) {
574 			if (strlen(smiTypeModule->name)) {
575 			     addImport(smiTypeModule->name, smiType->name);
576 			}
577 		   }
578 		   if (smiType->basetype == SMI_BASETYPE_INTEGER32) {
579 			addImport("SNMPv2-SMI", "Integer32");
580 		   }
581 	      }
582 	      break;
583 	}
584     }
585 }
586 
587 
588 
freeImportList(void)589 static void freeImportList(void)
590 {
591     Import *import, *freeme;
592 
593     for (import = importList; import; ) {
594 	freeme = import;
595 	import = import->nextPtr;
596 	xfree(freeme);
597     }
598     importList = NULL;
599 }
600 
601 
602 
fprint(FILE * f,char * fmt,...)603 static void fprint(FILE *f, char *fmt, ...)
604 {
605     va_list ap;
606     char    *s;
607     char    *p;
608 
609     va_start(ap, fmt);
610     current_column += smiVasprintf(&s, fmt, ap);
611     va_end(ap);
612     fputs(s, f);
613     if ((p = strrchr(s, '\n'))) {
614         current_column = strlen(p) - 1;
615     }
616     free(s);
617 }
618 
619 
620 
fprintSegment(FILE * f,int column,char * string,int length)621 static void fprintSegment(FILE *f, int column, char *string, int length)
622 {
623     fprint(f, "%*c%s", column, ' ', string);
624     if (length) {
625 	fprint(f, "%*c", length - strlen(string) - column, ' ');
626     }
627 }
628 
629 
630 
fprintMultilineString(FILE * f,const char * s)631 static void fprintMultilineString(FILE *f, const char *s)
632 {
633     int i, len;
634 
635     fprintSegment(f, INDENTTEXTS - 1, "\"", 0);
636     if (s) {
637 	len = strlen(s);
638 	for (i=0; i < len; i++) {
639 	    putc(s[i], f);
640 	    current_column++;
641 	    if (s[i] == '\n') {
642 		current_column = 0;
643 		fprintSegment(f, INDENTTEXTS, "", 0);
644 	    }
645 	}
646     }
647     putc('\"', f);
648     current_column++;
649 }
650 
651 
652 
fprintMultiline(FILE * f,const char * s)653 static void fprintMultiline(FILE *f, const char *s)
654 {
655     int i, len;
656 
657     fprintSegment(f, INDENTTEXTS, "", 0);
658     if (s) {
659 	len = strlen(s);
660 	for (i=0; i < len; i++) {
661 	    putc(s[i], f);
662 	    current_column++;
663 	    if (s[i] == '\n') {
664 		current_column = 0;
665 		fprintSegment(f, INDENTTEXTS, "", 0);
666 	    }
667 	}
668     }
669     putc('\n', f);
670     current_column++;
671 }
672 
673 
674 
675 static char *
getStringTime(time_t t)676 getStringTime(time_t t)
677 {
678     static char   s[27];
679     struct tm	  *tm;
680 
681     tm = gmtime(&t);
682     sprintf(s, "%04d-%02d-%02d %02d:%02d",
683 	    tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
684 	    tm->tm_hour, tm->tm_min);
685     return s;
686 }
687 
688 
689 
690 static void
fprintCommentString(FILE * f,char * s)691 fprintCommentString(FILE *f, char *s)
692 {
693     int i, len;
694 
695     if (s) {
696 	fprintf(f, " *   ");
697 	len = strlen(s);
698 	for (i = 0; i < len; i++) {
699 	    fputc(s[i], f);
700 	    if (s[i] == '\n') {
701 		fprintf(f, " *   ");
702 	    }
703 	}
704 	fputc('\n', f);
705     }
706 }
707 
708 
709 
translate(char * s)710 static char* translate(char *s)
711 {
712     int i;
713 
714     s = xstrdup(s);
715     for (i = 0; s[i]; i++) {
716 	if (s[i] == '-') s[i] = '_';
717     }
718 
719     return s;
720 }
721 
722 
723 
isGroup(SmiNode * smiNode)724 static int isGroup(SmiNode *smiNode)
725 {
726     SmiNode *childNode;
727 
728     for (childNode = smiGetFirstChildNode(smiNode);
729 	 childNode;
730 	 childNode = smiGetNextChildNode(childNode)) {
731 	if ((childNode->nodekind == SMI_NODEKIND_SCALAR
732 	     || childNode->nodekind == SMI_NODEKIND_TABLE)
733 	    && current(childNode->status)) {
734 	    return 1;
735 	}
736     }
737 
738     return 0;
739 }
740 
741 
742 
isCreatable(SmiNode * smiNode)743 static int isCreatable(SmiNode *smiNode)
744 {
745     SmiNode *childNode;
746 
747     if ((isGroup(smiNode) || smiNode->nodekind == SMI_NODEKIND_ROW)
748 	&& current(smiNode->status)) {
749 
750 	for (childNode = smiGetFirstChildNode(smiNode);
751 	     childNode;
752 	     childNode = smiGetNextChildNode(childNode)) {
753 
754 	    if ((childNode->nodekind == SMI_NODEKIND_SCALAR
755 		 || childNode->nodekind == SMI_NODEKIND_COLUMN)
756 		&& current(childNode->status)
757 		&& childNode->access == SMI_ACCESS_READ_WRITE) {
758 		return 1;
759 	    }
760 	}
761     }
762 
763     return 0;
764 }
765 
766 
767 
fprintDescription(FILE * f,SmiNode * smiNode,int indent)768 static void fprintDescription(FILE *f, SmiNode *smiNode, int indent)
769 {
770     fprint(f, "\n");
771     fprintSegment(f, indent, "/*\n", 0);
772     if (smiNode->description) {
773 	fprintMultiline(f, smiNode->description);
774     }
775     if (smiNode->reference) {
776 	fprintSegment(f, indent, "REFERENCE:", 0);
777 	fprint(f, "\n");
778 	fprintMultilineString(f, smiNode->reference);
779 	fprint(f, "\n\n");
780     }
781     if (smiNode->units) {
782 	fprintSegment(f, indent, "UNITS:", 0);
783 	fprint(f, "\n");
784 	fprintMultilineString(f, smiNode->units);
785 	fprint(f, "\n\n");
786     }
787     fprintSegment(f, indent, "*/\n", 0);
788 }
789 
790 
791 
fprintIndex(FILE * f,SmiNode * indexNode)792 static void fprintIndex(FILE *f, SmiNode *indexNode)
793 {
794     SmiElement *smiElement;
795     int        j;
796 
797     for (j = 0, smiElement = smiGetFirstElement(indexNode);
798 	 smiElement;
799 	 j++, smiElement = smiGetNextElement(smiElement)) {
800 	if (j) {
801 	    fprint(f, " ");
802 	}
803 	fprint(f, smiGetElementNode(smiElement)->name);
804 	/* TODO: non-local name if non-local */
805     } /* TODO: empty? -> print error */
806 }
807 
808 
809 
fprintIncludes(FILE * f,SmiModule * smiModule)810 static void fprintIncludes(FILE *f, SmiModule *smiModule)
811 {
812     Import    *import;
813     char      *lastModulename = NULL;
814 
815     fprint(f, "#include <ASN1Types.idl>\n");
816     fprint(f, "#include <SNMPMgmt.idl>\n");
817 
818     for (import = importList; import; import = import->nextPtr) {
819 	if (!lastModulename
820 	    || strcmp(lastModulename, import->module)) {
821 	    fprint(f, "#include <%s.idl>\n",
822 		  getIdlModuleName(import->module));
823 	    lastModulename = import->module;
824 	}
825     }
826 
827     fprint(f, "\n");
828 }
829 
830 
831 
fprintImportedTypedefs(FILE * f,SmiModule * smiModule)832 static void fprintImportedTypedefs(FILE *f, SmiModule *smiModule)
833 {
834     Import    *import;
835     int	      cnt = 0;
836     char      *idlTypeName;
837 
838     for (import = importList; import; import = import->nextPtr) {
839 	cnt++;
840 	idlTypeName = getIdlTypeName(import->module, import->name);
841 	fprintSegment(f, INDENT, "typedef ", 0);
842 	fprint(f, "%s::%s %s;\n",
843 	      getIdlModuleName(import->module), idlTypeName, idlTypeName);
844     }
845 
846     if (cnt) {
847 	fprint(f, "\n");
848     }
849 }
850 
851 
852 
fprintModule(FILE * f,SmiModule * smiModule)853 static void fprintModule(FILE *f, SmiModule *smiModule)
854 {
855     SmiRevision  *smiRevision;
856     SmiNode      *smiNode;
857     char         *idlModuleName;
858 
859     smiNode = smiGetModuleIdentityNode(smiModule);
860 
861     if (smiNode) {
862 
863 	idlModuleName = getIdlModuleName(smiModule->name);
864 	fprintSegment(f, INDENT, "const ", 0);
865 	fprint(f, "string moduleIdentity = \"%s\";\n", smiNode->name);
866 	fprintSegment(f, INDENT, "const ", 0);
867 	fprint(f, "ASN1_ObjectIdentifier %s = \"::%s::%s\";\n\n",
868 	      getIdlModuleName(smiNode->name),
869 	      idlModuleName, smiNode->name);
870 	if (! silent) {
871 	    fprintSegment(f, INDENT, "/*\n", 0);
872 	    if (smiModule->description) {
873 		fprintMultiline(f, smiModule->description);
874 		fprint(f, "\n");
875 	    }
876 	    smiRevision = smiGetFirstRevision(smiModule);
877 	    fprintSegment(f, INDENT, "LAST-UPDATED:", INDENTVALUE);
878 	    fprint(f, smiRevision
879 		  ? getTimeString(smiRevision->date) : "197001010000Z");
880 	    fprint(f, "\n\n");
881 	    fprintSegment(f, INDENT, "ORGANIZATION:", 0);
882 	    fprint(f, "\n");
883 	    fprintMultilineString(f, smiModule->organization);
884 	    fprint(f, "\n\n");
885 	    fprintSegment(f, INDENT, "CONTACT-INFO:", 0);
886 	    fprint(f, "\n");
887 	    fprintMultilineString(f, smiModule->contactinfo);
888 	    fprint(f, "\n\n");
889 	    for (; smiRevision;
890 		 smiRevision = smiGetNextRevision(smiRevision)) {
891 		if (! smiRevision->description ||
892 		    strcmp(smiRevision->description,
893 			   "[Revision added by libsmi due to a LAST-UPDATED clause.]")) {
894 		    fprintSegment(f, INDENT, "REVISION:", INDENTVALUE);
895 		    fprint(f, "\"%s\"\n", getTimeString(smiRevision->date));
896 		    fprintSegment(f, INDENT, "REVISION-DESCRIPTION:", 0);
897 		    fprint(f, "\n");
898 		    if (smiRevision->description) {
899 			fprintMultilineString(f, smiRevision->description);
900 		    } else {
901 			fprintMultilineString(f, "...");
902 		    }
903 		    fprint(f, "\n\n");
904 		}
905 	    }
906 	    fprintSegment(f, INDENT, "*/", 0);
907 	    fprint(f, "\n\n");
908 	}
909     }
910 
911 }
912 
913 
914 
fprintType(FILE * f,SmiNode * smiNode,SmiType * smiType)915 static void fprintType(FILE *f, SmiNode *smiNode, SmiType *smiType)
916 {
917     SmiNamedNumber *nn;
918     char           *idlTypeName;
919     char           *nnName;
920     int            i;
921 
922     if (! silent) {
923 	if (smiType->name) {
924 	    fprintSegment(f, INDENT, "/*\n", 0);
925 	    if (smiType->description) {
926 		fprintMultiline(f, smiType->description);
927 	    }
928 	    if (smiType->reference) {
929 		fprintSegment(f, INDENT, "REFERENCE:", 0);
930 		fprint(f, "\n");
931 		fprintMultilineString(f, smiType->reference);
932 		fprint(f, "\n\n");
933 	    }
934 	    if (smiType->format) {
935 		fprintSegment(f, INDENT, "DISPLAY-HINT:", 0);
936 		fprint(f, " %s\n", smiType->format);
937 		fprint(f, "\n\n");
938 	    }
939 	    fprintSegment(f, INDENT, "*/\n", 0);
940 	}
941     }
942     if (! smiType->name) {
943 	idlTypeName = getIdlTypeName(smiGetNodeModule(smiNode)->name,
944 				     smiNode->name);
945     } else {
946 	idlTypeName = getIdlTypeName(smiGetTypeModule(smiType)->name,
947 				     smiType->name);
948     }
949     fprintSegment(f, INDENT, "typedef ", 0);
950     fprint(f, "%s %s; \n",
951 	  getBaseTypeString(smiType->basetype), idlTypeName);
952 
953     if (smiType->basetype == SMI_BASETYPE_ENUM) {
954 	for (nn = smiGetFirstNamedNumber(smiType);
955 	     nn;
956 	     nn = smiGetNextNamedNumber(nn)) {
957 	    fprintSegment(f, INDENT, "const ", 0);
958 	    nnName = translate(nn->name);
959 	    fprint(f, "%s %s_%s = %s;\n", idlTypeName, idlTypeName, nnName,
960 		  getValueString(&nn->value, smiType));
961 	    xfree(nnName);
962 	}
963 	fprintSegment(f, INDENT, "const string ", 0);
964 	fprint(f, "%s_NameNumberList = \"", idlTypeName);
965 	for (i = 0, nn = smiGetFirstNamedNumber(smiType);
966 	     nn;
967 	     i++, nn = smiGetNextNamedNumber(nn)) {
968 	    nnName = translate(nn->name);
969 	    if (i) {
970 		fprint(f, " , ");
971 	    }
972 	    fprint(f, "%s (%s)", nnName, getValueString(&nn->value, smiType));
973 	    xfree(nnName);
974 	}
975 	fprint(f, "\";\n");
976     }
977     fprint(f, "\n");
978 }
979 
980 
981 
fprintTypedefs(FILE * f,SmiModule * smiModule)982 static void fprintTypedefs(FILE *f, SmiModule *smiModule)
983 {
984     SmiNode        *smiNode;
985     SmiType        *smiType;
986     SmiNodekind    kind = SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN;
987 
988     for (smiType = smiGetFirstType(smiModule);
989 	 smiType;
990 	 smiType = smiGetNextType(smiType)) {
991 	if (current(smiType->status)) {
992 	    fprintType(f, NULL, smiType);
993 	}
994     }
995 
996     for (smiNode = smiGetFirstNode(smiModule, kind);
997 	 smiNode;
998 	 smiNode = smiGetNextNode(smiNode, kind)) {
999 	if (current(smiNode->status)) {
1000 	    smiType = smiGetNodeType(smiNode);
1001 	    if (smiType && ! smiType->name) {
1002 		fprintType(f, smiNode, smiType);
1003 	    }
1004 	}
1005     }
1006 }
1007 
1008 
1009 
fprintAttribute(FILE * f,SmiNode * smiNode)1010 static void fprintAttribute(FILE *f, SmiNode *smiNode)
1011 {
1012     char *idlTypeName = NULL, *idlNodeName;
1013     SmiType *smiType;
1014     SmiModule *smiModule;
1015 
1016     if (smiNode->access < SMI_ACCESS_READ_ONLY) {
1017 	return;
1018     }
1019 
1020     smiType = smiGetNodeType(smiNode);
1021     smiModule = smiGetNodeModule(smiNode);
1022 
1023     if (! smiType) {
1024 	return;
1025     }
1026 
1027     idlNodeName = getIdlNodeName(smiModule->name, smiNode->name);
1028     idlTypeName = getIdlAnyTypeName(smiNode, smiType);
1029     if (! silent) {
1030 	fprintDescription(f, smiNode, 2*INDENT);
1031     }
1032     fprintSegment(f, 2*INDENT,
1033 		 smiNode->access == SMI_ACCESS_READ_ONLY
1034 		 ? "readonly attribute" : "attribute", 0);
1035 
1036     fprint(f, " %s %s;\n", idlTypeName, idlNodeName);
1037 }
1038 
1039 
1040 
fprintGroupInterface(FILE * f,SmiNode * smiNode)1041 static void fprintGroupInterface(FILE *f, SmiNode *smiNode)
1042 {
1043     SmiNode *childNode;
1044     char *idlNodeName;
1045     SmiModule *smiModule, *childModule;
1046 
1047     smiModule = smiGetNodeModule(smiNode);
1048     idlNodeName = getIdlNodeName(smiModule->name, smiNode->name);
1049     fprintSegment(f, INDENT, "interface", 0);
1050     fprint(f, " %s : SNMPMgmt::SmiEntry {\n", idlNodeName);
1051 
1052     for (childNode = smiGetFirstChildNode(smiNode);
1053 	 childNode;
1054 	 childNode = smiGetNextChildNode(childNode)) {
1055 	if (childNode->nodekind == SMI_NODEKIND_TABLE
1056 	    && current(childNode->status)) {
1057 	    if (! silent) {
1058 		fprintDescription(f, childNode, 2*INDENT);
1059 	    }
1060 	    fprintSegment(f, 2*INDENT, "SNMPMgmt::SmiTableIterator", 0);
1061 	    childModule = smiGetNodeModule(childNode);
1062 	    fprint(f, " get_%s();\n", getIdlNodeName(childModule->name,
1063 						 childNode->name));
1064 	}
1065 	if (childNode->nodekind == SMI_NODEKIND_SCALAR
1066 	    && current(childNode->status)) {
1067 	    fprintAttribute(f, childNode);
1068 	}
1069     }
1070 
1071     fprintSegment(f, INDENT, "};\n\n", 0);
1072 }
1073 
1074 
1075 
fprintRowInterface(FILE * f,SmiNode * smiNode)1076 static void fprintRowInterface(FILE *f, SmiNode *smiNode)
1077 {
1078     SmiNode *childNode, *relatedNode;
1079     char *idlModuleName, *idlNodeName;
1080 
1081     idlNodeName = getIdlNodeName(smiGetNodeModule(smiNode)->name,
1082 				 smiNode->name);
1083     if (! silent) {
1084 	fprintDescription(f, smiNode, INDENT);
1085     }
1086     fprintSegment(f, INDENT, "interface", 0);
1087     if (smiNode->indexkind == SMI_INDEX_AUGMENT
1088 	|| smiNode->indexkind == SMI_INDEX_SPARSE) {
1089 	relatedNode = smiGetRelatedNode(smiNode);
1090 	idlModuleName = getIdlModuleName(smiGetNodeModule(relatedNode)->name);
1091 	fprint(f, " %s : %s::%s {\n", idlNodeName,
1092 	      idlModuleName, relatedNode->name);
1093     } else {
1094 	fprint(f, " %s : SNMPMgmt::SmiEntry {\n", idlNodeName);
1095     }
1096 
1097     if (smiNode->indexkind == SMI_INDEX_INDEX
1098 	|| smiNode->indexkind == SMI_INDEX_REORDER) {
1099 	fprint(f, "\n");
1100 	fprintSegment(f, 2*INDENT, "const ", 0);
1101 	fprint(f, "string IndexVarList = \"");
1102 	fprintIndex(f, smiNode);
1103 	fprint(f, "\";\n");
1104     }
1105 
1106     /* SMI_INDEX_EXPAND ? */
1107 
1108     for (childNode = smiGetFirstChildNode(smiNode);
1109 	 childNode;
1110 	 childNode = smiGetNextChildNode(childNode)) {
1111 	if (childNode->nodekind == SMI_NODEKIND_COLUMN
1112 	    && current(childNode->status)) {
1113 	    fprintAttribute(f, childNode);
1114 	}
1115     }
1116 
1117     fprintSegment(f, INDENT, "};\n\n", 0);
1118 }
1119 
1120 
1121 
fprintInterfaces(FILE * f,SmiModule * smiModule)1122 static void fprintInterfaces(FILE *f, SmiModule *smiModule)
1123 {
1124     SmiNode *smiNode;
1125 
1126     for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
1127 	 smiNode;
1128 	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
1129 	if (isGroup(smiNode)) {
1130 	    fprintGroupInterface(f, smiNode);
1131 	}
1132 	if (smiNode->nodekind == SMI_NODEKIND_ROW
1133 	    && current(smiNode->status)) {
1134 	    fprintRowInterface(f, smiNode);
1135 	}
1136     }
1137 }
1138 
1139 
1140 
fprintConstructor(FILE * f,SmiNode * smiNode)1141 static void fprintConstructor(FILE *f, SmiNode *smiNode)
1142 {
1143     SmiNode *childNode;
1144     SmiNode *indexNode;
1145     SmiType *smiType;
1146     SmiModule *smiModule;
1147     SmiElement *smiElement = NULL;
1148     char    *idlNodeName;
1149     char    *idlChildNodeName, *idlChildTypeName;
1150     int	    cnt = 0;
1151 
1152     smiModule = smiGetNodeModule(smiNode);
1153     idlNodeName = getIdlNodeName(smiModule->name, smiNode->name);
1154 
1155     fprint(f, "\n");
1156     fprintSegment(f, 2*INDENT, "", 0);
1157     fprint(f, "%s create_%s (\n", idlNodeName, idlNodeName);
1158 
1159     /* First include the INDEXes as parameters to allow row creation
1160        for rows with not-accesible index objects. */
1161 
1162     if (smiNode->indexkind == SMI_INDEX_INDEX
1163 	|| smiNode->indexkind == SMI_INDEX_REORDER) {
1164 	 for (smiElement = smiGetFirstElement(smiNode);
1165 	      smiElement; smiElement = smiGetNextElement(smiElement)) {
1166 	      cnt++;
1167 	      indexNode = smiGetElementNode(smiElement);
1168 	      idlChildNodeName =
1169 		   getIdlNodeName(smiGetNodeModule(indexNode)->name,
1170 				  indexNode->name);
1171 	      smiType = smiGetNodeType(indexNode);
1172 	      idlChildTypeName = getIdlAnyTypeName(indexNode, smiType);
1173 	      if (cnt > 1) {
1174 		   fprint(f, ",\n");
1175 	      }
1176 	      fprintSegment(f, 3*INDENT, "in ", 0);
1177 	      fprint(f, "%s %s", idlChildTypeName, idlChildNodeName);
1178 	 }
1179     }
1180 
1181     for (childNode = smiGetFirstChildNode(smiNode);
1182 	 childNode;
1183 	 childNode = smiGetNextChildNode(childNode)) {
1184 
1185 	if ((childNode->nodekind == SMI_NODEKIND_SCALAR
1186 	     || childNode->nodekind == SMI_NODEKIND_COLUMN)
1187 	    && current(childNode->status)
1188 	    && childNode->access == SMI_ACCESS_READ_WRITE) {
1189 
1190 	    /* Test if this column is already used as parameter
1191 	       because it is an INDEX of the row. */
1192 
1193 	    if (childNode->nodekind == SMI_NODEKIND_SCALAR
1194 		|| childNode->nodekind == SMI_NODEKIND_COLUMN) {
1195 		for (smiElement = smiGetFirstElement(smiNode);
1196 		    smiElement; smiElement = smiGetNextElement(smiElement)) {
1197 		    indexNode = smiGetElementNode(smiElement);
1198 		    if (indexNode == childNode) {
1199 			break;
1200 		    }
1201 		}
1202 	    }
1203 
1204 	    if (! smiElement) {
1205 		cnt++;
1206 		idlChildNodeName =
1207 		    getIdlNodeName(smiGetNodeModule(childNode)->name,
1208 				   childNode->name);
1209 		smiType = smiGetNodeType(childNode);
1210 		idlChildTypeName = getIdlAnyTypeName(childNode, smiType);
1211 		if (cnt > 1) {
1212 		    fprint(f, ",\n");
1213 		}
1214 		fprintSegment(f, 3*INDENT, "in ", 0);
1215 		fprint(f, "%s %s", idlChildTypeName, idlChildNodeName);
1216 	    }
1217 	}
1218     }
1219     fprint(f, "\n");
1220 
1221     fprintSegment(f, 2*INDENT, ") raises (\n", 0);
1222     fprintSegment(f, 3*INDENT, "SNMPMgmt::AlreadyExists,\n", 0);
1223     fprintSegment(f, 3*INDENT, "CosLifeCycle::InvalidCriteria,\n", 0);
1224     fprintSegment(f, 3*INDENT, "CosLifeCycle::CannotMeetCriteria\n", 0);
1225     fprintSegment(f, 2*INDENT, ");\n", 0);
1226 }
1227 
1228 
1229 
fprintFactory(FILE * f,SmiModule * smiModule)1230 static void fprintFactory(FILE *f, SmiModule *smiModule)
1231 {
1232     SmiNode *smiNode;
1233     int	    cnt = 0;
1234 
1235     for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
1236 	 smiNode;
1237 	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
1238 
1239 	if (isCreatable(smiNode)) {
1240 	    cnt++;
1241 	    if (cnt == 1) {
1242 		fprintSegment(f, INDENT, "interface SmiEntryFactory : "
1243 			     "SNMPMgmt::GenericFactory {\n", 0);
1244 	    }
1245 	    fprintConstructor(f, smiNode);
1246 	}
1247     }
1248 
1249     if (cnt) {
1250 	fprintSegment(f, INDENT, "};\n\n", 0);
1251     }
1252 }
1253 
1254 
1255 
fprintNotificationVBTypes(FILE * f,SmiModule * smiModule)1256 static void fprintNotificationVBTypes(FILE *f, SmiModule *smiModule)
1257 {
1258     SmiNode     *smiNode, *listSmiNode;
1259     SmiElement  *smiElement;
1260     SmiType	*smiType;
1261     char	*idlTypeName;
1262     char	*idlVBTypeName;
1263     int		isnew;
1264 
1265     for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
1266 	 smiNode;
1267 	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) {
1268 
1269 	for (smiElement = smiGetFirstElement(smiNode);
1270 	     smiElement; smiElement = smiGetNextElement(smiElement)) {
1271 	    listSmiNode = smiGetElementNode(smiElement);
1272 	    idlVBTypeName = getIdlVBTypeName(
1273 		                           smiGetNodeModule(listSmiNode)->name,
1274 					   listSmiNode->name, &isnew);
1275 	    if (isnew && listSmiNode) {
1276 		smiType = smiGetNodeType(listSmiNode);
1277 		if (smiType) {
1278 		    idlTypeName = getIdlAnyTypeName(listSmiNode, smiType);
1279 		    fprintSegment(f, INDENT, "struct ", 0);
1280 		    fprint(f, "%s {\n", idlVBTypeName);
1281 		    fprintSegment(f, 2*INDENT, "string var_name;\n", 0);
1282 		    fprintSegment(f, 2*INDENT, "string var_index;\n", 0);
1283 		    fprintSegment(f, 2*INDENT, "", 0);
1284 		    fprint(f, "%s %s;\n", idlTypeName,
1285 			   smiGetElementNode(smiElement)->name);
1286 		    fprintSegment(f, INDENT, "};\n\n", 0);
1287 		}
1288 	    }
1289 	}
1290     }
1291 }
1292 
1293 
1294 
fprintNotificationTypes(FILE * f,SmiModule * smiModule)1295 static void fprintNotificationTypes(FILE *f, SmiModule *smiModule)
1296 {
1297     SmiNode     *smiNode;
1298     SmiElement  *smiElement;
1299     char	*idlTypeName;
1300     char	*idlVBTypeName;
1301 
1302     for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
1303 	 smiNode;
1304 	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) {
1305 
1306 	if ((smiElement = smiGetFirstElement(smiNode))) {
1307 	    idlTypeName = getIdlTypeName(smiGetNodeModule(smiNode)->name,
1308 					 smiNode->name);
1309 	    fprintSegment(f, INDENT, "struct ", 0);
1310 	    fprint(f, "%s {\n", idlTypeName);
1311 	    for (; smiElement; smiElement = smiGetNextElement(smiElement)) {
1312 		idlVBTypeName = getIdlVBTypeName(smiGetNodeModule(
1313 		                          smiGetElementNode(smiElement))->name,
1314 				    smiGetElementNode(smiElement)->name, NULL);
1315 		fprintSegment(f, 2*INDENT, "", 0);
1316 		fprint(f, "%s %s;\n", idlVBTypeName,
1317 		      smiGetElementNode(smiElement)->name);
1318 	    }
1319 	    fprintSegment(f, INDENT, "};\n\n", 0);
1320 	}
1321     }
1322 }
1323 
1324 
1325 
fprintPushNotifications(FILE * f,SmiModule * smiModule)1326 static void fprintPushNotifications(FILE *f, SmiModule *smiModule)
1327 {
1328     SmiNode     *smiNode;
1329     SmiElement  *smiElement;
1330     char        *idlNodeName;
1331     char	*idlTypeName;
1332     int         cnt = 0;
1333 
1334     for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
1335 	 smiNode;
1336 	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) {
1337 
1338 	cnt++;
1339 	if (cnt == 1) {
1340 	    if (! silent) {
1341 		fprintSegment(f, INDENT,
1342 			     "/* typed push event communication */\n", 0);
1343 	    }
1344 	    fprintSegment(f, INDENT, "interface Notifications : ", 0);
1345 	    fprint(f, "SNMPMgmt::Notifications {\n");
1346 	}
1347 	idlNodeName = getIdlNodeName(smiModule->name,
1348 				     smiNode->name);
1349 	if (! silent) {
1350 	    fprintDescription(f, smiNode, 2*INDENT);
1351 	}
1352 	fprintSegment(f, 2*INDENT, "void ", 0);
1353 	fprint(f, "%s (\n", idlNodeName);
1354 	fprintSegment(f, 3*INDENT, "in CosNaming::Name src_entry_name,\n", 0);
1355 	fprintSegment(f, 3*INDENT, "in CORBA::ScopedName event_type,\n", 0);
1356 	fprintSegment(f, 3*INDENT, "in ASN1_GeneralizedTime event_time", 0);
1357 	if ((smiElement = smiGetFirstElement(smiNode))) {
1358 	    idlTypeName = getIdlTypeName(smiModule->name, smiNode->name);
1359 	    fprint(f, ",\n");
1360 	    fprintSegment(f, 3*INDENT, "in ", 0);
1361 	    fprint(f, "%s notification_info", idlTypeName);
1362 	}
1363 	fprint(f, "\n");
1364 	fprintSegment(f, 2*INDENT, ");\n", 0);
1365     }
1366 
1367     if (cnt) {
1368 	fprintSegment(f, INDENT, "};\n\n", 0);
1369     }
1370 }
1371 
1372 
1373 
fprintPullNotifications(FILE * f,SmiModule * smiModule)1374 static void fprintPullNotifications(FILE *f, SmiModule *smiModule)
1375 {
1376     SmiNode     *smiNode;
1377     SmiElement  *smiElement;
1378     int         cnt = 0;
1379     char        *idlNodeName;
1380     char	*idlTypeName;
1381 
1382     for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
1383 	 smiNode;
1384 	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) {
1385 
1386 	cnt++;
1387 	if (cnt == 1) {
1388 	    if (! silent) {
1389 		fprintSegment(f, INDENT,
1390 			     "/* typed pull event communication */\n", 0);
1391 	    }
1392 	    fprintSegment(f, INDENT, "interface PullNotifications : ", 0);
1393 	    fprint(f, "SNMPMgmt::PullNotifications {\n");
1394 	}
1395 	idlNodeName = getIdlNodeName(smiModule->name, smiNode->name);
1396 
1397 	if (! silent) {
1398 	    fprintDescription(f, smiNode, 2*INDENT);
1399 	}
1400 	fprintSegment(f, 2*INDENT, "void ", 0);
1401 	fprint(f, "pull_%s (\n", idlNodeName);
1402 	fprintSegment(f, 3*INDENT, "out CosNaming::Name src_entry_name,\n", 0);
1403 	fprintSegment(f, 3*INDENT, "out CORBA::ScopedName event_type,\n", 0);
1404 	fprintSegment(f, 3*INDENT, "out ASN1_GeneralizedTime event_time", 0);
1405 	if ((smiElement = smiGetFirstElement(smiNode))) {
1406 	    idlTypeName = getIdlTypeName(smiModule->name, smiNode->name);
1407 	    fprint(f, ",\n");
1408 	    fprintSegment(f, 3*INDENT, "out ", 0);
1409 	    fprint(f, "%s notification_info", idlTypeName);
1410 	}
1411 	fprint(f, "\n");
1412 	fprintSegment(f, 2*INDENT, ");\n", 0);
1413 	fprintSegment(f, 2*INDENT, "boolean ", 0);
1414 	fprint(f, "try_%s (\n", idlNodeName);
1415 	fprintSegment(f, 3*INDENT, "out CosNaming::Name src_entry_name,\n", 0);
1416 	fprintSegment(f, 3*INDENT, "out CORBA::ScopedName event_type,\n", 0);
1417 	fprintSegment(f, 3*INDENT, "out ASN1_GeneralizedTime event_time", 0);
1418 	if ((smiElement = smiGetFirstElement(smiNode))) {
1419 	    char *idlTypeName;
1420 	    idlTypeName = getIdlTypeName(smiModule->name, smiNode->name);
1421 	    fprint(f, ",\n");
1422 	    fprintSegment(f, 3*INDENT, "out ", 0);
1423 	    fprint(f, "%s notification_info", idlTypeName);
1424 	}
1425 	fprint(f, "\n");
1426 	fprintSegment(f, 2*INDENT, ");\n", 0);
1427     }
1428 
1429     if (cnt) {
1430 	fprintSegment(f, INDENT, "};\n\n", 0);
1431     }
1432 }
1433 
1434 
1435 
fprintDefVals(FILE * f,SmiModule * smiModule)1436 static void fprintDefVals(FILE *f, SmiModule *smiModule)
1437 {
1438     SmiNode *smiNode;
1439     SmiType *smiType;
1440     int     cnt = 0;
1441     char    *idlTypeName;
1442 
1443 
1444     for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
1445 	 smiNode;
1446 	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
1447 
1448 	if (smiNode->value.basetype != SMI_BASETYPE_UNKNOWN) {
1449 	    smiType = smiGetNodeType(smiNode);
1450 	    if (smiType) {
1451 		cnt++;
1452 		if (cnt == 1) {
1453 		    fprintSegment(f, INDENT, "/* pseudo */\n", 0);
1454 		    fprintSegment(f, INDENT, "interface DefaultValues {\n", 0);
1455 		}
1456 		if (! silent) {
1457 		    fprintSegment(f, 2*INDENT, "/* DEFVAL: ", 0);
1458 		    fprint(f, " %s */\n",
1459 			   getValueString(&smiNode->value, smiType));
1460 		}
1461 		fprintSegment(f, 2*INDENT, "", 0);
1462 		idlTypeName = getIdlAnyTypeName(smiNode, smiType);
1463 		fprint(f, "%s %s();\n\n", idlTypeName, smiNode->name);
1464 	    }
1465 	}
1466     }
1467 
1468     if (cnt) {
1469 	fprintSegment(f, INDENT, "};\n\n", 0);
1470     }
1471 }
1472 
1473 
1474 
fprintDisplayHints(FILE * f,SmiModule * smiModule)1475 static void fprintDisplayHints(FILE *f, SmiModule *smiModule)
1476 {
1477     SmiType *smiType;
1478     int     cnt = 0;
1479 
1480     for (smiType = smiGetFirstType(smiModule);
1481 	 smiType;
1482 	 smiType = smiGetNextType(smiType)) {
1483 	if (current(smiType->status) && smiType->format) {
1484 	    cnt++;
1485 	    if (cnt == 1) {
1486 		fprintSegment(f, INDENT, "/* pseudo */\n", 0);
1487 		fprintSegment(f, INDENT, "interface TextualConventions {\n", 0);
1488 	    }
1489 	    fprint(f, "\n");
1490 	    if (! silent) {
1491 		fprintSegment(f, 2*INDENT, "/*\n", 0);
1492 		if (smiType->description) {
1493 		    fprintMultiline(f, smiType->description);
1494 		}
1495 		if (smiType->reference) {
1496 		    fprintSegment(f, 2*INDENT, "REFERENCE:", 0);
1497 		    fprint(f, "\n");
1498 		    fprintMultilineString(f, smiType->reference);
1499 		}
1500 		if (smiType->format) {
1501 		    fprintSegment(f, 2*INDENT, "DISPLAY-HINT:", 0);
1502 		    fprint(f, " %s\n", smiType->format);
1503 		}
1504 		fprintSegment(f, 2*INDENT, "*/\n", 0);
1505 	    }
1506 	    fprintSegment(f, 2*INDENT, "", 0);
1507 	    fprint(f, "string %sToString (in %s Value);\n", smiType->name,
1508 		  getIdlTypeName(smiGetTypeModule(smiType)->name,
1509 				 smiType->name));
1510 	    fprintSegment(f, 2*INDENT, "", 0);
1511 	    fprint(f, "%s %sFromString (in string str);\n",
1512 		  getIdlTypeName(smiGetTypeModule(smiType)->name,
1513 				 smiType->name),
1514 		  smiType->name);
1515 	}
1516     }
1517 
1518     if (cnt) {
1519 	fprintSegment(f, INDENT, "};\n\n", 0);
1520     }
1521 }
1522 
1523 
1524 
dumpIdl(SmiModule * smiModule)1525 static void dumpIdl(SmiModule *smiModule)
1526 {
1527     char        *idlModuleName;
1528     FILE        *f;
1529     SmiRevision *smiRevision;
1530     char        *date;
1531 
1532     f = createFile(getIdlModuleName(smiModule->name), ".idl");
1533     if (! f) {
1534         return;
1535     }
1536 
1537     fprintf(f,
1538 	    "/*	\t\t\t\t\t\t-- DO NOT EDIT --\n"
1539 	    " * Generated by smidump version " SMI_VERSION_STRING ":\n");
1540 
1541     fprintf(f, " *   smidump -f corba %s\n *\n", smiModule->name);
1542 
1543     fprintf(f,
1544 	    " * Derived from %s:\n", smiModule->name);
1545     fprintCommentString(f, smiModule->description);
1546 
1547     for (smiRevision = smiGetFirstRevision(smiModule);
1548 	 smiRevision;
1549 	 smiRevision = smiGetNextRevision(smiRevision)) {
1550 	date = getStringTime(smiRevision->date);
1551 	fprintf(f,
1552 		" *\n"
1553 		" * Revision %s:\n", date);
1554 	fprintCommentString(f, smiRevision->description);
1555     }
1556 
1557     fprintf(f,
1558 	    " *\n * $I" "d$\n"
1559 	    " */\n"
1560 	    "\n");
1561 
1562     idlModuleName = getIdlModuleName(smiModule->name);
1563     createImportList(smiModule);
1564 
1565     fprint(f, "#ifndef _%s_IDL_\n", idlModuleName);
1566     fprint(f, "#define _%s_IDL_\n\n", idlModuleName);
1567 
1568     fprintIncludes(f, smiModule);
1569 
1570     fprint(f, "module %s {\n\n", idlModuleName);
1571 
1572     fprintImportedTypedefs(f, smiModule);
1573     fprintModule(f, smiModule);
1574     fprintTypedefs(f, smiModule);
1575     fprintInterfaces(f, smiModule);
1576     fprintNotificationVBTypes(f, smiModule);
1577     fprintNotificationTypes(f, smiModule);
1578     fprintPushNotifications(f, smiModule);
1579     fprintPullNotifications(f, smiModule);
1580     fprintFactory(f, smiModule);
1581     fprintDefVals(f, smiModule);
1582     fprintDisplayHints(f, smiModule);
1583 
1584     fprint(f, "};\n\n");
1585     fprint(f, "#endif /* !_%s_IDL_ */\n", idlModuleName);
1586 
1587     freeImportList();
1588     dictFree(&idlModuleNameList);
1589     dictFree(&idlNodeNameList);
1590     dictFree(&idlTypeNameList);
1591     dictFree(&idlVBTypeNameList);
1592 
1593     if (fflush(f) || ferror(f)) {
1594 	perror("smidump: write error");
1595 	exit(1);
1596     }
1597 
1598     fclose(f);
1599 }
1600 
1601 
1602 
fprintNameAndOid(FILE * f,SmiNode * smiNode,SmiNode * smiParentNode)1603 static void fprintNameAndOid(FILE *f, SmiNode *smiNode, SmiNode *smiParentNode)
1604 {
1605     unsigned int i;
1606     char         *idlModuleName;
1607 
1608     idlModuleName = getIdlModuleName(smiGetNodeModule(smiNode)->name);
1609 
1610     if (smiParentNode) {
1611 	fprint(f, "::%s::%s::%s ",
1612 	       idlModuleName, smiParentNode->name, smiNode->name);
1613     } else {
1614 	fprint(f, "::%s::%s ", idlModuleName, smiNode->name);
1615     }
1616     for (i = 0; i < smiNode->oidlen; i++) {
1617 	fprint(f, "%s%u", i ? "." : "", smiNode->oid[i]);
1618     }
1619     fprint(f, " ");
1620 }
1621 
1622 
1623 
dumpOid(SmiModule * smiModule)1624 static void dumpOid(SmiModule *smiModule)
1625 {
1626     SmiNode   *smiNode;
1627     SmiType   *smiType;
1628     FILE      *f;
1629 
1630     f = createFile(getIdlModuleName(smiModule->name), ".oid");
1631     if (! f) {
1632         return;
1633     }
1634 
1635     for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
1636 	 smiNode;
1637 	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
1638 
1639 	if (isGroup(smiNode)) {
1640             fprintNameAndOid(f, smiNode, NULL);
1641 	    fprint(f, "Group not-accessible\n");
1642 	    /* XXX what if the node is also of SMI_NODEKIND_MODULE ?? */
1643 	    continue;
1644 	}
1645 
1646 	smiType = smiGetNodeType(smiNode);
1647 
1648 	switch (smiNode->nodekind) {
1649 	case SMI_NODEKIND_NODE:
1650 	    if (current(smiNode->status)) {
1651 		fprintNameAndOid(f, smiNode, NULL);
1652 		fprint(f, "ASN1_ObjectIdentifier not-accessible\n");
1653 	    }
1654 	    break;
1655 	case SMI_NODEKIND_SCALAR:
1656 	    if (smiType && current(smiNode->status)) {
1657 		SmiNode *smiParentNode = smiGetParentNode(smiNode);
1658 		fprintNameAndOid(f, smiNode, smiParentNode);
1659 		fprint(f, "%s %s\n",
1660 		       getBaseTypeString(smiType->basetype),
1661 		       getAccessString(smiNode->access, 0));
1662 	    }
1663 	    break;
1664 	case SMI_NODEKIND_TABLE:
1665 	    if (current(smiNode->status)) {
1666 		fprintNameAndOid(f, smiNode, NULL);
1667 		fprint(f, "Table not-accessible\n");
1668 	    }
1669 	    break;
1670 	case SMI_NODEKIND_ROW:
1671 	    if (current(smiNode->status)) {
1672 		fprintNameAndOid(f, smiNode, NULL);
1673 		fprint(f, "TableEntry not-accessible\n");
1674 	    }
1675 	    break;
1676 	case SMI_NODEKIND_COLUMN:
1677 	    if (smiType && current(smiNode->status)) {
1678 		SmiNode *smiParentNode = smiGetParentNode(smiNode);
1679 		int create = smiParentNode ? smiParentNode->create : 0;
1680 		fprintNameAndOid(f, smiNode, smiParentNode);
1681 		fprint(f, "%s %s\n",
1682 		       getBaseTypeString(smiType->basetype),
1683 		       getAccessString(smiNode->access, create));
1684 	    }
1685 	    break;
1686 	case SMI_NODEKIND_NOTIFICATION:
1687 	    if (current(smiNode->status)) {
1688 		SmiNode *smiParentNode = smiGetParentNode(smiNode);
1689 		fprintNameAndOid(f, smiNode, smiParentNode);
1690 		fprint(f, "Notification not-accessible\n");
1691 	    }
1692 	    break;
1693 	case SMI_NODEKIND_GROUP:
1694 	    break;
1695 	case SMI_NODEKIND_COMPLIANCE:
1696 	    break;
1697 	}
1698     }
1699 
1700     dictFree(&idlModuleNameList);
1701 
1702     if (fflush(f) || ferror(f)) {
1703 	perror("smidump: write error");
1704 	exit(1);
1705     }
1706 
1707     fclose(f);
1708 }
1709 
1710 
dumpCorba(int modc,SmiModule ** modv,int flags,char * output)1711 static void dumpCorba(int modc, SmiModule **modv, int flags, char *output)
1712 {
1713     int       i;
1714 
1715     silent = (flags & SMIDUMP_FLAG_SILENT);
1716 
1717     for (i = 0; i < modc; i++) {
1718 	dumpIdl(modv[i]);
1719 	dumpOid(modv[i]);
1720     }
1721 }
1722 
1723 
1724 
initCorba()1725 void initCorba()
1726 {
1727 
1728     static SmidumpDriver driver = {
1729 	"corba",
1730 	dumpCorba,
1731 	0,
1732 	SMIDUMP_DRIVER_CANT_UNITE | SMIDUMP_DRIVER_CANT_OUTPUT,
1733 	"corba IDL interface and OID definitions (JIDM)",
1734 	NULL,
1735 	NULL
1736     };
1737 
1738     smidumpRegisterDriver(&driver);
1739 }
1740