Blame tools/dump-smi.c

Packit 022b05
/*
Packit 022b05
 * dump-smi.c --
Packit 022b05
 *
Packit 022b05
 *      Operations to dump SMIv1/v2 module information.
Packit 022b05
 *
Packit 022b05
 * Copyright (c) 1999 Frank Strauss, Technical University of Braunschweig.
Packit 022b05
 *
Packit 022b05
 * See the file "COPYING" for information on usage and redistribution
Packit 022b05
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Packit 022b05
 *
Packit 022b05
 * @(#) $Id: dump-smi.c 8090 2008-04-18 12:56:29Z strauss $
Packit 022b05
 */
Packit 022b05
Packit 022b05
#include <config.h>
Packit 022b05
Packit 022b05
#include <stdlib.h>
Packit 022b05
#include <stdio.h>
Packit 022b05
#include <stdarg.h>
Packit 022b05
#include <string.h>
Packit 022b05
#include <ctype.h>
Packit 022b05
#include <time.h>
Packit 022b05
Packit 022b05
#include "smi.h"
Packit 022b05
#include "smidump.h"
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
extern int smiAsprintf(char **strp, const char *format, ...);
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
#define  INDENT		4    /* indent factor */
Packit 022b05
#define  INDENTVALUE	16   /* column to start values, except multiline */
Packit 022b05
#define  INDENTTEXTS	 9   /* column to start multiline texts */
Packit 022b05
#define  INDENTTEXTS2	15   /* column to start indented multiline texts */
Packit 022b05
#define  INDENTMAX	72   /* max column to fill, break lines otherwise */
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char *convertTypev1[] = {
Packit 022b05
    NULL,		 "Counter32",	       NULL,	   "Counter",
Packit 022b05
    NULL,		 "Gauge32",	       NULL,	   "Gauge",
Packit 022b05
    NULL,		 "Integer32",	       NULL,	   "INTEGER",
Packit 022b05
    NULL,		 "Unsigned32",	       NULL,	   "Gauge",
Packit 022b05
    NULL,		 "Bits",	       NULL,	   "OCTET STRING",
Packit 022b05
    NULL,		 "OctetString",	       NULL,	   "OCTET STRING",
Packit 022b05
    NULL,		 "ObjectIdentifier",   NULL,	   "OBJECT IDENTIFIER",
Packit 022b05
    NULL, NULL, NULL, NULL };
Packit 022b05
Packit 022b05
Packit 022b05
static char *convertTypev2[] = {
Packit 022b05
    NULL,		 "INTEGER",	       NULL,	   "Integer32",
Packit 022b05
    NULL,		 "Enumeration",	       NULL,	   "INTEGER",
Packit 022b05
    NULL,		 "Bits",	       NULL,	   "BITS",
Packit 022b05
    NULL,		 "OctetString",	       NULL,	   "OCTET STRING",
Packit 022b05
    NULL,		 "ObjectIdentifier",   NULL,	   "OBJECT IDENTIFIER",
Packit 022b05
    NULL,		 "Counter",	       NULL,	   "Counter32",
Packit 022b05
    NULL,		 "Gauge",	       NULL,	   "Gauge32",
Packit 022b05
    NULL, NULL, NULL, NULL };
Packit 022b05
Packit 022b05
static char *convertTypePIBtoMIB[] = {
Packit 022b05
    NULL,		 "Unsigned64",	       NULL,	   "IBRUnsigned64",
Packit 022b05
    NULL,		 "Integer64",	       NULL,	   "IBRInteger64",
Packit 022b05
/* XXX This breaks SMIv2 -> SMIv? compilation such that the IMPORT statement
Packit 022b05
   for SnmpAdminString is removed. I've remove this as a quick fix, but I'm
Packit 022b05
   not sure what to do for PIB compilation here.
Packit 022b05
    NULL,		 "SnmpAdminString",    NULL,	   "OCTET STRING",
Packit 022b05
*/
Packit 022b05
    NULL, NULL, NULL, NULL };
Packit 022b05
Packit 022b05
static char *convertImportv2[] = {
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "IpAddress",       "SNMPv2-SMI", "IpAddress",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "Counter32",       "SNMPv2-SMI", "Counter32",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "Gauge32",	        "SNMPv2-SMI", "Gauge32",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "TimeTicks",       "SNMPv2-SMI", "TimeTicks",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "Opaque",	        "SNMPv2-SMI", "Opaque",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "Counter64",       "SNMPv2-SMI", "Counter64",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "DisplayString",   "SNMPv2-TC", "DisplayString",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "PhysAddress",     "SNMPv2-TC", "PhysAddress",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "MacAddress",      "SNMPv2-TC", "MacAddress",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "TruthValue",      "SNMPv2-TC", "TruthValue",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "TestAndIncr",     "SNMPv2-TC", "TestAndIncr",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "AutonomousType",  "SNMPv2-TC", "AutonomousType",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "InstancePointer", "SNMPv2-TC", "InstancePointer",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "VariablePointer", "SNMPv2-TC", "VariablePointer",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "RowPointer",      "SNMPv2-TC", "RowPointer",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "RowStatus",       "SNMPv2-TC", "RowStatus",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "TimeStamp",       "SNMPv2-TC", "TimeStamp",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "TimeInterval",    "SNMPv2-TC", "TimeInterval",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "DateAndTime",     "SNMPv2-TC", "DateAndTime",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "StorageType",     "SNMPv2-TC", "StorageType",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "TDomain",         "SNMPv2-TC", "TDomain",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "TAddress",        "SNMPv2-TC", "TAddress",
Packit 022b05
    "IRTF-NMRG-SMING", NULL,                    "SNMPv2-SMI", NULL,
Packit 022b05
Packit 022b05
    "RFC1155-SMI", "internet",	    "SNMPv2-SMI", "internet",
Packit 022b05
    "RFC1155-SMI", "directory",	    "SNMPv2-SMI", "directory",
Packit 022b05
    "RFC1155-SMI", "mgmt",	    "SNMPv2-SMI", "mgmt",
Packit 022b05
    "RFC1155-SMI", "experimental",  "SNMPv2-SMI", "experimental",
Packit 022b05
    "RFC1155-SMI", "private",	    "SNMPv2-SMI", "private",
Packit 022b05
    "RFC1155-SMI", "enterprises",   "SNMPv2-SMI", "enterprises",
Packit 022b05
    "RFC1155-SMI", "IpAddress",     "SNMPv2-SMI", "IpAddress",
Packit 022b05
    "RFC1155-SMI", "Counter",       "SNMPv2-SMI", "Counter32",
Packit 022b05
    "RFC1155-SMI", "Gauge",         "SNMPv2-SMI", "Gauge32",
Packit 022b05
    "RFC1155-SMI", "TimeTicks",     "SNMPv2-SMI", "TimeTicks",
Packit 022b05
    "RFC1155-SMI", "Opaque",        "SNMPv2-SMI", "Opaque",
Packit 022b05
    "RFC1213-MIB", "mib-2",         "SNMPv2-SMI", "mib-2",    
Packit 022b05
    "RFC1213-MIB", "DisplayString", "SNMPv2-TC",  "DisplayString",    
Packit 022b05
Packit 022b05
/* import types for PIB to MIB conversion */
Packit 022b05
Packit 022b05
    NULL, NULL, NULL, NULL };
Packit 022b05
Packit 022b05
static char *convertImportv1[] = {
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "IpAddress",   "RFC1155-SMI", "IpAddress",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "Counter32",   "RFC1155-SMI", "Counter",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "Gauge32",	    "RFC1155-SMI", "Gauge",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "TimeTicks",   "RFC1155-SMI", "TimeTicks",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "Opaque",	    "RFC1155-SMI", "Opaque",
Packit 022b05
    "IRTF-NMRG-SMING-TYPES", "Counter64",   NULL,          NULL,
Packit 022b05
    "IRTF-NMRG-SMING",       "mib-2",	    "RFC1213-MIB", "mib-2",
Packit 022b05
    
Packit 022b05
    "SNMPv2-SMI", "IpAddress",              "RFC1155-SMI", "IpAddress",
Packit 022b05
    "SNMPv2-SMI", "Counter32",              "RFC1155-SMI", "Counter",
Packit 022b05
    "SNMPv2-SMI", "Gauge32",	            "RFC1155-SMI", "Gauge",
Packit 022b05
    "SNMPv2-SMI", "TimeTicks",              "RFC1155-SMI", "TimeTicks",
Packit 022b05
    "SNMPv2-SMI", "Opaque",	            "RFC1155-SMI", "Opaque",
Packit 022b05
    "SNMPv2-SMI", "Integer32",	            NULL,	   NULL,
Packit 022b05
    "SNMPv2-SMI", "Unsigned32",	            NULL,	   NULL,
Packit 022b05
    "SNMPv2-SMI", "Counter64",	            NULL,	   NULL,
Packit 022b05
    "SNMPv2-SMI", "mib-2",                  "RFC1213-MIB", "mib-2",
Packit 022b05
    "SNMPv2-SMI", "MODULE-IDENTITY",        NULL,	   NULL,
Packit 022b05
    "SNMPv2-SMI", "OBJECT-IDENTITY",        NULL,	   NULL,
Packit 022b05
    "SNMPv2-SMI", "ObjectName",		    NULL,	   NULL,
Packit 022b05
    "SNMPv2-SMI", "NotificationName",       NULL,	   NULL,
Packit 022b05
    "SNMPv2-SMI", "ObjectSyntax",	    NULL,	   NULL,
Packit 022b05
    "SNMPv2-SMI", "SimpleSyntax",	    NULL,	   NULL,
Packit 022b05
    "SNMPv2-SMI", "ApplicationSyntax",      NULL,	   NULL,
Packit 022b05
    "SNMPv2-SMI", "OBJECT-TYPE",	    NULL,	   NULL,
Packit 022b05
    "SNMPv2-SMI", "NOTIFICATION-TYPE",      NULL,	   NULL,
Packit 022b05
    NULL, NULL, NULL, NULL };
Packit 022b05
Packit 022b05
static int current_column = 0;
Packit 022b05
static int smiv1 = 0;
Packit 022b05
static int silent = 0;
Packit 022b05
static int pibtomib = 0;
Packit 022b05
Packit 022b05
Packit 022b05
typedef struct Import {
Packit 022b05
    char          *module;
Packit 022b05
    char          *name;
Packit 022b05
    struct Import *nextPtr;
Packit 022b05
} Import;
Packit 022b05
Packit 022b05
static Import *importList = NULL;
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int invalidType(SmiBasetype basetype)
Packit 022b05
{
Packit 022b05
    if (smiv1) {
Packit 022b05
	return (basetype == SMI_BASETYPE_INTEGER64)
Packit 022b05
	    || (basetype == SMI_BASETYPE_UNSIGNED64)
Packit 022b05
	    || (basetype == SMI_BASETYPE_FLOAT32)
Packit 022b05
	    || (basetype == SMI_BASETYPE_FLOAT64)
Packit 022b05
	    || (basetype == SMI_BASETYPE_FLOAT128);
Packit 022b05
    } else if (!pibtomib) {
Packit 022b05
	return (basetype == SMI_BASETYPE_INTEGER64)
Packit 022b05
	    || (basetype == SMI_BASETYPE_FLOAT32)
Packit 022b05
	    || (basetype == SMI_BASETYPE_FLOAT64)
Packit 022b05
	    || (basetype == SMI_BASETYPE_FLOAT128);
Packit 022b05
    } else {
Packit 022b05
	return (basetype == SMI_BASETYPE_FLOAT32)
Packit 022b05
	    || (basetype == SMI_BASETYPE_FLOAT64)
Packit 022b05
	    || (basetype == SMI_BASETYPE_FLOAT128);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char *getStatusString(SmiStatus status)
Packit 022b05
{
Packit 022b05
    if (smiv1) {
Packit 022b05
	return
Packit 022b05
	    (status == SMI_STATUS_CURRENT)     ? "mandatory" :
Packit 022b05
	    (status == SMI_STATUS_DEPRECATED)  ? "deprecated" :
Packit 022b05
	    (status == SMI_STATUS_OBSOLETE)    ? "obsolete" :
Packit 022b05
	    (status == SMI_STATUS_MANDATORY)   ? "mandatory" :
Packit 022b05
	    (status == SMI_STATUS_OPTIONAL)    ? "optional" :
Packit 022b05
					         "<unknown>";
Packit 022b05
    } else {
Packit 022b05
	return
Packit 022b05
	    (status == SMI_STATUS_CURRENT)     ? "current" :
Packit 022b05
	    (status == SMI_STATUS_DEPRECATED)  ? "deprecated" :
Packit 022b05
	    (status == SMI_STATUS_OBSOLETE)    ? "obsolete" :
Packit 022b05
	    (status == SMI_STATUS_MANDATORY)   ? "current" :
Packit 022b05
	    (status == SMI_STATUS_OPTIONAL)    ? "current" :
Packit 022b05
					         "<unknown>";
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char *getAccessString(SmiAccess access, int create)
Packit 022b05
{
Packit 022b05
    if (smiv1) {
Packit 022b05
	return
Packit 022b05
	    (access == SMI_ACCESS_NOT_ACCESSIBLE) ? "not-accessible" :
Packit 022b05
	    (access == SMI_ACCESS_NOTIFY)	  ? "read-only" :
Packit 022b05
	    (access == SMI_ACCESS_READ_ONLY)      ? "read-only" :
Packit 022b05
	    (access == SMI_ACCESS_READ_WRITE)     ? "read-write" :
Packit 022b05
						    "<unknown>";
Packit 022b05
Packit 022b05
    } else {
Packit 022b05
	if (create && (access == SMI_ACCESS_READ_WRITE)) {
Packit 022b05
	    return "read-create";
Packit 022b05
	} else {
Packit 022b05
            if (pibtomib)
Packit 022b05
                return
Packit 022b05
	        (access == SMI_ACCESS_NOT_ACCESSIBLE) ? "not-accessible" :
Packit 022b05
	        (access == SMI_ACCESS_NOTIFY)	      ? "read-only" :
Packit 022b05
	        (access == SMI_ACCESS_READ_ONLY)      ? "read-only" :
Packit 022b05
	        (access == SMI_ACCESS_READ_WRITE)     ? "read-write" :
Packit 022b05
	        (access == SMI_ACCESS_INSTALL)        ? "read-create" :
Packit 022b05
	        (access == SMI_ACCESS_INSTALL_NOTIFY) ? "read-create" :
Packit 022b05
						        "<unknown>";
Packit 022b05
            else
Packit 022b05
	        return
Packit 022b05
	        (access == SMI_ACCESS_NOT_ACCESSIBLE) ? "not-accessible" :
Packit 022b05
	        (access == SMI_ACCESS_NOTIFY)	  ? "accessible-for-notify" :
Packit 022b05
	        (access == SMI_ACCESS_READ_ONLY)      ? "read-only" :
Packit 022b05
	        (access == SMI_ACCESS_READ_WRITE)     ? "read-write" :
Packit 022b05
						        "<unknown>";
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char *getTimeString(time_t t)
Packit 022b05
{
Packit 022b05
    static char   *s = NULL;
Packit 022b05
    struct tm	  *tm;
Packit 022b05
Packit 022b05
    if (s) xfree(s);
Packit 022b05
    
Packit 022b05
    tm = gmtime(&t);
Packit 022b05
    smiAsprintf(&s, "%04d%02d%02d%02d%02dZ",
Packit 022b05
		tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
Packit 022b05
		tm->tm_hour, tm->tm_min);
Packit 022b05
    return s;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char *getTypeString(SmiBasetype basetype, SmiType *smiType)
Packit 022b05
{
Packit 022b05
    int         i;
Packit 022b05
    char	**convertType;
Packit 022b05
    char        *typeModule, *typeName;
Packit 022b05
Packit 022b05
    typeName = smiType ? smiType->name : NULL;
Packit 022b05
    typeModule = smiType ? smiGetTypeModule(smiType)->name : NULL;
Packit 022b05
Packit 022b05
    convertType = smiv1 ? convertTypev1 : convertTypev2;
Packit 022b05
Packit 022b05
    if (typeName &&
Packit 022b05
	(basetype != SMI_BASETYPE_ENUM) &&
Packit 022b05
	(basetype != SMI_BASETYPE_BITS)) {
Packit 022b05
        if (pibtomib)
Packit 022b05
	    for(i=0; convertTypePIBtoMIB[i+1]; i += 4) {
Packit 022b05
	        if ((!strcmp(typeName, convertTypePIBtoMIB[i+1])) &&
Packit 022b05
		    ((!typeModule) || (!convertTypePIBtoMIB[i]) ||
Packit 022b05
		     (!strcmp(typeModule, convertTypePIBtoMIB[i])))) {
Packit 022b05
		    return convertTypePIBtoMIB[i+3];
Packit 022b05
	        }
Packit 022b05
	    }
Packit 022b05
	for(i=0; convertType[i+1]; i += 4) {
Packit 022b05
	    if ((!strcmp(typeName, convertType[i+1])) &&
Packit 022b05
		((!typeModule) || (!convertType[i]) ||
Packit 022b05
		 (!strcmp(typeModule, convertType[i])))) {
Packit 022b05
		return convertType[i+3];
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if ((!typeModule) || (!strlen(typeModule)) || (!typeName)) {
Packit 022b05
	if (basetype == SMI_BASETYPE_ENUM) {
Packit 022b05
	    return "INTEGER";
Packit 022b05
	}
Packit 022b05
	if (basetype == SMI_BASETYPE_BITS) {
Packit 022b05
	    if (smiv1) {
Packit 022b05
		return "OCTET STRING";
Packit 022b05
	    } else {
Packit 022b05
		return "BITS";
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
	
Packit 022b05
    /* TODO: fully qualified if unambigous */
Packit 022b05
Packit 022b05
    return typeName;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char *getOidString(SmiNode *smiNode, int importedParent)
Packit 022b05
{
Packit 022b05
    SmiNode	 *parentNode;
Packit 022b05
    SmiModule	 *smiModule;
Packit 022b05
    static char	 s[200];
Packit 022b05
    char	 append[200];
Packit 022b05
    unsigned int i;
Packit 022b05
Packit 022b05
    append[0] = 0;
Packit 022b05
Packit 022b05
    parentNode = smiNode;
Packit 022b05
    smiModule = smiGetNodeModule(smiNode);
Packit 022b05
    
Packit 022b05
    do {
Packit 022b05
	
Packit 022b05
	if (parentNode->oidlen <= 1) {
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
	
Packit 022b05
	/* prepend the cut-off subidentifier to `append'. */
Packit 022b05
	strcpy(s, append);
Packit 022b05
	if (parentNode->decl != SMI_DECL_IMPL_OBJECT) {
Packit 022b05
	    sprintf(append, " %u%s", parentNode->oid[parentNode->oidlen-1], s);
Packit 022b05
	} else {
Packit 022b05
	    sprintf(append, " %s(%u)%s",
Packit 022b05
		    parentNode->name,
Packit 022b05
		    parentNode->oid[parentNode->oidlen-1], s);
Packit 022b05
	}
Packit 022b05
	
Packit 022b05
	/* retrieve the parent SmiNode */
Packit 022b05
	parentNode = smiGetParentNode(parentNode);
Packit 022b05
Packit 022b05
	if (!parentNode) {
Packit 022b05
	    sprintf(s, "%s", append);
Packit 022b05
	    return s;
Packit 022b05
	}
Packit 022b05
	
Packit 022b05
	/* found an imported or a local parent node? */
Packit 022b05
	if ((parentNode->decl != SMI_DECL_IMPL_OBJECT) &&
Packit 022b05
	    ((parentNode->name && strlen(parentNode->name)) &&
Packit 022b05
	    (smiIsImported(smiModule, NULL, parentNode->name) ||
Packit 022b05
	     (!importedParent &&
Packit 022b05
	      (smiGetNodeModule(parentNode) == smiModule)) ||
Packit 022b05
	     (parentNode->oidlen == 1)))) {
Packit 022b05
	    sprintf(s, "%s%s", parentNode->name, append);
Packit 022b05
	    return s;
Packit 022b05
	}
Packit 022b05
Packit 022b05
    } while (parentNode);
Packit 022b05
Packit 022b05
    s[0] = 0;
Packit 022b05
    for (i=0; i < smiNode->oidlen; i++) {
Packit 022b05
	if (i) strcat(s, " ");
Packit 022b05
	sprintf(&s[strlen(s)], "%u", smiNode->oid[i]);
Packit 022b05
    }
Packit 022b05
    return s;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char *getUppercaseString(char *s)
Packit 022b05
{
Packit 022b05
    static char *ss;
Packit 022b05
Packit 022b05
    ss = xstrdup(s);
Packit 022b05
    ss[0] = (char)toupper((int)ss[0]);
Packit 022b05
    return ss;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int isObjectGroup(SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiNode     *smiNode;
Packit 022b05
    SmiElement  *smiElement;
Packit 022b05
    
Packit 022b05
    for (smiElement = smiGetFirstElement(groupNode); smiElement;
Packit 022b05
	 smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
Packit 022b05
	smiNode = smiGetElementNode(smiElement);
Packit 022b05
	
Packit 022b05
	if (smiNode->nodekind != SMI_NODEKIND_SCALAR
Packit 022b05
	    && smiNode->nodekind != SMI_NODEKIND_COLUMN) {
Packit 022b05
	    return 0;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return 1;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int isNotificationGroup(SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiNode     *smiNode;
Packit 022b05
    SmiElement  *smiElement;
Packit 022b05
    
Packit 022b05
    for (smiElement = smiGetFirstElement(groupNode); smiElement;
Packit 022b05
	 smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
Packit 022b05
	smiNode = smiGetElementNode(smiElement);
Packit 022b05
	
Packit 022b05
	if (smiNode->nodekind != SMI_NODEKIND_NOTIFICATION) {
Packit 022b05
	    return 0;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return 1;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static Import* addImport(char *module, char *name)
Packit 022b05
{
Packit 022b05
    Import **import, *newImport;
Packit 022b05
    char   **convertImport;
Packit 022b05
    int    i;
Packit 022b05
Packit 022b05
    convertImport = smiv1 ? convertImportv1 : convertImportv2;
Packit 022b05
Packit 022b05
    for (i = 0; convertImport[i]; i += 4) {
Packit 022b05
	if (convertImport[i] && convertImport[i+1]
Packit 022b05
	    && !strcmp(module, convertImport[i])
Packit 022b05
	    && !strcmp(name, convertImport[i+1])) {
Packit 022b05
	    module = convertImport[i+2];
Packit 022b05
	    name = convertImport[i+3];
Packit 022b05
	    break;
Packit 022b05
	} else if (convertImport[i] && !convertImport[i+1]
Packit 022b05
		   && !strcmp(module, convertImport[i])) {
Packit 022b05
	    module = convertImport[i+2];
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (!module || !name) {
Packit 022b05
	return NULL;
Packit 022b05
    }
Packit 022b05
	    
Packit 022b05
    for (import = &importList; *import; import = &(*import)->nextPtr) {
Packit 022b05
	int c = strcmp((*import)->module, module);
Packit 022b05
	if (c < 0) continue;
Packit 022b05
	if (c == 0) {
Packit 022b05
	    int d = strcmp((*import)->name, name);
Packit 022b05
	    if (d < 0) continue;
Packit 022b05
	    if (d == 0) return *import;
Packit 022b05
	    if (d > 0) break;
Packit 022b05
	}
Packit 022b05
	if (c > 0) break;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    newImport = xmalloc(sizeof(Import));
Packit 022b05
    if (! newImport) {
Packit 022b05
	return NULL;
Packit 022b05
    }
Packit 022b05
    newImport->module = module;
Packit 022b05
    newImport->name = name;
Packit 022b05
    newImport->nextPtr = *import;
Packit 022b05
    *import = newImport;
Packit 022b05
	
Packit 022b05
    return *import;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void createImportList(SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode     *smiNode;
Packit 022b05
    SmiType     *smiType;
Packit 022b05
    SmiNodekind kind = SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN;
Packit 022b05
    SmiImport   *smiImport;
Packit 022b05
    SmiModule	*smiModule2;
Packit 022b05
    
Packit 022b05
    if (pibtomib) {
Packit 022b05
        addImport("TUBS-SMI", "ibrpibtomib");
Packit 022b05
	for(smiType = smiGetFirstType(smiModule);
Packit 022b05
	    smiType; smiType = smiGetNextType(smiType)) {
Packit 022b05
	    if (smiType->basetype == SMI_BASETYPE_UNSIGNED32)
Packit 022b05
	        addImport("SNMPv2-SMI", "Unsigned32"); 
Packit 022b05
            else if (smiType->basetype == SMI_BASETYPE_UNSIGNED64)
Packit 022b05
	        addImport("TUBS-SMI", "IBRUnsigned64"); 
Packit 022b05
            else if (smiType->basetype == SMI_BASETYPE_INTEGER64)
Packit 022b05
	        addImport("TUBS-SMI", "IBRInteger64"); 
Packit 022b05
        }
Packit 022b05
        if (smiGetFirstNode(smiModule, SMI_NODEKIND_TABLE) != NULL)
Packit 022b05
            addImport("SNMPv2-TC", "RowStatus");
Packit 022b05
        for(smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ROW);
Packit 022b05
            smiNode; smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ROW)) {
Packit 022b05
            if (smiNode->indexkind == SMI_INDEX_SPARSE) {
Packit 022b05
                SmiNode *smiNode2 = smiGetRelatedNode(smiNode);
Packit 022b05
                while (smiNode2 && (smiNode2->indexkind == SMI_INDEX_SPARSE))
Packit 022b05
                    smiNode2 = smiGetRelatedNode(smiNode2);
Packit 022b05
                if (smiNode2) {
Packit 022b05
                    smiModule2 = smiGetNodeModule(smiNode2);
Packit 022b05
                    if (smiModule != smiModule2)
Packit 022b05
                        addImport(smiModule2->name, smiNode2->name);
Packit 022b05
                }
Packit 022b05
            }
Packit 022b05
        }
Packit 022b05
    }
Packit 022b05
        
Packit 022b05
    for(smiNode = smiGetFirstNode(smiModule, kind); smiNode;
Packit 022b05
	smiNode = smiGetNextNode(smiNode, kind)) {
Packit 022b05
	smiType = smiGetNodeType(smiNode);
Packit 022b05
	if (smiType && (smiType->decl == SMI_DECL_IMPLICIT_TYPE)) {
Packit 022b05
	    smiType = smiGetParentType(smiType);
Packit 022b05
	}
Packit 022b05
	if (smiType) {
Packit 022b05
	    smiModule2 = smiGetTypeModule(smiType);
Packit 022b05
	    if (smiModule2 && (smiModule2 != smiModule)) {
Packit 022b05
                size_t len = strlen(smiModule2->name);
Packit 022b05
		if (len && smiType->name) {
Packit 022b05
                    if (pibtomib && (len > 4) &&
Packit 022b05
                        !strcmp(&smiModule2->name[len - 4], "-PIB")) {
Packit 022b05
                        char *newName = xmalloc(len + 5);
Packit 022b05
                        strcpy(newName, smiModule2->name);
Packit 022b05
                        strcat(newName, "-MIB");
Packit 022b05
                        addImport(newName, smiType->name);
Packit 022b05
                    } else
Packit 022b05
		        addImport(smiModule2->name, smiType->name);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (pibtomib) {
Packit 022b05
            if (smiType && (smiType->basetype == SMI_BASETYPE_UNSIGNED32))
Packit 022b05
	        addImport("SNMPv2-SMI", "Unsigned32");
Packit 022b05
            if (smiType && (smiType->basetype == SMI_BASETYPE_UNSIGNED64))
Packit 022b05
	        addImport("TUBS-SMI", "IBRUnsigned64");
Packit 022b05
            if (smiType && (smiType->basetype == SMI_BASETYPE_INTEGER64))
Packit 022b05
	        addImport("TUBS-SMI", "IBRInteger64");
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (! smiv1 &&
Packit 022b05
	    smiType && smiType->basetype == SMI_BASETYPE_INTEGER32) {
Packit 022b05
	    addImport("SNMPv2-SMI", "Integer32");
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if ((!smiv1) &&
Packit 022b05
	    (smiNode->value.basetype == SMI_BASETYPE_OBJECTIDENTIFIER) &&
Packit 022b05
	    (!strcmp(smiNode->value.value.ptr, "zeroDotZero"))) {
Packit 022b05
	    addImport("SNMPv2-SMI", "zeroDotZero");
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    smiNode = smiGetFirstNode(smiModule,
Packit 022b05
			      SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN
Packit 022b05
			      | SMI_NODEKIND_TABLE | SMI_NODEKIND_ROW);
Packit 022b05
    if (smiNode) {
Packit 022b05
	addImport(smiv1 ? "RFC-1212" : "SNMPv2-SMI", "OBJECT-TYPE");
Packit 022b05
    }
Packit 022b05
Packit 022b05
    smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
Packit 022b05
    if (smiNode) {
Packit 022b05
	addImport(smiv1 ? "RFC-1215" : "SNMPv2-SMI",
Packit 022b05
		  smiv1 ? "TRAP-TYPE" : "NOTIFICATION-TYPE");
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (! smiv1) {
Packit 022b05
	smiNode = smiGetModuleIdentityNode(smiModule);
Packit 022b05
	if (smiNode) {
Packit 022b05
	    if (strcmp("SNMPv2-SMI", smiModule->name)) {
Packit 022b05
		addImport("SNMPv2-SMI", "MODULE-IDENTITY");
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (! smiv1) {
Packit 022b05
	for(smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NODE);
Packit 022b05
	    smiNode; smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NODE)) {
Packit 022b05
	    if (smiNode->status != SMI_STATUS_UNKNOWN &&
Packit 022b05
		smiNode != smiGetModuleIdentityNode(smiModule)) {
Packit 022b05
		if (strcmp("SNMPv2-SMI", smiModule->name)) {
Packit 022b05
		    addImport("SNMPv2-SMI", "OBJECT-IDENTITY");
Packit 022b05
		}
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (! smiv1) {
Packit 022b05
	smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_COMPLIANCE);
Packit 022b05
	if (smiNode) {
Packit 022b05
	    if (strcmp("SNMPv2-CONF", smiModule->name)) {
Packit 022b05
		addImport("SNMPv2-CONF", "MODULE-COMPLIANCE");
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (! smiv1) {
Packit 022b05
	for(smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_GROUP);
Packit 022b05
	    smiNode;
Packit 022b05
	    smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_GROUP)) {
Packit 022b05
	    if (isObjectGroup(smiNode)) {
Packit 022b05
		if (strcmp("SNMPv2-CONF", smiModule->name)) {
Packit 022b05
		    addImport("SNMPv2-CONF", "OBJECT-GROUP");
Packit 022b05
		}
Packit 022b05
	    } else if (isNotificationGroup(smiNode)) {
Packit 022b05
		if (strcmp("SNMPv2-CONF", smiModule->name)) {
Packit 022b05
		    addImport("SNMPv2-CONF", "NOTIFICATION-GROUP");
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (! smiv1) {
Packit 022b05
	for(smiType = smiGetFirstType(smiModule);
Packit 022b05
	    smiType; smiType = smiGetNextType(smiType)) {
Packit 022b05
	    if (smiType->description) {
Packit 022b05
		if (strcmp("SNMPv2-TC", smiModule->name)) {
Packit 022b05
		    addImport("SNMPv2-TC", "TEXTUAL-CONVENTION");
Packit 022b05
		}
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    for (smiImport = smiGetFirstImport(smiModule); smiImport;
Packit 022b05
	 smiImport = smiGetNextImport(smiImport)) {
Packit 022b05
	if (islower((int) smiImport->name[0]) ||
Packit 022b05
	    (smiImport->module && !strcmp(smiImport->module, "SNMPv2-SMI")) ||
Packit 022b05
	    (!smiv1 && smiImport->module && !strcmp(smiImport->module, "SNMPv2-TC"))) {
Packit 022b05
	    addImport(smiImport->module, smiImport->name);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void freeImportList(void)
Packit 022b05
{
Packit 022b05
    Import *import, *freeme;
Packit 022b05
Packit 022b05
    for (import = importList; import; ) {
Packit 022b05
	freeme = import;
Packit 022b05
	import = import->nextPtr;
Packit 022b05
	xfree(freeme);
Packit 022b05
    }
Packit 022b05
    importList = NULL;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprint(FILE *f, char *fmt, ...)
Packit 022b05
{
Packit 022b05
    va_list ap;
Packit 022b05
    char    *s;
Packit 022b05
    char    *p;
Packit 022b05
    
Packit 022b05
    va_start(ap, fmt);
Packit 022b05
    current_column += smiVasprintf(&s, fmt, ap);
Packit 022b05
    va_end(ap);
Packit 022b05
    fputs(s, f);
Packit 022b05
    if ((p = strrchr(s, '\n'))) {
Packit 022b05
	current_column = strlen(p) - 1;
Packit 022b05
    }
Packit 022b05
    free(s);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintSegment(FILE *f, int column, char *string,
Packit 022b05
			  int length, int comment)
Packit 022b05
{
Packit 022b05
    char *format;
Packit 022b05
    
Packit 022b05
    if (comment) {
Packit 022b05
	format = "-- %*c%s";
Packit 022b05
	/* if (column >= 3) column -= 3; */
Packit 022b05
    } else {
Packit 022b05
	format = "%*c%s";
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    fprint(f, format, column, ' ', string);
Packit 022b05
    if (length) {
Packit 022b05
	fprint(f, "%*c", length - strlen(string) - column, ' ');
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintWrapped(FILE *f, int column, char *string, int comment)
Packit 022b05
{
Packit 022b05
    if ((current_column + strlen(string)) > INDENTMAX) {
Packit 022b05
	putc('\n', f);
Packit 022b05
	current_column = 0;
Packit 022b05
	fprintSegment(f, column, "", 0, comment);
Packit 022b05
    }
Packit 022b05
    fprint(f, "%s", string);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintMultilineString(FILE *f, const char *s, const int comment)
Packit 022b05
{
Packit 022b05
    int i, len;
Packit 022b05
    
Packit 022b05
    fprintSegment(f, INDENTTEXTS - 1, "\"", 0, comment);
Packit 022b05
    if (s) {
Packit 022b05
	len = strlen(s);
Packit 022b05
	for (i=0; i < len; i++) {
Packit 022b05
	    putc(s[i], f);
Packit 022b05
	    current_column++;
Packit 022b05
	    if (s[i] == '\n') {
Packit 022b05
		current_column = 0;
Packit 022b05
		fprintSegment(f, INDENTTEXTS, "", 0, comment);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    putc('\"', f);
Packit 022b05
    current_column++;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintMultilineString2(FILE *f, const char *s, const int comment)
Packit 022b05
{
Packit 022b05
    int i, len;
Packit 022b05
    
Packit 022b05
    fprintSegment(f, INDENTTEXTS2 - 1, "\"", 0, comment);
Packit 022b05
    if (s) {
Packit 022b05
	len = strlen(s);
Packit 022b05
	for (i=0; i < len; i++) {
Packit 022b05
	    putc(s[i], f);
Packit 022b05
	    current_column++;
Packit 022b05
	    if (s[i] == '\n') {
Packit 022b05
		current_column = 0;
Packit 022b05
		fprintSegment(f, INDENTTEXTS2, "", 0, comment);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    putc('\"', f);
Packit 022b05
    current_column++;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char *getValueString(SmiValue *valuePtr, SmiType *typePtr)
Packit 022b05
{
Packit 022b05
    static char    s[1024];
Packit 022b05
    char           ss[9];
Packit 022b05
    int		   n;
Packit 022b05
    unsigned int   i;
Packit 022b05
    SmiNamedNumber *nn;
Packit 022b05
    SmiNode        *nodePtr;
Packit 022b05
    
Packit 022b05
    s[0] = 0;
Packit 022b05
    
Packit 022b05
    switch (valuePtr->basetype) {
Packit 022b05
    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
	sprintf(s, "%lu", valuePtr->value.unsigned32);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_INTEGER32:
Packit 022b05
	sprintf(s, "%ld", valuePtr->value.integer32);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_UNSIGNED64:
Packit 022b05
	sprintf(s, UINT64_FORMAT, valuePtr->value.unsigned64);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_INTEGER64:
Packit 022b05
	sprintf(s, INT64_FORMAT, valuePtr->value.integer64);
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_FLOAT32:
Packit 022b05
    case SMI_BASETYPE_FLOAT64:
Packit 022b05
    case SMI_BASETYPE_FLOAT128:
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_ENUM:
Packit 022b05
	for (nn = smiGetFirstNamedNumber(typePtr); nn;
Packit 022b05
	     nn = smiGetNextNamedNumber(nn)) {
Packit 022b05
	    if (nn->value.value.unsigned32 == valuePtr->value.unsigned32)
Packit 022b05
		break;
Packit 022b05
	}
Packit 022b05
	if (nn) {
Packit 022b05
	    sprintf(s, "%s", nn->name);
Packit 022b05
	} else {
Packit 022b05
	    sprintf(s, "%ld", valuePtr->value.integer32);
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
	for (i = 0; i < valuePtr->len; i++) {
Packit 022b05
	    if (!isprint((int)valuePtr->value.ptr[i])) break;
Packit 022b05
	}
Packit 022b05
	if (i == valuePtr->len) {
Packit 022b05
	    sprintf(s, "\"%s\"", valuePtr->value.ptr);
Packit 022b05
	} else {
Packit 022b05
            sprintf(s, "'%*s'H", 2 * valuePtr->len, " ");
Packit 022b05
            for (i=0; i < valuePtr->len; i++) {
Packit 022b05
                sprintf(ss, "%02x", valuePtr->value.ptr[i]);
Packit 022b05
                strncpy(&s[1+2*i], ss, 2);
Packit 022b05
            }
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_BITS:
Packit 022b05
	if (smiv1) {
Packit 022b05
            sprintf(s, "'%*s'H", 2 * valuePtr->len, " ");
Packit 022b05
            for (i=0; i < valuePtr->len; i++) {
Packit 022b05
                sprintf(ss, "%02x", valuePtr->value.ptr[i]);
Packit 022b05
                strncpy(&s[1+2*i], ss, 2);
Packit 022b05
            }
Packit 022b05
	} else {
Packit 022b05
	    sprintf(s, "{");
Packit 022b05
	    for (i = 0, n = 0; i < valuePtr->len * 8; i++) {
Packit 022b05
		if (valuePtr->value.ptr[i/8] & (1 << (7-(i%8)))) {
Packit 022b05
		    for (nn = smiGetFirstNamedNumber(typePtr); nn;
Packit 022b05
			 nn = smiGetNextNamedNumber(nn)) {
Packit 022b05
			if (nn->value.value.unsigned32 == i)
Packit 022b05
			    break;
Packit 022b05
		    }
Packit 022b05
		    if (nn) {
Packit 022b05
			if (n)
Packit 022b05
			    sprintf(&s[strlen(s)], ", ");
Packit 022b05
			n++;
Packit 022b05
			sprintf(&s[strlen(s)], "%s", nn->name);
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    sprintf(&s[strlen(s)], "}");
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_UNKNOWN:
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_POINTER:
Packit 022b05
	break;
Packit 022b05
    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
	nodePtr = smiGetNodeByOID(valuePtr->len, valuePtr->value.oid);
Packit 022b05
	if (nodePtr) {
Packit 022b05
	    sprintf(s, "%s", nodePtr->name);
Packit 022b05
	} else {
Packit 022b05
	    strcpy(s, "{");
Packit 022b05
	    for (i=0; i < valuePtr->len; i++) {
Packit 022b05
		if (i) strcat(s, " ");
Packit 022b05
		sprintf(&s[strlen(s)], "%u", valuePtr->value.oid[i]);
Packit 022b05
	    }
Packit 022b05
	    strcat(s, "}");
Packit 022b05
	}
Packit 022b05
	break;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return s;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintSubtype(FILE *f, SmiType *smiType, const int comment)
Packit 022b05
{
Packit 022b05
    SmiRange       *range;
Packit 022b05
    SmiNamedNumber *nn;
Packit 022b05
    char	   s[1024];
Packit 022b05
    int		   i, c = comment;
Packit 022b05
Packit 022b05
    if (pibtomib && ((smiType->basetype == SMI_BASETYPE_UNSIGNED64) ||
Packit 022b05
        (smiType->basetype == SMI_BASETYPE_INTEGER64))) {
Packit 022b05
        c = 1;
Packit 022b05
        fprint(f, " -- commented out by smidump\n-- ");
Packit 022b05
    }
Packit 022b05
    c = c || (smiv1 && smiType->basetype == SMI_BASETYPE_BITS);
Packit 022b05
    
Packit 022b05
    if ((smiType->basetype == SMI_BASETYPE_ENUM) ||
Packit 022b05
	(smiType->basetype == SMI_BASETYPE_BITS)) {
Packit 022b05
	for(i = 0, nn = smiGetFirstNamedNumber(smiType);
Packit 022b05
	    nn; i++, nn = smiGetNextNamedNumber(nn)) {
Packit 022b05
	    if (i) {
Packit 022b05
		fprint(f, ", ");
Packit 022b05
	    } else {
Packit 022b05
		if (c) {
Packit 022b05
		    fprint(f, "\n");
Packit 022b05
		    fprintSegment(f, INDENT, "", INDENTVALUE, c);
Packit 022b05
		    fprint(f, "  { ");
Packit 022b05
		} else {
Packit 022b05
		    fprint(f, " { ");
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    sprintf(s, "%s(%s)", nn->name,
Packit 022b05
		    getValueString(&nn->value, smiType));
Packit 022b05
	    fprintWrapped(f, INDENTVALUE + INDENT, s, c);
Packit 022b05
	}
Packit 022b05
	if (i) {
Packit 022b05
	    fprint(f, " }");
Packit 022b05
	}
Packit 022b05
    } else {
Packit 022b05
	for(i = 0, range = smiGetFirstRange(smiType);
Packit 022b05
	    range; i++, range = smiGetNextRange(range)) {
Packit 022b05
	    if (i) {
Packit 022b05
		fprint(f, " | ");
Packit 022b05
	    } else {
Packit 022b05
		if (smiType->basetype == SMI_BASETYPE_OCTETSTRING) {
Packit 022b05
		    fprint(f, " (SIZE(");
Packit 022b05
		} else {
Packit 022b05
		    fprint(f, " (");
Packit 022b05
		}
Packit 022b05
	    }	    
Packit 022b05
	    if (memcmp(&range->minValue, &range->maxValue,
Packit 022b05
		       sizeof(SmiValue))) {
Packit 022b05
		sprintf(s, "%s", getValueString(&range->minValue, smiType));
Packit 022b05
		sprintf(&s[strlen(s)], "..%s", 
Packit 022b05
			getValueString(&range->maxValue, smiType));
Packit 022b05
	    } else {
Packit 022b05
		sprintf(s, "%s", getValueString(&range->minValue, smiType));
Packit 022b05
	    }
Packit 022b05
	    fprintWrapped(f, INDENTVALUE + INDENT, s, 0);
Packit 022b05
	}
Packit 022b05
	if (i) {
Packit 022b05
	    if (smiType->basetype == SMI_BASETYPE_OCTETSTRING) {
Packit 022b05
		fprint(f, ")");
Packit 022b05
	    }
Packit 022b05
	    fprint(f, ")");
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintIndex(FILE *f, SmiNode *indexNode, const int comment)
Packit 022b05
{
Packit 022b05
    SmiElement *smiElement, *smiFirstElement;
Packit 022b05
    int        n, j;
Packit 022b05
Packit 022b05
    for (n = 0, smiElement = smiGetFirstElement(indexNode); smiElement;
Packit 022b05
	 n++, smiElement = smiGetNextElement(smiElement));
Packit 022b05
    if (pibtomib && (n > 1))
Packit 022b05
        smiFirstElement = smiGetNextElement(smiGetFirstElement(indexNode));
Packit 022b05
    else
Packit 022b05
        smiFirstElement = smiGetFirstElement(indexNode);
Packit 022b05
    fprintSegment(f, INDENT, "INDEX", INDENTVALUE, comment);
Packit 022b05
    fprint(f, "{ ");
Packit 022b05
    for (j = 0, smiElement = smiFirstElement; smiElement;
Packit 022b05
	 j++, smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
	if (j) {
Packit 022b05
	    fprint(f, ", ");
Packit 022b05
	}
Packit 022b05
	if (indexNode->implied && ((j+1) == n)) {
Packit 022b05
	    fprintWrapped(f, INDENTVALUE + 2, "IMPLIED ", 0);
Packit 022b05
	}
Packit 022b05
	fprintWrapped(f, INDENTVALUE + 2,
Packit 022b05
		      smiGetElementNode(smiElement)->name, 0);
Packit 022b05
	/* TODO: non-local name if non-local */
Packit 022b05
    } /* TODO: empty? -> print error */
Packit 022b05
    fprint(f, " }\n");
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintImports(FILE *f)
Packit 022b05
{
Packit 022b05
    Import        *import;
Packit 022b05
    char	  *lastModulename = NULL;
Packit 022b05
    char	  *importedModulename, *importedDescriptor;
Packit 022b05
    int		  i;
Packit 022b05
    char	  **convertImport;
Packit 022b05
Packit 022b05
    convertImport = smiv1 ? convertImportv1 : convertImportv2;
Packit 022b05
Packit 022b05
    for(import = importList; import; import = import->nextPtr) {
Packit 022b05
	importedModulename = import->module;
Packit 022b05
	importedDescriptor = import->name;
Packit 022b05
Packit 022b05
	if (!strlen(importedModulename))
Packit 022b05
	    continue;
Packit 022b05
	
Packit 022b05
	for(i = 0; convertImport[i]; i += 4) {
Packit 022b05
	    if (convertImport[i] && convertImport[i+1]
Packit 022b05
		&& !strcmp(importedModulename, convertImport[i])
Packit 022b05
		&& !strcmp(importedDescriptor, convertImport[i+1])) {
Packit 022b05
		importedModulename = convertImport[i+2];
Packit 022b05
		importedDescriptor = convertImport[i+3];
Packit 022b05
		break;
Packit 022b05
	    } else if (convertImport[i] && !convertImport[i+1]
Packit 022b05
		       && !strcmp(importedModulename, convertImport[i])) {
Packit 022b05
		importedModulename = convertImport[i+2];
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (importedModulename && importedDescriptor &&
Packit 022b05
	    strlen(importedDescriptor)) {
Packit 022b05
	    if ((!lastModulename) ||
Packit 022b05
		strcmp(importedModulename, lastModulename)) {
Packit 022b05
		if (!lastModulename) {
Packit 022b05
		    fprint(f, "IMPORTS");
Packit 022b05
		} else {
Packit 022b05
		    fprint(f, "\n");
Packit 022b05
		    fprintSegment(f, 2 * INDENT, "", 0, 0);
Packit 022b05
		    fprint(f, "FROM %s", lastModulename);
Packit 022b05
		}
Packit 022b05
		fprint(f, "\n");
Packit 022b05
		fprintSegment(f, INDENT, "", 0, 0);
Packit 022b05
	    } else {
Packit 022b05
		fprint(f, ", ");
Packit 022b05
	    }
Packit 022b05
	    fprintWrapped(f, INDENT, importedDescriptor, 0);
Packit 022b05
	    lastModulename = importedModulename;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    if (lastModulename) {
Packit 022b05
	fprint(f, "\n");
Packit 022b05
	fprintSegment(f, 2 * INDENT, "", 0, 0);
Packit 022b05
	fprint(f, "FROM %s;\n\n", lastModulename);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintModuleIdentity(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiRevision  *smiRevision;
Packit 022b05
    SmiNode      *smiNode;
Packit 022b05
Packit 022b05
    smiNode = smiGetModuleIdentityNode(smiModule);
Packit 022b05
    
Packit 022b05
    if (smiNode) {
Packit 022b05
Packit 022b05
	if (smiv1 && smiNode) {
Packit 022b05
	    fprint(f, "%s OBJECT IDENTIFIER\n", smiNode->name);
Packit 022b05
	    fprintSegment(f, INDENT, "::= ", 0, 0);
Packit 022b05
	    fprint(f, "{ %s }\n\n", getOidString(smiNode, 0));
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (! smiv1 || ! silent) {
Packit 022b05
Packit 022b05
	    if (smiv1) {
Packit 022b05
		fprint(f, "-- %s MODULE-IDENTITY\n", smiNode->name);
Packit 022b05
	    } else {
Packit 022b05
		fprint(f, "%s MODULE-IDENTITY\n", smiNode->name);
Packit 022b05
	    }
Packit 022b05
	    fprintSegment(f, INDENT, "LAST-UPDATED", INDENTVALUE, smiv1);
Packit 022b05
	    smiRevision = smiGetFirstRevision(smiModule);
Packit 022b05
	    if (smiRevision)
Packit 022b05
		fprint(f, "\"%s\"\n", getTimeString(smiRevision->date));
Packit 022b05
	    else
Packit 022b05
		fprint(f, "\"197001010000Z\"\n");
Packit 022b05
	    fprintSegment(f, INDENT, "ORGANIZATION", INDENTVALUE, smiv1);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    fprintMultilineString(f, smiModule->organization, smiv1);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    fprintSegment(f, INDENT, "CONTACT-INFO", INDENTVALUE, smiv1);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    fprintMultilineString(f, smiModule->contactinfo, smiv1);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    fprintSegment(f, INDENT, "DESCRIPTION", INDENTVALUE, smiv1);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    if (smiModule->description) {
Packit 022b05
		fprintMultilineString(f, smiModule->description, smiv1);
Packit 022b05
	    } else {
Packit 022b05
		fprintMultilineString(f, "...", smiv1);
Packit 022b05
	    }
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    
Packit 022b05
	    for(; smiRevision;
Packit 022b05
		smiRevision = smiGetNextRevision(smiRevision)) {
Packit 022b05
		if (!smiRevision->description
Packit 022b05
		    || strcmp(smiRevision->description,
Packit 022b05
	   "[Revision added by libsmi due to a LAST-UPDATED clause.]")) {
Packit 022b05
		    fprintSegment(f, INDENT, "REVISION", INDENTVALUE, smiv1);
Packit 022b05
		    fprint(f, "\"%s\"\n", getTimeString(smiRevision->date));
Packit 022b05
		    fprintSegment(f, INDENT, "DESCRIPTION", INDENTVALUE,
Packit 022b05
				  smiv1);
Packit 022b05
		    fprint(f, "\n");
Packit 022b05
		    if (smiRevision->description) {
Packit 022b05
			fprintMultilineString(f, smiRevision->description,
Packit 022b05
					      smiv1);
Packit 022b05
		    } else {
Packit 022b05
			fprintMultilineString(f, "...", smiv1);
Packit 022b05
		    }
Packit 022b05
		    fprint(f, "\n");
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    
Packit 022b05
	    if (smiNode) {
Packit 022b05
		fprintSegment(f, INDENT, "::= ", 0, smiv1);
Packit 022b05
                if (!pibtomib)
Packit 022b05
		    fprint(f, "{ %s }\n\n", getOidString(smiNode, 0));
Packit 022b05
                else
Packit 022b05
                    fprint(f, "{ ibrpibtomib %d }\n\n",
Packit 022b05
                           smiNode->oid[smiNode->oidlen - 1]);
Packit 022b05
	    }
Packit 022b05
	    /* TODO: else error */
Packit 022b05
	    
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintTypeDefinition(FILE *f, SmiType *smiType)
Packit 022b05
{
Packit 022b05
    int		 invalid;
Packit 022b05
Packit 022b05
    if (smiType->status == SMI_STATUS_UNKNOWN) {
Packit 022b05
	invalid = invalidType(smiType->basetype);
Packit 022b05
	if (invalid) {
Packit 022b05
	    fprint(f, "-- %s ::=\n", smiType->name);
Packit 022b05
	} else {
Packit 022b05
	    fprint(f, "%s ::=\n", smiType->name);
Packit 022b05
	}
Packit 022b05
	fprintSegment(f, INDENT, "", 0, invalid);
Packit 022b05
	fprint(f, "%s", getTypeString(smiType->basetype,
Packit 022b05
				      smiGetParentType(smiType)));
Packit 022b05
	fprintSubtype(f, smiType, invalid);
Packit 022b05
	fprint(f, "\n\n");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintTypeDefinitions(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiType	 *smiType;
Packit 022b05
Packit 022b05
    for(smiType = smiGetFirstType(smiModule);
Packit 022b05
	smiType; smiType = smiGetNextType(smiType)) {
Packit 022b05
	fprintTypeDefinition(f, smiType);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintTextualConvention(FILE *f, SmiType *smiType)
Packit 022b05
{
Packit 022b05
    SmiType      *baseType;
Packit 022b05
    SmiModule    *baseModule;
Packit 022b05
    int		 i, invalid;
Packit 022b05
Packit 022b05
    char *smiv2basetypes[] = {
Packit 022b05
	"SNMPv2-SMI", "IpAddress",
Packit 022b05
	"SNMPv2-SMI", "Counter32",
Packit 022b05
	"SNMPv2-SMI", "Gauge32",
Packit 022b05
	"SNMPv2-SMI", "TimeTicks",    
Packit 022b05
	"SNMPv2-SMI", "Counter64",
Packit 022b05
	NULL, NULL
Packit 022b05
    };
Packit 022b05
    
Packit 022b05
    if (smiType->status != SMI_STATUS_UNKNOWN) {
Packit 022b05
	invalid = invalidType(smiType->basetype);
Packit 022b05
	if (smiv1 && !invalid) {
Packit 022b05
	    fprint(f, "%s ::=\n", smiType->name);
Packit 022b05
	    fprintSegment(f, INDENT, "", 0, invalid);
Packit 022b05
	    fprint(f, "%s", getTypeString(smiType->basetype,
Packit 022b05
					  smiGetParentType(smiType)));
Packit 022b05
	    fprintSubtype(f, smiType, invalid);
Packit 022b05
	    fprint(f, "\n\n");
Packit 022b05
	}
Packit 022b05
	
Packit 022b05
	if (! smiv1 || ! silent) {
Packit 022b05
	    
Packit 022b05
	    if (smiv1 || invalid) {
Packit 022b05
		fprint(f, "-- %s ::= TEXTUAL-CONVENTION\n", smiType->name);
Packit 022b05
	    } else {
Packit 022b05
		fprint(f, "%s ::= TEXTUAL-CONVENTION\n", smiType->name);
Packit 022b05
	    }
Packit 022b05
	    
Packit 022b05
	    if (smiType->format) {
Packit 022b05
		fprintSegment(f, INDENT, "DISPLAY-HINT", INDENTVALUE,
Packit 022b05
			      smiv1 || invalid);
Packit 022b05
		fprint(f, "\"%s\"\n", smiType->format);
Packit 022b05
	    }
Packit 022b05
	    
Packit 022b05
	    fprintSegment(f, INDENT, "STATUS", INDENTVALUE,
Packit 022b05
			  smiv1 || invalid);
Packit 022b05
	    fprint(f, "%s\n", getStatusString(smiType->status));
Packit 022b05
	    
Packit 022b05
	    fprintSegment(f, INDENT, "DESCRIPTION", INDENTVALUE,
Packit 022b05
			  smiv1 || invalid);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    if (smiType->description) {
Packit 022b05
		fprintMultilineString(f, smiType->description,
Packit 022b05
				      smiv1 || invalid);
Packit 022b05
	    } else {
Packit 022b05
		fprintMultilineString(f, "...", smiv1 || invalid);
Packit 022b05
	    }
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    
Packit 022b05
	    if (smiType->reference) {
Packit 022b05
		fprintSegment(f, INDENT, "REFERENCE", INDENTVALUE,
Packit 022b05
			      smiv1 || invalid);
Packit 022b05
		fprint(f, "\n");
Packit 022b05
		fprintMultilineString(f, smiType->reference,
Packit 022b05
				      smiv1 || invalid);
Packit 022b05
		fprint(f, "\n");
Packit 022b05
	    }
Packit 022b05
	    
Packit 022b05
	    for (baseType = smiGetParentType(smiType);
Packit 022b05
		 baseType;
Packit 022b05
		 baseType = smiGetParentType(baseType)) {
Packit 022b05
		SmiType *parent = smiGetParentType(baseType);
Packit 022b05
Packit 022b05
		baseModule = smiGetTypeModule(baseType);
Packit 022b05
		if (baseModule && baseModule->name) {
Packit 022b05
		    for (i = 0; smiv2basetypes[i]; i += 2) {
Packit 022b05
			if (strcmp(smiv2basetypes[i+1], baseType->name) == 0
Packit 022b05
			    && strcmp(smiv2basetypes[i], baseModule->name) == 0) {
Packit 022b05
			    parent = NULL;
Packit 022b05
			}
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		
Packit 022b05
		fprintSegment(f, INDENT, "SYNTAX", INDENTVALUE,
Packit 022b05
			      smiv1 || invalid || parent);
Packit 022b05
		fprint(f, "%s",
Packit 022b05
		       getTypeString(baseType->basetype, baseType));
Packit 022b05
		fprintSubtype(f, smiType, smiv1 || invalid || parent);
Packit 022b05
		if (parent) {
Packit 022b05
		    fprintf(f, "\n");
Packit 022b05
		}
Packit 022b05
		if (!parent) break;
Packit 022b05
	    }
Packit 022b05
	    fprint(f, "\n\n");
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintTextualConventions(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiType	 *smiType;
Packit 022b05
    
Packit 022b05
    for(smiType = smiGetFirstType(smiModule);
Packit 022b05
	smiType; smiType = smiGetNextType(smiType)) {
Packit 022b05
	fprintTextualConvention(f, smiType);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
static int isInIndex(SmiNode *node, SmiNode *parentNode)
Packit 022b05
{
Packit 022b05
    SmiElement *element;
Packit 022b05
    
Packit 022b05
    if ((parentNode->indexkind != SMI_INDEX_INDEX) &&
Packit 022b05
        (parentNode->indexkind != SMI_INDEX_EXPAND))
Packit 022b05
        return 0;
Packit 022b05
    
Packit 022b05
    for (element = smiGetNextElement(smiGetFirstElement(parentNode)); element;
Packit 022b05
         element = smiGetNextElement(element))
Packit 022b05
        if (smiGetElementNode(element)->name &&
Packit 022b05
            node->name &&
Packit 022b05
            !strcmp(smiGetElementNode(element)->name, node->name))
Packit 022b05
            return 1;
Packit 022b05
    return 0;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintObjects(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode	 *smiNode, *rowNode, *colNode, *smiParentNode, *relatedNode;
Packit 022b05
    SmiType	 *smiType;
Packit 022b05
    SmiNodekind  nodekinds;
Packit 022b05
    int		 i, invalid, create, assignement, indentsequence, addrowstatus;
Packit 022b05
    
Packit 022b05
    nodekinds =  SMI_NODEKIND_NODE | SMI_NODEKIND_TABLE |
Packit 022b05
	SMI_NODEKIND_ROW | SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR |
Packit 022b05
	SMI_NODEKIND_CAPABILITIES;
Packit 022b05
    
Packit 022b05
    for(smiNode = smiGetFirstNode(smiModule, nodekinds);
Packit 022b05
	smiNode; smiNode = smiGetNextNode(smiNode, nodekinds)) {
Packit 022b05
Packit 022b05
	smiType = smiGetNodeType(smiNode);
Packit 022b05
	smiParentNode = smiGetParentNode(smiNode);
Packit 022b05
	
Packit 022b05
	create = smiParentNode ? smiParentNode->create : 0;
Packit 022b05
	
Packit 022b05
	invalid = !smiType ? 0 : invalidType(smiType->basetype);
Packit 022b05
	assignement = 0;
Packit 022b05
Packit 022b05
	if (invalid && silent
Packit 022b05
	    && (smiNode->nodekind == SMI_NODEKIND_SCALAR
Packit 022b05
		|| smiNode->nodekind == SMI_NODEKIND_COLUMN)) {
Packit 022b05
	    continue;
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (smiNode == smiGetModuleIdentityNode(smiModule)) {
Packit 022b05
	    continue;
Packit 022b05
	}
Packit 022b05
	
Packit 022b05
	if ((smiNode->nodekind == SMI_NODEKIND_NODE) &&
Packit 022b05
	    (smiNode->status == SMI_STATUS_UNKNOWN)) {
Packit 022b05
	    assignement = 1;
Packit 022b05
	    fprint(f, "%s OBJECT IDENTIFIER\n", smiNode->name);
Packit 022b05
	} else if (smiNode->nodekind == SMI_NODEKIND_NODE) {
Packit 022b05
	    if (smiv1) {
Packit 022b05
		assignement = 1;
Packit 022b05
		fprint(f, "%s OBJECT IDENTIFIER\n", smiNode->name);
Packit 022b05
	    } else {
Packit 022b05
		fprint(f, "%s OBJECT-IDENTITY\n", smiNode->name);
Packit 022b05
	    }
Packit 022b05
	} else if (smiNode->nodekind == SMI_NODEKIND_CAPABILITIES) {
Packit 022b05
	    /* TODO: real agent capabilities */
Packit 022b05
	    fprint(f, "-- This has been an SMIv2 AGENT-CAPABILITIES node:\n");
Packit 022b05
	    if (smiv1) {
Packit 022b05
		assignement = 1;
Packit 022b05
		fprint(f, "%s OBJECT IDENTIFIER\n", smiNode->name);
Packit 022b05
	    } else {
Packit 022b05
		fprint(f, "%s OBJECT-IDENTITY\n", smiNode->name);
Packit 022b05
	    }
Packit 022b05
	} else {
Packit 022b05
	    if (invalid) {
Packit 022b05
		fprint(f, "-- %s OBJECT-TYPE\n", smiNode->name);
Packit 022b05
	    } else {
Packit 022b05
		fprint(f, "%s OBJECT-TYPE\n", smiNode->name);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if ((smiNode->nodekind == SMI_NODEKIND_TABLE) ||
Packit 022b05
	    (smiNode->nodekind == SMI_NODEKIND_ROW) ||
Packit 022b05
	    (smiType)) {
Packit 022b05
	    fprintSegment(f, INDENT, "SYNTAX", INDENTVALUE, invalid);
Packit 022b05
	    if (smiNode->nodekind == SMI_NODEKIND_TABLE) {
Packit 022b05
		fprint(f, "SEQUENCE OF ");
Packit 022b05
		rowNode = smiGetFirstChildNode(smiNode);
Packit 022b05
		if (rowNode) {
Packit 022b05
		    smiType = smiGetNodeType(rowNode);
Packit 022b05
		    if (smiType) {
Packit 022b05
			fprint(f, "%s\n", smiType->name);
Packit 022b05
		    } else {
Packit 022b05
			/* guess type name is uppercase row name */
Packit 022b05
			char *s = getUppercaseString(rowNode->name);
Packit 022b05
			fprint(f, "%s\n", s);
Packit 022b05
			xfree(s);
Packit 022b05
		    }
Packit 022b05
		    /* TODO: print non-local name qualified */
Packit 022b05
		} else {
Packit 022b05
		    fprint(f, "<unknown>\n");
Packit 022b05
		}
Packit 022b05
	    } else if (smiNode->nodekind == SMI_NODEKIND_ROW) {
Packit 022b05
		if (smiType) {
Packit 022b05
		    fprint(f, "%s\n", smiType->name);
Packit 022b05
		} else {
Packit 022b05
		    char *s = getUppercaseString(smiNode->name);
Packit 022b05
		    /* guess type name is uppercase row name */
Packit 022b05
		    fprint(f, "%s\n", s);
Packit 022b05
		    xfree(s);
Packit 022b05
		}
Packit 022b05
		/* TODO: print non-local name qualified */
Packit 022b05
	    } else if (smiType) {
Packit 022b05
		if (!smiType->name) {
Packit 022b05
		    /*
Packit 022b05
		     * an implicitly restricted type.
Packit 022b05
		     */
Packit 022b05
		    fprint(f, "%s", getTypeString(smiType->basetype,
Packit 022b05
						  smiGetParentType(smiType)));
Packit 022b05
		    fprintSubtype(f, smiType, invalid);
Packit 022b05
		    fprint(f, "\n");
Packit 022b05
		} else {
Packit 022b05
		    fprint(f, "%s\n",
Packit 022b05
			   getTypeString(smiType->basetype, smiType));
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (! assignement && smiNode->units) {
Packit 022b05
	    fprintSegment(f, INDENT, "UNITS", INDENTVALUE, smiv1 || invalid);
Packit 022b05
	    fprint(f, "\"%s\"\n", smiNode->units);
Packit 022b05
	}
Packit 022b05
	
Packit 022b05
	if (! assignement &&
Packit 022b05
	    smiNode->nodekind != SMI_NODEKIND_CAPABILITIES &&
Packit 022b05
	    smiNode->nodekind != SMI_NODEKIND_NODE) {
Packit 022b05
	    if (smiv1) {
Packit 022b05
		fprintSegment(f, INDENT, "ACCESS", INDENTVALUE, invalid);
Packit 022b05
	    } else {
Packit 022b05
 		fprintSegment(f, INDENT, "MAX-ACCESS", INDENTVALUE, 0);
Packit 022b05
	    }
Packit 022b05
            if (pibtomib) {
Packit 022b05
                if ((smiNode->nodekind == SMI_NODEKIND_TABLE) ||
Packit 022b05
                    (smiNode->nodekind == SMI_NODEKIND_ROW))
Packit 022b05
                    fprint(f, "not-accessible\n");
Packit 022b05
                else if ((smiNode->nodekind == SMI_NODEKIND_COLUMN) &&
Packit 022b05
                         isInIndex(smiNode, smiParentNode))
Packit 022b05
	            fprint(f, "not-accessible\n");
Packit 022b05
                else if (smiNode->nodekind == SMI_NODEKIND_COLUMN)
Packit 022b05
                    fprint(f, "read-create\n");
Packit 022b05
                else
Packit 022b05
	            fprint(f, "%s\n", getAccessString(smiNode->access, create));
Packit 022b05
            } else
Packit 022b05
	        fprint(f, "%s\n", getAccessString(smiNode->access, create));
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (! assignement) {
Packit 022b05
	    fprintSegment(f, INDENT, "STATUS", INDENTVALUE, invalid);
Packit 022b05
	    fprint(f, "%s\n", getStatusString(smiNode->status));
Packit 022b05
	}
Packit 022b05
	
Packit 022b05
	if (! assignement) {
Packit 022b05
	    fprintSegment(f, INDENT, "DESCRIPTION", INDENTVALUE, invalid);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    if (smiNode->description) {
Packit 022b05
		fprintMultilineString(f, smiNode->description, invalid);
Packit 022b05
	    } else {
Packit 022b05
		fprintMultilineString(f, "...", invalid);
Packit 022b05
	    }
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	}
Packit 022b05
	    
Packit 022b05
	if (! assignement && smiNode->reference) {
Packit 022b05
	    fprintSegment(f, INDENT, "REFERENCE", INDENTVALUE,
Packit 022b05
			  smiv1 || invalid);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    fprintMultilineString(f, smiNode->reference, smiv1 || invalid);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	}
Packit 022b05
Packit 022b05
	relatedNode = smiGetRelatedNode(smiNode);
Packit 022b05
	switch (smiNode->indexkind) {
Packit 022b05
	case SMI_INDEX_INDEX:
Packit 022b05
	case SMI_INDEX_REORDER:
Packit 022b05
	    fprintIndex(f, smiNode, invalid);
Packit 022b05
	    break;
Packit 022b05
	case SMI_INDEX_EXPAND:  /* TODO: we have to do more work here! */
Packit 022b05
	    fprintIndex(f, smiNode, invalid);
Packit 022b05
	    break;
Packit 022b05
	case SMI_INDEX_AUGMENT:
Packit 022b05
	    if (smiv1 && ! invalid) {
Packit 022b05
		if (relatedNode) {
Packit 022b05
		    fprintIndex(f, relatedNode, invalid);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    if ((! smiv1 || ! silent) && relatedNode) {
Packit 022b05
		fprintSegment(f, INDENT, "AUGMENTS", INDENTVALUE,
Packit 022b05
			      smiv1 || invalid);
Packit 022b05
		fprint(f, "{ %s }\n", relatedNode->name);
Packit 022b05
	    }
Packit 022b05
	    break;
Packit 022b05
	case SMI_INDEX_SPARSE:
Packit 022b05
	    if (! invalid) {
Packit 022b05
                while (relatedNode &&
Packit 022b05
                       (relatedNode->indexkind == SMI_INDEX_SPARSE))
Packit 022b05
                    relatedNode = smiGetRelatedNode(relatedNode);
Packit 022b05
		if (relatedNode) {
Packit 022b05
		    fprintIndex(f, relatedNode, invalid);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	    /* TODO: non-local name if non-local */
Packit 022b05
	    break;
Packit 022b05
	case SMI_INDEX_UNKNOWN:
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
	
Packit 022b05
	if (smiNode->value.basetype != SMI_BASETYPE_UNKNOWN) {
Packit 022b05
	    fprintSegment(f, INDENT, "DEFVAL", INDENTVALUE, invalid);
Packit 022b05
	    fprint(f, "{ %s }", getValueString(&smiNode->value, smiType));
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	}
Packit 022b05
Packit 022b05
	fprintSegment(f, INDENT, "::= ", 0, invalid);
Packit 022b05
	fprint(f, "{ %s }\n\n", getOidString(smiNode, 0));
Packit 022b05
Packit 022b05
	smiType = smiGetNodeType(smiNode);
Packit 022b05
        addrowstatus = 0;
Packit 022b05
	if (smiNode->nodekind == SMI_NODEKIND_ROW) {
Packit 022b05
            if (pibtomib)
Packit 022b05
                addrowstatus = 1;
Packit 022b05
	    if (smiType) {
Packit 022b05
		fprint(f, "%s ::= SEQUENCE {", smiType->name);
Packit 022b05
	    } else {
Packit 022b05
		/* guess type name is uppercase row name */
Packit 022b05
		char *s = getUppercaseString(smiNode->name);
Packit 022b05
		fprint(f, "%s ::= SEQUENCE {", s);
Packit 022b05
		xfree(s);
Packit 022b05
	    }
Packit 022b05
	    /* Find the last valid node in this sequence. We need it
Packit 022b05
	     * to suppress its trailing comma. Compute the longest
Packit 022b05
	     * column name so that we can adjust the indentation of
Packit 022b05
	     * the type names in the SEQUENCE definition. */
Packit 022b05
	    for(indentsequence = 0, colNode = smiGetFirstChildNode(smiNode);
Packit 022b05
		colNode;
Packit 022b05
		colNode = smiGetNextChildNode(colNode)) {
Packit 022b05
		int len = strlen(colNode->name);
Packit 022b05
		if (len > indentsequence) indentsequence = len;
Packit 022b05
		smiType = smiGetNodeType(colNode);
Packit 022b05
		if (smiType && !invalidType(smiType->basetype)) {
Packit 022b05
		    relatedNode = colNode;
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
            if (pibtomib) {
Packit 022b05
                int len = strlen(smiParentNode->name) + 9;
Packit 022b05
                if (len > 64)
Packit 022b05
                  len = 64;
Packit 022b05
                indentsequence = len;
Packit 022b05
            }
Packit 022b05
	    if (relatedNode) relatedNode = smiGetNextChildNode(relatedNode);
Packit 022b05
	    indentsequence = (2*INDENT + indentsequence + 1) / INDENT * INDENT;
Packit 022b05
	    /* TODO: non-local name? */
Packit 022b05
	    for(i = 0, invalid = 0, colNode = smiGetFirstChildNode(smiNode);
Packit 022b05
		colNode;
Packit 022b05
		colNode = smiGetNextChildNode(colNode)) {
Packit 022b05
		if (! invalid || ! silent) {
Packit 022b05
		    if (i && (relatedNode != colNode)) {
Packit 022b05
			fprint(f, ",");
Packit 022b05
		    } 
Packit 022b05
		    fprint(f, "\n");
Packit 022b05
		}
Packit 022b05
		
Packit 022b05
		smiType = smiGetNodeType(colNode);
Packit 022b05
		invalid = (smiType == NULL) || invalidType(smiType->basetype);
Packit 022b05
Packit 022b05
		if (! invalid || ! silent) {
Packit 022b05
		    fprintSegment(f, INDENT, colNode->name, indentsequence,
Packit 022b05
				  invalid);
Packit 022b05
		    if (smiType && smiType->decl == SMI_DECL_IMPLICIT_TYPE) {
Packit 022b05
			fprint(f, "%s", getTypeString(smiType->basetype,
Packit 022b05
					      smiGetParentType(smiType)));
Packit 022b05
		    } else if (smiType) {
Packit 022b05
			fprint(f, "%s", getTypeString(smiType->basetype,
Packit 022b05
					      smiGetNodeType(colNode)));
Packit 022b05
		    } else {
Packit 022b05
			fprint(f, "<unknown>");
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		i++;
Packit 022b05
	    }
Packit 022b05
            if (pibtomib) {
Packit 022b05
                size_t len = strlen(smiParentNode->name);
Packit 022b05
                int maxid;
Packit 022b05
                char *rowStatus = xmalloc(len + 10);
Packit 022b05
                strcpy(rowStatus, smiParentNode->name);
Packit 022b05
                if (len > 55)
Packit 022b05
                  len = 55;
Packit 022b05
                strcpy(&rowStatus[len], "RowStatus");
Packit 022b05
                fprint(f, ",\n");
Packit 022b05
                fprintSegment(f, INDENT, rowStatus, indentsequence, 0);
Packit 022b05
                fprint(f, "RowStatus\n}\n\n");
Packit 022b05
                
Packit 022b05
                fprint(f, "%s OBJECT-TYPE\n", rowStatus);
Packit 022b05
	        fprintSegment(f, INDENT, "SYNTAX", INDENTVALUE, 0);
Packit 022b05
                fprint(f, "RowStatus\n");
Packit 022b05
                fprintSegment(f, INDENT, "MAX-ACCESS", INDENTVALUE, 0);
Packit 022b05
                fprint(f, "read-create\n");
Packit 022b05
                fprintSegment(f, INDENT, "STATUS", INDENTVALUE, 0);
Packit 022b05
                fprint(f, "current\n");
Packit 022b05
                fprintSegment(f, INDENT, "DESCRIPTION", INDENTVALUE, 0);
Packit 022b05
                fprint(f, "\n");
Packit 022b05
		fprintMultilineString(f, "Added by smidump for automatic " \
Packit 022b05
                                      "PIB to MIB conversion.", 0);
Packit 022b05
                fprint(f, "\n");
Packit 022b05
	        fprintSegment(f, INDENT, "::= ", 0, 0);
Packit 022b05
                for (maxid = 0, colNode = smiGetFirstChildNode(smiNode);
Packit 022b05
                     colNode; colNode = smiGetNextChildNode(colNode))
Packit 022b05
                     if (colNode->oidlen &&
Packit 022b05
                         (colNode->oid[colNode->oidlen - 1] > maxid))
Packit 022b05
                         maxid = colNode->oid[colNode->oidlen - 1];
Packit 022b05
	        fprint(f, "{ %s %d }\n\n",
Packit 022b05
                       smiGetFirstChildNode(smiParentNode)->name, 
Packit 022b05
                       (maxid + 1) > 128 ? (maxid + 1) : 128);
Packit 022b05
                xfree(rowStatus);
Packit 022b05
            } else
Packit 022b05
 	        fprint(f, "\n}\n\n");
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintNotifications(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode	 *smiNode, *parentNode;
Packit 022b05
    SmiElement   *smiElement;
Packit 022b05
    int          j;
Packit 022b05
    
Packit 022b05
    for(smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_NOTIFICATION);
Packit 022b05
	smiNode;
Packit 022b05
	smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_NOTIFICATION)) {
Packit 022b05
Packit 022b05
	if (smiv1) {
Packit 022b05
	    fprint(f, "%s TRAP-TYPE\n", smiNode->name);
Packit 022b05
	    parentNode = smiGetParentNode(smiNode);
Packit 022b05
	    while ((parentNode->oidlen > 0) &&
Packit 022b05
		   ((!parentNode->name) ||
Packit 022b05
		    (!parentNode->oid[parentNode->oidlen-1]))) {
Packit 022b05
		parentNode = smiGetParentNode(parentNode);
Packit 022b05
	    }
Packit 022b05
	    fprintSegment(f, INDENT, "ENTERPRISE", INDENTVALUE, 0);
Packit 022b05
	    fprint(f, "%s\n", parentNode->name);
Packit 022b05
	} else {
Packit 022b05
	    fprint(f, "%s NOTIFICATION-TYPE\n", smiNode->name);
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if ((smiElement = smiGetFirstElement(smiNode))) {
Packit 022b05
	    if (smiv1) {
Packit 022b05
		fprintSegment(f, INDENT, "VARIABLES", INDENTVALUE, 0);
Packit 022b05
	    } else {
Packit 022b05
		fprintSegment(f, INDENT, "OBJECTS", INDENTVALUE, 0);
Packit 022b05
	    }
Packit 022b05
	    fprint(f, "{ ");
Packit 022b05
	    for (j = 0; smiElement;
Packit 022b05
		 j++, smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
		if (j) {
Packit 022b05
		    fprint(f, ", ");
Packit 022b05
		}
Packit 022b05
		fprintWrapped(f, INDENTVALUE + 2,
Packit 022b05
			      smiGetElementNode(smiElement)->name, 0);
Packit 022b05
		/* TODO: non-local name if non-local */
Packit 022b05
	    } /* TODO: empty? -> print error */
Packit 022b05
	    fprint(f, " }\n");
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (! smiv1 || ! silent) {
Packit 022b05
	    fprintSegment(f, INDENT, "STATUS", INDENTVALUE, smiv1);
Packit 022b05
	    fprint(f, "%s\n", getStatusString(smiNode->status));
Packit 022b05
	}
Packit 022b05
Packit 022b05
	fprintSegment(f, INDENT, "DESCRIPTION", INDENTVALUE, 0);
Packit 022b05
	fprint(f, "\n");
Packit 022b05
	if (smiNode->description) {
Packit 022b05
	    fprintMultilineString(f, smiNode->description, 0);
Packit 022b05
	} else {
Packit 022b05
	    fprintMultilineString(f, "...", 0);
Packit 022b05
	}
Packit 022b05
	fprint(f, "\n");
Packit 022b05
	    
Packit 022b05
	if (smiNode->reference) {
Packit 022b05
	    fprintSegment(f, INDENT, "REFERENCE", INDENTVALUE, smiv1);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    fprintMultilineString(f, smiNode->reference, smiv1);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	}
Packit 022b05
Packit 022b05
	fprintSegment(f, INDENT, "::= ", 0, 0);
Packit 022b05
	if (smiv1) {
Packit 022b05
	    fprint(f, "%d\n\n", smiNode->oid[smiNode->oidlen-1]);
Packit 022b05
	} else {
Packit 022b05
	    fprint(f, "{ %s }\n\n", getOidString(smiNode, 0));
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintGroups(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode	 *smiNode;
Packit 022b05
    SmiElement   *smiElement;
Packit 022b05
    int          j, objectGroup = 0, notificationGroup = 0;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_GROUP);
Packit 022b05
	 smiNode; smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_GROUP)) {
Packit 022b05
Packit 022b05
	objectGroup = isObjectGroup(smiNode);
Packit 022b05
	if (! objectGroup) {
Packit 022b05
	    notificationGroup = isNotificationGroup(smiNode);
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (smiv1 || (!objectGroup && !notificationGroup)) {
Packit 022b05
	    fprint(f, "%s OBJECT IDENTIFIER\n", smiNode->name);
Packit 022b05
	    fprintSegment(f, INDENT, "::= ", 0, 0);
Packit 022b05
	    fprint(f, "{ %s }\n\n", getOidString(smiNode, 0));
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (!objectGroup && !notificationGroup) {
Packit 022b05
	    continue;
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (! smiv1 || ! silent) {
Packit 022b05
Packit 022b05
	    if (smiv1) {
Packit 022b05
		fprint(f, "-- %s %s\n", smiNode->name,
Packit 022b05
		       objectGroup ? "OBJECT-GROUP" : "NOTIFICATION-GROUP");
Packit 022b05
	    } else {
Packit 022b05
		fprint(f, "%s %s\n", smiNode->name,
Packit 022b05
		       objectGroup ? "OBJECT-GROUP" : "NOTIFICATION-GROUP");
Packit 022b05
	    }
Packit 022b05
Packit 022b05
	    if (objectGroup) {
Packit 022b05
		fprintSegment(f, INDENT, "OBJECTS", INDENTVALUE, smiv1);
Packit 022b05
	    } else {
Packit 022b05
		fprintSegment(f, INDENT, "NOTIFICATIONS", INDENTVALUE, smiv1);
Packit 022b05
	    }
Packit 022b05
	    fprint(f, "{ ");
Packit 022b05
	    for (j = 0, smiElement = smiGetFirstElement(smiNode);
Packit 022b05
		 smiElement;
Packit 022b05
		 j++, smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
		if (j) {
Packit 022b05
		    fprint(f, ", ");
Packit 022b05
		}
Packit 022b05
		fprintWrapped(f, INDENTVALUE + 2,
Packit 022b05
			      smiGetElementNode(smiElement)->name, smiv1);
Packit 022b05
		/* TODO: non-local name if non-local */
Packit 022b05
	    } /* TODO: empty? -> print error */
Packit 022b05
	    fprint(f, " }\n");
Packit 022b05
	    
Packit 022b05
	    fprintSegment(f, INDENT, "STATUS", INDENTVALUE, smiv1);
Packit 022b05
	    fprint(f, "%s\n", getStatusString(smiNode->status));
Packit 022b05
	    
Packit 022b05
	    fprintSegment(f, INDENT, "DESCRIPTION", INDENTVALUE, smiv1);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    if (smiNode->description) {
Packit 022b05
		fprintMultilineString(f, smiNode->description, smiv1);
Packit 022b05
	    } else {
Packit 022b05
		fprintMultilineString(f, "...", smiv1);
Packit 022b05
	    }
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    
Packit 022b05
	    if (smiNode->reference) {
Packit 022b05
		fprintSegment(f, INDENT, "REFERENCE", INDENTVALUE, smiv1);
Packit 022b05
		fprint(f, "\n");
Packit 022b05
		fprintMultilineString(f, smiNode->reference, smiv1);
Packit 022b05
		fprint(f, "\n");
Packit 022b05
	    }
Packit 022b05
	    
Packit 022b05
	    fprintSegment(f, INDENT, "::= ", 0, smiv1);
Packit 022b05
	    fprint(f, "{ %s }\n\n", getOidString(smiNode, 0));
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void fprintModuleCompliances(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode	  *smiNode, *smiNode2;
Packit 022b05
    SmiModule     *smiModule2;
Packit 022b05
    SmiType	  *smiType;
Packit 022b05
    SmiOption	  *smiOption;
Packit 022b05
    SmiRefinement *smiRefinement;
Packit 022b05
    SmiElement    *smiElement;
Packit 022b05
    char	  *module;
Packit 022b05
    char	  *done = NULL; /* "+" separated list of module names */
Packit 022b05
    char	  s[1024];
Packit 022b05
    int		  j;
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_COMPLIANCE);
Packit 022b05
	 smiNode; smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_COMPLIANCE)) {
Packit 022b05
	
Packit 022b05
	if (smiv1) {
Packit 022b05
	    fprint(f, "%s OBJECT IDENTIFIER\n", smiNode->name);
Packit 022b05
	    fprintSegment(f, INDENT, "::= ", 0, 0);
Packit 022b05
	    fprint(f, "{ %s }\n\n", getOidString(smiNode, 0));
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (! smiv1 || ! silent) {
Packit 022b05
Packit 022b05
	    if (smiv1) {
Packit 022b05
		fprint(f, "-- %s MODULE-COMPLIANCE\n", smiNode->name);
Packit 022b05
	    } else {
Packit 022b05
		fprint(f, "%s MODULE-COMPLIANCE\n", smiNode->name);
Packit 022b05
	    }
Packit 022b05
	    
Packit 022b05
	    fprintSegment(f, INDENT, "STATUS", INDENTVALUE, smiv1);
Packit 022b05
	    fprint(f, "%s\n", getStatusString(smiNode->status));
Packit 022b05
	    
Packit 022b05
	    fprintSegment(f, INDENT, "DESCRIPTION", INDENTVALUE, smiv1);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    if (smiNode->description) {
Packit 022b05
		fprintMultilineString(f, smiNode->description, smiv1);
Packit 022b05
	    } else {
Packit 022b05
		fprintMultilineString(f, "...", smiv1);
Packit 022b05
	    }
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    
Packit 022b05
	    if (smiNode->reference) {
Packit 022b05
		fprintSegment(f, INDENT, "REFERENCE", INDENTVALUE, smiv1);
Packit 022b05
		fprint(f, "\n");
Packit 022b05
		fprintMultilineString(f, smiNode->reference, smiv1);
Packit 022b05
		fprint(f, "\n");
Packit 022b05
	    }
Packit 022b05
	    
Packit 022b05
	    /* `this module' always first */
Packit 022b05
	    done = xstrdup("+");
Packit 022b05
	    for (module = smiModule->name; module; ) {
Packit 022b05
		
Packit 022b05
		fprint(f, "\n");
Packit 022b05
		fprintSegment(f, INDENT, "MODULE", INDENTVALUE, smiv1);
Packit 022b05
		if (strlen(module) && strcmp(smiModule->name, module)) {
Packit 022b05
		    fprint(f, "%s\n", module);
Packit 022b05
		} else {
Packit 022b05
		    if (smiv1) {
Packit 022b05
			fprint(f, "-- -- this module\n");
Packit 022b05
		    } else {
Packit 022b05
			fprint(f, "-- this module\n");
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		
Packit 022b05
		for (j = 0, smiElement = smiGetFirstElement(smiNode);
Packit 022b05
		     smiElement;
Packit 022b05
		     smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
		    if (!strcmp(smiGetNodeModule(smiGetElementNode(smiElement))->name, module)) {
Packit 022b05
			if (j) {
Packit 022b05
			    fprint(f, ", ");
Packit 022b05
			} else {
Packit 022b05
			    fprint(f, "\n");
Packit 022b05
			    fprintSegment(f, 2 * INDENT, "MANDATORY-GROUPS",
Packit 022b05
					  INDENTVALUE, smiv1);
Packit 022b05
			    fprint(f, "{ ");
Packit 022b05
			}
Packit 022b05
			j++;
Packit 022b05
			fprintWrapped(f, INDENTVALUE + 2,
Packit 022b05
				      smiGetElementNode(smiElement)->name,
Packit 022b05
				      smiv1);
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		if (j) {
Packit 022b05
		    fprint(f, " }\n");
Packit 022b05
		}
Packit 022b05
		
Packit 022b05
		for(smiOption = smiGetFirstOption(smiNode); smiOption;
Packit 022b05
		    smiOption = smiGetNextOption(smiOption)) {
Packit 022b05
		    smiNode2 = smiGetOptionNode(smiOption);
Packit 022b05
		    smiModule2 = smiGetNodeModule(smiNode2);
Packit 022b05
		    if (!strcmp(smiModule2->name, module)) {
Packit 022b05
			fprint(f, "\n");
Packit 022b05
			fprintSegment(f, 2 * INDENT, "GROUP",
Packit 022b05
				      INDENTVALUE, smiv1);
Packit 022b05
			fprint(f, "%s\n", smiNode2->name);
Packit 022b05
			fprintSegment(f, 2 * INDENT, "DESCRIPTION",
Packit 022b05
				      INDENTVALUE, smiv1);
Packit 022b05
			fprint(f, "\n");
Packit 022b05
			if (smiOption->description) {
Packit 022b05
			    fprintMultilineString2(f, smiOption->description,
Packit 022b05
						  smiv1);
Packit 022b05
			} else {
Packit 022b05
			    fprintMultilineString2(f, "...", smiv1);
Packit 022b05
			}
Packit 022b05
			fprint(f, "\n");
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		
Packit 022b05
		for(smiRefinement = smiGetFirstRefinement(smiNode);
Packit 022b05
		    smiRefinement;
Packit 022b05
		    smiRefinement = smiGetNextRefinement(smiRefinement)) {
Packit 022b05
		    smiNode2 = smiGetRefinementNode(smiRefinement);
Packit 022b05
		    smiModule2 = smiGetNodeModule(smiNode2);
Packit 022b05
		    if (!strcmp(smiModule2->name, module)) {
Packit 022b05
			fprint(f, "\n");
Packit 022b05
			fprintSegment(f, 2 * INDENT, "OBJECT",
Packit 022b05
				      INDENTVALUE, smiv1);
Packit 022b05
			fprint(f, "%s\n", smiNode2->name);
Packit 022b05
Packit 022b05
			smiType = smiGetRefinementType(smiRefinement);
Packit 022b05
			if (smiType) {
Packit 022b05
			    fprintSegment(f, 2 * INDENT, "SYNTAX", INDENTVALUE,
Packit 022b05
					  smiv1);
Packit 022b05
			    fprint(f, "%s",
Packit 022b05
				   getTypeString(smiType->basetype,
Packit 022b05
						 smiGetParentType(smiType)));
Packit 022b05
			    fprintSubtype(f, smiType, smiv1);
Packit 022b05
			    fprint(f, "\n");
Packit 022b05
			}
Packit 022b05
			
Packit 022b05
			smiType = smiGetRefinementWriteType(smiRefinement);
Packit 022b05
			if (smiType) {
Packit 022b05
			    fprintSegment(f, 2 * INDENT, "WRITE-SYNTAX",
Packit 022b05
					  INDENTVALUE, smiv1);
Packit 022b05
			    fprint(f, "%s",
Packit 022b05
				   getTypeString(smiType->basetype,
Packit 022b05
						 smiGetParentType(smiType)));
Packit 022b05
			    fprintSubtype(f, smiType, smiv1);
Packit 022b05
			    fprint(f, "\n");
Packit 022b05
			}
Packit 022b05
			
Packit 022b05
			if (smiRefinement->access != SMI_ACCESS_UNKNOWN) {
Packit 022b05
			    fprintSegment(f, 2 * INDENT, "MIN-ACCESS",
Packit 022b05
					  INDENTVALUE, smiv1);
Packit 022b05
			    fprint(f, "%s\n",
Packit 022b05
				   getAccessString(smiRefinement->access, 0));
Packit 022b05
			    /* we assume, that read-create does not appear in
Packit 022b05
			     * an OT refinement.
Packit 022b05
			     */
Packit 022b05
			}
Packit 022b05
			fprintSegment(f, 2 * INDENT, "DESCRIPTION",
Packit 022b05
				      INDENTVALUE, smiv1);
Packit 022b05
			fprint(f, "\n");
Packit 022b05
			if (smiRefinement->description) {
Packit 022b05
			    fprintMultilineString2(f,
Packit 022b05
						  smiRefinement->description,
Packit 022b05
						  smiv1);
Packit 022b05
			} else {
Packit 022b05
			    fprintMultilineString2(f, "...", smiv1);
Packit 022b05
			}
Packit 022b05
			fprint(f, "\n");
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		
Packit 022b05
		/*
Packit 022b05
		 * search the next module name in the list of mandatory
Packit 022b05
		 * groups, optional groups and refinements.
Packit 022b05
		 */
Packit 022b05
		done = xrealloc(done,
Packit 022b05
				strlen(done)+strlen(module)+2*sizeof(char));
Packit 022b05
		strcat(done, module);
Packit 022b05
		strcat(done, "+");
Packit 022b05
		module = NULL;
Packit 022b05
		for (smiElement = smiGetFirstElement(smiNode);
Packit 022b05
		     smiElement;
Packit 022b05
		     smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
		    sprintf(s, "+%s+",
Packit 022b05
			smiGetNodeModule(smiGetElementNode(smiElement))->name);
Packit 022b05
		    if ((!strstr(done, s))) {
Packit 022b05
			module =
Packit 022b05
			 smiGetNodeModule(smiGetElementNode(smiElement))->name;
Packit 022b05
			break;
Packit 022b05
		    }
Packit 022b05
		}
Packit 022b05
		if (!module) {
Packit 022b05
		    ; /* TODO: search in options list */
Packit 022b05
		}
Packit 022b05
		if (!module) {
Packit 022b05
		    ; /* TODO: search in refinements list */
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    fprintSegment(f, INDENT, "::= ", 0, smiv1);
Packit 022b05
	    fprint(f, "{ %s }\n\n", getOidString(smiNode, 0));
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    xfree(done);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void dumpSmi(FILE *f, SmiModule *smiModule, int flags)
Packit 022b05
{
Packit 022b05
    if (smiModule->language == SMI_LANGUAGE_SPPI) /* PIB to MIB conversion */
Packit 022b05
        pibtomib = 1;
Packit 022b05
    else
Packit 022b05
        pibtomib = 0;
Packit 022b05
Packit 022b05
    createImportList(smiModule);
Packit 022b05
    
Packit 022b05
    fprint(f, "--\n");
Packit 022b05
    fprint(f, "-- This %s module has been generated by smidump "
Packit 022b05
	   SMI_VERSION_STRING ". Do not edit.\n", smiv1 ? "SMIv1" : "SMIv2");
Packit 022b05
    fprint(f, "--\n\n");
Packit 022b05
    if (pibtomib && smiv1) {
Packit 022b05
        fprint(f, "--\n");
Packit 022b05
        fprint(f, "-- WARNING: SPPI to SMIv1 conversion is not explicitly " \
Packit 022b05
          "supported.\n");
Packit 022b05
        fprint(f, "-- Expect flawed output.\n");
Packit 022b05
        fprint(f, "--\n\n");
Packit 022b05
    }
Packit 022b05
    if (! (flags & SMIDUMP_FLAG_SILENT) && (flags & SMIDUMP_FLAG_ERROR)) {
Packit 022b05
	fprintf(f, "--\n-- WARNING: this output may be incorrect due to "
Packit 022b05
		"significant parse errors\n--\n\n");
Packit 022b05
    }
Packit 022b05
    fprint(f, "%s%s DEFINITIONS ::= BEGIN\n\n", smiModule->name,
Packit 022b05
           (pibtomib ? "-MIB" : ""));
Packit 022b05
	
Packit 022b05
    fprintImports(f);
Packit 022b05
    fprintModuleIdentity(f, smiModule);
Packit 022b05
    fprintTypeDefinitions(f, smiModule);
Packit 022b05
    fprintTextualConventions(f, smiModule);
Packit 022b05
    fprintObjects(f, smiModule);
Packit 022b05
    fprintNotifications(f, smiModule);
Packit 022b05
    fprintGroups(f, smiModule);
Packit 022b05
    fprintModuleCompliances(f, smiModule);
Packit 022b05
    
Packit 022b05
    fprint(f, "END -- end of module %s%s.\n", smiModule->name,
Packit 022b05
           (pibtomib ? "-MIB" : ""));
Packit 022b05
Packit 022b05
    freeImportList();
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
static void dumpSmiV1(int modc, SmiModule **modv, int flags, char *output)
Packit 022b05
{
Packit 022b05
    int  i;
Packit 022b05
    FILE *f = stdout;
Packit 022b05
    
Packit 022b05
    smiv1 = 1;
Packit 022b05
    silent = (flags & SMIDUMP_FLAG_SILENT);
Packit 022b05
Packit 022b05
    if (output) {
Packit 022b05
	f = fopen(output, "w");
Packit 022b05
	if (!f) {
Packit 022b05
	    fprintf(stderr, "smidump: cannot open %s for writing: ", output);
Packit 022b05
	    perror(NULL);
Packit 022b05
	    exit(1);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    for (i = 0; i < modc; i++) {
Packit 022b05
	dumpSmi(f, modv[i], flags);
Packit 022b05
	if (fflush(f) || ferror(f)) {
Packit 022b05
	    perror("smidump: write error");
Packit 022b05
	    exit(1);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (output) {
Packit 022b05
	fclose(f);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
static void dumpSmiV2(int modc, SmiModule **modv, int flags, char *output)
Packit 022b05
{
Packit 022b05
    int  i;
Packit 022b05
    FILE *f = stdout;
Packit 022b05
Packit 022b05
    smiv1 = 0;
Packit 022b05
    silent = (flags & SMIDUMP_FLAG_SILENT);
Packit 022b05
Packit 022b05
    if (output) {
Packit 022b05
	f = fopen(output, "w");
Packit 022b05
	if (!f) {
Packit 022b05
	    fprintf(stderr, "smidump: cannot open %s for writing: ", output);
Packit 022b05
	    perror(NULL);
Packit 022b05
	    exit(1);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    for (i = 0; i < modc; i++) {
Packit 022b05
	dumpSmi(f, modv[i], flags);
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (fflush(f) || ferror(f)) {
Packit 022b05
	perror("smidump: write error");
Packit 022b05
	exit(1);
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (output) {
Packit 022b05
	fclose(f);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
void initSmi()
Packit 022b05
{
Packit 022b05
    static SmidumpDriver driver1 = {
Packit 022b05
	"smiv1",
Packit 022b05
	dumpSmiV1,
Packit 022b05
	0,
Packit 022b05
	SMIDUMP_DRIVER_CANT_UNITE,
Packit 022b05
	"SMIv1 (RFC 1155, RFC 1212, RFC 1215)",
Packit 022b05
	NULL,
Packit 022b05
	NULL
Packit 022b05
    };
Packit 022b05
    
Packit 022b05
    static SmidumpDriver driver2 = {
Packit 022b05
	"smiv2",
Packit 022b05
	dumpSmiV2,
Packit 022b05
	0,
Packit 022b05
	SMIDUMP_DRIVER_CANT_UNITE,
Packit 022b05
	"SMIv2 (RFC 2578, RFC 2579, RFC 2580)",
Packit 022b05
	NULL,
Packit 022b05
	NULL
Packit 022b05
    };
Packit 022b05
    
Packit 022b05
    smidumpRegisterDriver(&driver1);
Packit 022b05
    smidumpRegisterDriver(&driver2);
Packit 022b05
}