Blame tools/dump-sppi.c

Packit 022b05
/*
Packit 022b05
 * dump-sppi.c --
Packit 022b05
 *
Packit 022b05
 *      Operations to dump SPPI 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
 */
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
#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  INDENTMAX	72   /* max column to fill, break lines otherwise */
Packit 022b05
Packit 022b05
static char *convertType[] = {
Packit 022b05
    NULL,		 "INTEGER",	       NULL,	   "Integer32",
Packit 022b05
    NULL,		 "Bits",	       NULL,	   "BITS",
Packit 022b05
    NULL,		 "OctetString",	       NULL,	   "OCTET STRING",
Packit 022b05
    NULL,		 "ObjectIdentifier",   NULL,	   "OBJECT IDENTIFIER",
Packit 022b05
    NULL,		 "IpAddress",          NULL,	   "InetAddress",
Packit 022b05
    NULL,		 "Counter64",          NULL,	   "Unsigned64",
Packit 022b05
    NULL,		 "Counter32",          NULL,	   "Unsigned32",
Packit 022b05
    NULL,		 "Gauge32",            NULL,	   "Unsigned32",
Packit 022b05
    NULL, NULL, NULL, NULL };
Packit 022b05
Packit 022b05
static char *convertTypeMibToPib[] = {
Packit 022b05
    NULL,		 "SnmpAdminString",    NULL,	   "OCTET STRING",
Packit 022b05
    NULL, NULL, NULL, NULL };
Packit 022b05
Packit 022b05
static char *convertImport[] = {
Packit 022b05
    "SNMPv2-SMI", "Integer32",      "COPS-PR-SPPI", "Integer32",
Packit 022b05
    "SNMPv2-SMI", "Unsigned32",     "COPS-PR-SPPI", "Unsigned32",
Packit 022b05
    "SNMPv2-SMI", "TimeTicks",      "COPS-PR-SPPI", "TimeTicks",
Packit 022b05
    "SNMPv2-SMI", "IpAddress",      "INET-ADDRESS-MIB", "InetAddress",
Packit 022b05
    "SNMPv2-SMI", "MODULE-IDENTITY","COPS-PR-SPPI", "MODULE-IDENTITY",
Packit 022b05
    "SNMPv2-SMI", "MODULE-COMPLIANCE","COPS-PR-SPPI", "MODULE-COMPLIANCE",
Packit 022b05
    "SNMPv2-SMI", "OBJECT-TYPE",    "COPS-PR-SPPI", "OBJECT-TYPE",
Packit 022b05
    "SNMPv2-SMI", "OBJECT-IDENTITY","COPS-PR-SPPI", "OBJECT-IDENTITY",
Packit 022b05
    "SNMPv2-TC",  "TEXTUAL-CONVENTION","COPS-PR-SPPI", "TEXTUAL-CONVENTION",
Packit 022b05
    NULL, NULL, NULL, NULL };
Packit 022b05
Packit 022b05
static int current_column = 0;
Packit 022b05
static int silent = 0;
Packit 022b05
static int mibtopib = 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
    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
static char *getStatusString(SmiStatus status)
Packit 022b05
{
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
					     "<unknown>";
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char *getAccessString(SmiAccess access, int pibaccess)
Packit 022b05
{
Packit 022b05
    return
Packit 022b05
        (access == SMI_ACCESS_NOTIFY)	      ? "notify" :
Packit 022b05
        (access == SMI_ACCESS_INSTALL)	      ? "install" :
Packit 022b05
        (access == SMI_ACCESS_INSTALL_NOTIFY) ? "install-notify" :
Packit 022b05
        (access == SMI_ACCESS_REPORT_ONLY)    ? "report-only" :
Packit 022b05
        (access == SMI_ACCESS_NOT_ACCESSIBLE) ?
Packit 022b05
             (pibaccess == 1 ? "report-only" : "not-accessible") :
Packit 022b05
        mibtopib                              ? "notify" : 
Packit 022b05
					        "<unknown>";
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
static int isSmiOnlyType(char *type)
Packit 022b05
{
Packit 022b05
    return (!strcmp(type, "Counter32") ||
Packit 022b05
            !strcmp(type, "Counter64") ||
Packit 022b05
            !strcmp(type, "Gauge32"));
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        *typeModule, *typeName;
Packit 022b05
Packit 022b05
    typeName = smiType ? smiType->name : NULL;
Packit 022b05
    typeModule = smiType ? smiGetTypeModule(smiType)->name : NULL;
Packit 022b05
Packit 022b05
    if (typeName &&
Packit 022b05
	(basetype != SMI_BASETYPE_ENUM) &&
Packit 022b05
	(basetype != SMI_BASETYPE_BITS)) {
Packit 022b05
        if (mibtopib)
Packit 022b05
            for(i=0; convertTypeMibToPib[i+1]; i += 4) {
Packit 022b05
	        if ((!strcmp(typeName, convertTypeMibToPib[i+1])) &&
Packit 022b05
	            ((!typeModule) || (!convertTypeMibToPib[i]) ||
Packit 022b05
	             (!strcmp(typeModule, convertTypeMibToPib[i])))) {
Packit 022b05
	            return convertTypeMibToPib[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
            return "BITS";
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
	sprintf(append, " %u%s", parentNode->oid[parentNode->oidlen-1], s);
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->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 Import* addImport(char *module, char *name)
Packit 022b05
{
Packit 022b05
    Import **import, *newImport;
Packit 022b05
    int    i;
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 (mibtopib) {
Packit 022b05
        addImport("TUBS-SMI", "ibrmibtopib");
Packit 022b05
        if (smiGetFirstNode(smiModule, SMI_NODEKIND_COLUMN)) {
Packit 022b05
            addImport("COPS-PR-SPPI", "MODULE-COMPLIANCE");
Packit 022b05
            addImport("COPS-PR-SPPI", "OBJECT-GROUP");
Packit 022b05
            addImport("COPS-PR-SPPI", "OBJECT-IDENTITY");
Packit 022b05
            addImport("COPS-PR-SPPI-TC", "InstanceId");
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
		if (strlen(smiModule2->name) && smiType->name &&
Packit 022b05
                    !isSmiOnlyType(smiType->name)) {
Packit 022b05
		    addImport(smiModule2->name, smiType->name);
Packit 022b05
		}
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (smiType && smiType->basetype == SMI_BASETYPE_INTEGER32) {
Packit 022b05
	    addImport("COPS-PR-SPPI", "Integer32");
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (smiType && smiType->basetype == SMI_BASETYPE_INTEGER64) {
Packit 022b05
	    addImport("COPS-PR-SPPI", "Integer64");
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (smiType && smiType->basetype == SMI_BASETYPE_UNSIGNED32) {
Packit 022b05
	    addImport("COPS-PR-SPPI", "Unsigned32");
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (smiType && smiType->basetype == SMI_BASETYPE_UNSIGNED64) {
Packit 022b05
	    addImport("COPS-PR-SPPI", "Unsigned64");
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if ((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("COPS-PR-SPPI", "OBJECT-TYPE");
Packit 022b05
    }
Packit 022b05
Packit 022b05
    smiNode = smiGetModuleIdentityNode(smiModule);
Packit 022b05
    if (smiNode) {
Packit 022b05
	if (strcmp("COPS-PR-SPPI", smiModule->name)) {
Packit 022b05
	    addImport("COPS-PR-SPPI", "MODULE-IDENTITY");
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
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("COPS-PR-SPPI", smiModule->name)) {
Packit 022b05
		addImport("COPS-PR-SPPI", "OBJECT-IDENTITY");
Packit 022b05
	    }
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_COMPLIANCE);
Packit 022b05
    if (smiNode) {
Packit 022b05
	if (strcmp("COPS-PR-SPPI", smiModule->name)) {
Packit 022b05
	    addImport("COPS-PR-SPPI", "MODULE-COMPLIANCE");
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    for(smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_GROUP);
Packit 022b05
	smiNode;
Packit 022b05
	smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_GROUP)) {
Packit 022b05
	if (strcmp("COPS-PR-SPPI", smiModule->name)) {
Packit 022b05
	    addImport("COPS-PR-SPPI", "OBJECT-GROUP");
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    for(smiType = smiGetFirstType(smiModule);
Packit 022b05
	smiType; smiType = smiGetNextType(smiType)) {
Packit 022b05
	if (smiType->description) {
Packit 022b05
	    if (strcmp("COPS-PR-SPPI", smiModule->name)) {
Packit 022b05
		addImport("COPS-PR-SPPI", "TEXTUAL-CONVENTION");
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
        if (smiType->decl == SMI_DECL_TEXTUALCONVENTION) {
Packit 022b05
            switch (smiType->basetype) {
Packit 022b05
	    case SMI_BASETYPE_INTEGER32:
Packit 022b05
		addImport("COPS-PR-SPPI", "Integer32");
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_INTEGER64:
Packit 022b05
		addImport("COPS-PR-SPPI", "Integer64");
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
		addImport("COPS-PR-SPPI", "Unsigned32");
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_UNSIGNED64:
Packit 022b05
		addImport("COPS-PR-SPPI", "Unsigned64");
Packit 022b05
		break;
Packit 022b05
	    default:
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
	    (smiImport->module && !strcmp(smiImport->module, "SNMPv2-TC"))) &&
Packit 022b05
            !isSmiOnlyType(smiImport->name)) {
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 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_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
	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
	break;
Packit 022b05
    case SMI_BASETYPE_FLOAT32:
Packit 022b05
    case SMI_BASETYPE_FLOAT64:
Packit 022b05
    case SMI_BASETYPE_FLOAT128:
Packit 022b05
    case SMI_BASETYPE_UNKNOWN:
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;
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 (comment) {
Packit 022b05
		    fprint(f, "\n");
Packit 022b05
		    fprintSegment(f, INDENT, "", INDENTVALUE, comment);
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, comment);
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;
Packit 022b05
    int        n, j;
Packit 022b05
Packit 022b05
    /* PIBs can contain both a PIB-INDEX | EXTENDS | AUGMENTS and an
Packit 022b05
       INDEX clause. The index list's first element is the PIB-INDEX
Packit 022b05
       (or EXTENDS/AUGMENTS) followed by the elements belonging to the
Packit 022b05
       INDEX clause. */
Packit 022b05
    
Packit 022b05
    for (n = 0, smiElement = smiGetFirstElement(indexNode); smiElement;
Packit 022b05
	 n++, smiElement = smiGetNextElement(smiElement));
Packit 022b05
    if (mibtopib) {
Packit 022b05
        SmiNode *smiParentNode = smiGetParentNode(indexNode);
Packit 022b05
        size_t len = strlen(smiParentNode->name);
Packit 022b05
        char *instanceId = xmalloc(len + 11);
Packit 022b05
Packit 022b05
        strcpy(instanceId, smiParentNode->name);
Packit 022b05
        if (len > 54)
Packit 022b05
          len = 54;
Packit 022b05
        strcpy(&instanceId[len], "InstanceId");
Packit 022b05
        fprintSegment(f, INDENT, "PIB-INDEX", INDENTVALUE, 0);
Packit 022b05
        fprint(f, "{ ");
Packit 022b05
        fprintWrapped(f, INDENTVALUE + 2, instanceId, 0);
Packit 022b05
        fprint(f, " }\n");
Packit 022b05
        fprintSegment(f, INDENT, "INDEX", INDENTVALUE, 0);
Packit 022b05
        fprint(f, "{ ");
Packit 022b05
        for (j = 0, smiElement = smiGetFirstElement(indexNode); smiElement;
Packit 022b05
	     j++, smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
             if (j)
Packit 022b05
                 fprint(f, ", ");
Packit 022b05
             fprintWrapped(f, INDENTVALUE + 2,
Packit 022b05
                           smiGetElementNode(smiElement)->name, 0);
Packit 022b05
        }
Packit 022b05
        xfree(instanceId);
Packit 022b05
    }
Packit 022b05
    else
Packit 022b05
        for (j = 0, smiElement = smiGetFirstElement(indexNode); smiElement;
Packit 022b05
	     j++, smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
            if (!j) {
Packit 022b05
                switch (indexNode->indexkind) {
Packit 022b05
                    case SMI_INDEX_INDEX:
Packit 022b05
                        fprintSegment(f, INDENT, "PIB-INDEX", INDENTVALUE,
Packit 022b05
                                      comment);
Packit 022b05
                        break;
Packit 022b05
                    case SMI_INDEX_AUGMENT:
Packit 022b05
                        fprintSegment(f, INDENT, "AUGMENTS", INDENTVALUE,
Packit 022b05
                                      comment);
Packit 022b05
                        break;
Packit 022b05
                    case SMI_INDEX_SPARSE:
Packit 022b05
                        fprintSegment(f, INDENT, "EXTENDS", INDENTVALUE,
Packit 022b05
                                      comment);
Packit 022b05
                        break;
Packit 022b05
		    case SMI_INDEX_UNKNOWN:
Packit 022b05
		    case SMI_INDEX_REORDER:
Packit 022b05
		    case SMI_INDEX_EXPAND:
Packit 022b05
                        fprintSegment(f, INDENT, "-- unsupported indexing --",
Packit 022b05
				      INDENTVALUE, comment);
Packit 022b05
			break;
Packit 022b05
                }
Packit 022b05
                fprint(f, "{ ");
Packit 022b05
            } else if (j == 1) {
Packit 022b05
                fprint(f, " }\n");
Packit 022b05
                fprintSegment(f, INDENT, "INDEX", INDENTVALUE, comment);
Packit 022b05
                fprint(f, "{ ");
Packit 022b05
            } else
Packit 022b05
	        fprint(f, ", ");
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 fprintUniqueness(FILE *f, SmiNode *indexNode, const int comment)
Packit 022b05
{
Packit 022b05
    SmiElement *smiElement;
Packit 022b05
    int        j;
Packit 022b05
Packit 022b05
    smiElement = smiGetFirstUniquenessElement(indexNode);
Packit 022b05
    if (!smiElement)
Packit 022b05
        return;
Packit 022b05
    fprintSegment(f, INDENT, "UNIQUENESS", INDENTVALUE, comment);
Packit 022b05
    fprint(f, "{ ");
Packit 022b05
    for (j = 0; smiElement; j++,
Packit 022b05
         smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
        if (j)
Packit 022b05
	    fprint(f, ", ");
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 fprintInstallErrors(FILE *f, SmiNode *indexNode, const int comment)
Packit 022b05
{
Packit 022b05
    SmiElement *smiElement;
Packit 022b05
    SmiNode    *smiNode;
Packit 022b05
    int        j;
Packit 022b05
    char       *id;
Packit 022b05
Packit 022b05
    smiElement = smiGetFirstElement(indexNode);
Packit 022b05
    if (!smiElement)
Packit 022b05
        return;
Packit 022b05
    fprintSegment(f, INDENT, "INSTALL-ERRORS", INDENTVALUE, comment);
Packit 022b05
    fprint(f, "{ ");
Packit 022b05
    for (j = 0; smiElement; j++,
Packit 022b05
         smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
        smiNode = smiGetElementNode(smiElement);
Packit 022b05
        id = xmalloc(strlen(smiNode->name) + 10);
Packit 022b05
        sprintf(id, "%s (%ld)%s", smiNode->name,
Packit 022b05
                smiNode->oidlen ? (long)smiNode->oid : 0,
Packit 022b05
                smiGetNextElement(smiElement) ? ", " : "");
Packit 022b05
        fprintWrapped(f, 2+INDENTVALUE, id, 0);
Packit 022b05
        xfree(id);
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
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, *smiNode2;
Packit 022b05
    SmiElement   *smiElement;
Packit 022b05
    char         *id;
Packit 022b05
Packit 022b05
    smiNode = smiGetModuleIdentityNode(smiModule);
Packit 022b05
    
Packit 022b05
    if (smiNode) {
Packit 022b05
Packit 022b05
        fprint(f, "%s MODULE-IDENTITY\n", smiNode->name);
Packit 022b05
        fprintSegment(f, INDENT, "SUBJECT-CATEGORIES", INDENTVALUE, 0);
Packit 022b05
        fprint(f, "{ ");
Packit 022b05
        smiElement = smiGetFirstElement(smiNode);
Packit 022b05
        if (smiElement && smiGetElementNode(smiElement))
Packit 022b05
        {
Packit 022b05
            for (; smiElement; smiElement = smiGetNextElement(smiElement)) {
Packit 022b05
                smiNode2 = smiGetElementNode(smiElement);
Packit 022b05
                id = xmalloc(strlen(smiNode2->name) + 10);
Packit 022b05
                if (smiNode2->oidlen)
Packit 022b05
                    sprintf(id, "%s (%ld)%s", smiNode2->name, (long)smiNode2->oid,
Packit 022b05
                            smiGetNextElement(smiElement) ? ", " : "");
Packit 022b05
                else
Packit 022b05
                    sprintf(id, "%s%s", smiNode2->name,
Packit 022b05
                            smiGetNextElement(smiElement) ? ", " : "");
Packit 022b05
                fprintWrapped(f, 2+INDENTVALUE, id, 0);
Packit 022b05
                xfree(id);
Packit 022b05
            }
Packit 022b05
            fprint(f, " }\n");
Packit 022b05
        } else {
Packit 022b05
        /* No SUBJECT-CATEGORIES entry was present, add one */
Packit 022b05
            fprint(f, "all } -- added by smidump\n");
Packit 022b05
        }
Packit 022b05
	fprintSegment(f, INDENT, "LAST-UPDATED", INDENTVALUE, 0);
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, 0);
Packit 022b05
	fprint(f, "\n");
Packit 022b05
	fprintMultilineString(f, smiModule->organization, 0);
Packit 022b05
	fprint(f, "\n");
Packit 022b05
	fprintSegment(f, INDENT, "CONTACT-INFO", INDENTVALUE, 0);
Packit 022b05
	fprint(f, "\n");
Packit 022b05
	fprintMultilineString(f, smiModule->contactinfo, 0);
Packit 022b05
	fprint(f, "\n");
Packit 022b05
	fprintSegment(f, INDENT, "DESCRIPTION", INDENTVALUE, 0);
Packit 022b05
	fprint(f, "\n");
Packit 022b05
	if (smiModule->description) {
Packit 022b05
	    fprintMultilineString(f, smiModule->description, 0);
Packit 022b05
	} else {
Packit 022b05
	    fprintMultilineString(f, "...", 0);
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, 0);
Packit 022b05
		fprint(f, "\"%s\"\n", getTimeString(smiRevision->date));
Packit 022b05
		fprintSegment(f, INDENT, "DESCRIPTION", INDENTVALUE,
Packit 022b05
			      0);
Packit 022b05
		fprint(f, "\n");
Packit 022b05
		if (smiRevision->description) {
Packit 022b05
		    fprintMultilineString(f, smiRevision->description,
Packit 022b05
					  0);
Packit 022b05
		} else {
Packit 022b05
		    fprintMultilineString(f, "...", 0);
Packit 022b05
		}
Packit 022b05
		fprint(f, "\n");
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
Packit 022b05
	if (smiNode) {
Packit 022b05
	    fprintSegment(f, INDENT, "::= ", 0, 0);
Packit 022b05
            if (!mibtopib)
Packit 022b05
	        fprint(f, "{ %s }\n\n", getOidString(smiNode, 0));
Packit 022b05
            else
Packit 022b05
                fprint(f, "{ ibrmibtopib %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
static void fprintTypeDefinitions(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiType	 *smiType;
Packit 022b05
    int		 invalid;
Packit 022b05
Packit 022b05
    for(smiType = smiGetFirstType(smiModule);
Packit 022b05
	smiType; smiType = smiGetNextType(smiType)) {
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
Packit 022b05
static void fprintTextualConventions(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiType	 *smiType;
Packit 022b05
    int		 invalid;
Packit 022b05
    
Packit 022b05
    for(smiType = smiGetFirstType(smiModule);
Packit 022b05
	smiType; smiType = smiGetNextType(smiType)) {
Packit 022b05
	if (smiType->status != SMI_STATUS_UNKNOWN) {
Packit 022b05
	    invalid = invalidType(smiType->basetype);
Packit 022b05
            fprint(f, "%s ::= TEXTUAL-CONVENTION\n", smiType->name);
Packit 022b05
Packit 022b05
	    if (smiType->format) {
Packit 022b05
		fprintSegment(f, INDENT, "DISPLAY-HINT", INDENTVALUE,
Packit 022b05
			      invalid);
Packit 022b05
		fprint(f, "\"%s\"\n", smiType->format);
Packit 022b05
	    }
Packit 022b05
Packit 022b05
	    fprintSegment(f, INDENT, "STATUS", INDENTVALUE,
Packit 022b05
			  invalid);
Packit 022b05
	    fprint(f, "%s\n", getStatusString(smiType->status));
Packit 022b05
Packit 022b05
	    fprintSegment(f, INDENT, "DESCRIPTION", INDENTVALUE,
Packit 022b05
			  invalid);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    if (smiType->description) {
Packit 022b05
		fprintMultilineString(f, smiType->description,
Packit 022b05
				      invalid);
Packit 022b05
	    } else {
Packit 022b05
		fprintMultilineString(f, "...", invalid);
Packit 022b05
	    }
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
Packit 022b05
	    if (smiType->reference) {
Packit 022b05
		fprintSegment(f, INDENT, "REFERENCE", INDENTVALUE,
Packit 022b05
			      invalid);
Packit 022b05
		fprint(f, "\n");
Packit 022b05
		fprintMultilineString(f, smiType->reference,
Packit 022b05
				      invalid);
Packit 022b05
		fprint(f, "\n");
Packit 022b05
	    }
Packit 022b05
	    fprintSegment(f, INDENT, "SYNTAX", INDENTVALUE,
Packit 022b05
			  invalid);
Packit 022b05
	    fprint(f, "%s",
Packit 022b05
		   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
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, addinstanceid;
Packit 022b05
    
Packit 022b05
    nodekinds =  SMI_NODEKIND_NODE | SMI_NODEKIND_TABLE |
Packit 022b05
	SMI_NODEKIND_ROW | SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR;
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
	    fprint(f, "%s OBJECT-IDENTITY\n", smiNode->name);
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)) {	    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->nodekind == SMI_NODEKIND_TABLE) {
Packit 022b05
	    fprintSegment(f, INDENT, "PIB-ACCESS", INDENTVALUE, 0);
Packit 022b05
	    fprint(f, "%s\n", getAccessString(smiNode->access, 1));
Packit 022b05
	}
Packit 022b05
Packit 022b05
        if (! assignement && smiType && smiType->name &&
Packit 022b05
            !strcmp(smiType->name, "ReferenceId")) {
Packit 022b05
            relatedNode = smiGetRelatedNode(smiNode);
Packit 022b05
            if (relatedNode) {
Packit 022b05
                fprintSegment(f, INDENT, "PIB-REFERENCES", INDENTVALUE, 0);
Packit 022b05
                fprint(f, "{ %s }\n", relatedNode->name);
Packit 022b05
            }
Packit 022b05
        }
Packit 022b05
Packit 022b05
        if (! assignement && smiType && smiType->name &&
Packit 022b05
            !strcmp(smiType->name, "TagReferenceId")) {
Packit 022b05
            relatedNode = smiGetRelatedNode(smiNode);
Packit 022b05
            if (relatedNode) {
Packit 022b05
                fprintSegment(f, INDENT, "PIB-TAG", INDENTVALUE, 0);
Packit 022b05
                fprint(f, "{ %s }\n", relatedNode->name);
Packit 022b05
            }
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 (smiNode->nodekind == SMI_NODEKIND_TABLE)
Packit 022b05
            fprintInstallErrors(f, smiNode, invalid);
Packit 022b05
	    
Packit 022b05
	if (! assignement && smiNode->reference) {
Packit 022b05
	    fprintSegment(f, INDENT, "REFERENCE", INDENTVALUE, invalid);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    fprintMultilineString(f, smiNode->reference, 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
	    fprintIndex(f, smiNode, invalid);
Packit 022b05
	    break;
Packit 022b05
	case SMI_INDEX_AUGMENT:
Packit 022b05
	    fprintSegment(f, INDENT, "AUGMENTS", INDENTVALUE, invalid);
Packit 022b05
	    fprint(f, "{ %s }\n", relatedNode->name);
Packit 022b05
	    break;
Packit 022b05
	case SMI_INDEX_SPARSE:
Packit 022b05
	    fprintSegment(f, INDENT, "EXTENDS", INDENTVALUE, invalid);
Packit 022b05
	    fprint(f, "{ %s }\n", relatedNode->name);
Packit 022b05
	    break;
Packit 022b05
	case SMI_INDEX_UNKNOWN:
Packit 022b05
	case SMI_INDEX_REORDER:
Packit 022b05
	case SMI_INDEX_EXPAND:
Packit 022b05
	    break;
Packit 022b05
	}
Packit 022b05
	
Packit 022b05
        if (smiNode->nodekind == SMI_NODEKIND_ROW)
Packit 022b05
            fprintUniqueness(f, smiNode, invalid);
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
        addinstanceid = 0;
Packit 022b05
	if (smiNode->nodekind == SMI_NODEKIND_ROW) {
Packit 022b05
            if (mibtopib)
Packit 022b05
                addinstanceid = 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 (mibtopib) {
Packit 022b05
                int len = strlen(smiParentNode->name) + 10;
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 (mibtopib) {
Packit 022b05
                size_t len = strlen(smiParentNode->name);
Packit 022b05
                int maxid;
Packit 022b05
                char *instanceId = xmalloc(len + 11);
Packit 022b05
                strcpy(instanceId, smiParentNode->name);
Packit 022b05
                if (len > 54)
Packit 022b05
                  len = 54;
Packit 022b05
                strcpy(&instanceId[len], "InstanceId");
Packit 022b05
                fprint(f, ",\n");
Packit 022b05
                fprintSegment(f, INDENT, instanceId, indentsequence, 0);
Packit 022b05
                fprint(f, "InstanceId\n}\n\n");
Packit 022b05
                
Packit 022b05
                fprint(f, "%s OBJECT-TYPE\n", instanceId);
Packit 022b05
	        fprintSegment(f, INDENT, "SYNTAX", INDENTVALUE, 0);
Packit 022b05
                fprint(f, "InstanceId\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
                                      "MIB to PIB 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(instanceId);
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 fprintGroups(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode	 *smiNode;
Packit 022b05
    SmiElement   *smiElement;
Packit 022b05
    int          j, objectGroup = 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
Packit 022b05
	if (!objectGroup) {
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) {
Packit 022b05
	    continue;
Packit 022b05
	}
Packit 022b05
Packit 022b05
	fprint(f, "%s %s\n", smiNode->name, "OBJECT-GROUP");
Packit 022b05
	fprintSegment(f, INDENT, "OBJECTS", INDENTVALUE, 0);
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, 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
	fprintSegment(f, INDENT, "STATUS", INDENTVALUE, 0);
Packit 022b05
	fprint(f, "%s\n", getStatusString(smiNode->status));
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, 0);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    fprintMultilineString(f, smiNode->reference, 0);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	}
Packit 022b05
Packit 022b05
	fprintSegment(f, INDENT, "::= ", 0, 0);
Packit 022b05
	fprint(f, "{ %s }\n\n", getOidString(smiNode, 0));
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
	fprint(f, "%s MODULE-COMPLIANCE\n", smiNode->name);
Packit 022b05
Packit 022b05
	fprintSegment(f, INDENT, "STATUS", INDENTVALUE, 0);
Packit 022b05
	fprint(f, "%s\n", getStatusString(smiNode->status));
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, 0);
Packit 022b05
	    fprint(f, "\n");
Packit 022b05
	    fprintMultilineString(f, smiNode->reference, 0);
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, 0);
Packit 022b05
	    if (strlen(module) && strcmp(smiModule->name, module)) {
Packit 022b05
		fprint(f, "%s\n", module);
Packit 022b05
	    } else {
Packit 022b05
		fprint(f, "-- this module\n");
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, 0);
Packit 022b05
			fprint(f, "{ ");
Packit 022b05
		    }
Packit 022b05
		    j++;
Packit 022b05
		    fprintWrapped(f, INDENTVALUE + 2,
Packit 022b05
				  smiGetElementNode(smiElement)->name,
Packit 022b05
				  0);
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, 0);
Packit 022b05
		    fprint(f, "%s\n", smiNode2->name);
Packit 022b05
		    fprintSegment(f, 2 * INDENT, "DESCRIPTION",
Packit 022b05
				  INDENTVALUE, 0);
Packit 022b05
		    fprint(f, "\n");
Packit 022b05
		    if (smiOption->description) {
Packit 022b05
			fprintMultilineString(f, smiOption->description,
Packit 022b05
					      0);
Packit 022b05
		    } else {
Packit 022b05
			fprintMultilineString(f, "...", 0);
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, 0);
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
				      0);
Packit 022b05
			fprint(f, "%s",
Packit 022b05
			       getTypeString(smiType->basetype,
Packit 022b05
					     smiGetParentType(smiType)));
Packit 022b05
			fprintSubtype(f, smiType, 0);
Packit 022b05
			fprint(f, "\n");
Packit 022b05
		    }
Packit 022b05
Packit 022b05
/*		    if ((smiRefinement->access == SMI_ACCESS_NOTIFY) ||
Packit 022b05
                        (smiRefinement->access >= SMI_REPORT_ONLY)) {*/
Packit 022b05
                    if (smiRefinement->access != SMI_ACCESS_UNKNOWN) {
Packit 022b05
			fprintSegment(f, 2 * INDENT, "PIB-MIN-ACCESS",
Packit 022b05
				      INDENTVALUE, 0);
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, 0);
Packit 022b05
		    fprint(f, "\n");
Packit 022b05
		    if (smiRefinement->description) {
Packit 022b05
			fprintMultilineString(f,
Packit 022b05
					      smiRefinement->description,
Packit 022b05
					      0);
Packit 022b05
		    } else {
Packit 022b05
			fprintMultilineString(f, "...", 0);
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, 0);
Packit 022b05
	fprint(f, "{ %s }\n\n", getOidString(smiNode, 0));
Packit 022b05
    }
Packit 022b05
    xfree(done);
Packit 022b05
    
Packit 022b05
    if (mibtopib) {
Packit 022b05
        char *newCompliance = xmalloc(65);
Packit 022b05
        char *newGroup = xmalloc(65);
Packit 022b05
        char *newId = xmalloc(65);
Packit 022b05
        int len, maxid;
Packit 022b05
        
Packit 022b05
        for (maxid = 0, smiNode2 = smiGetFirstChildNode(smiNode);
Packit 022b05
             smiNode2; smiNode2 = smiGetNextChildNode(smiNode2))
Packit 022b05
             if (smiNode2->oidlen &&
Packit 022b05
                 (smiNode2->oid[smiNode2->oidlen - 1] > maxid))
Packit 022b05
                 maxid = smiNode2->oid[smiNode2->oidlen - 1];
Packit 022b05
        maxid++;
Packit 022b05
Packit 022b05
        smiNode = smiGetModuleIdentityNode(smiModule);
Packit 022b05
        if (!smiNode || !newCompliance || !newGroup)
Packit 022b05
            return;
Packit 022b05
        len = strlen(smiNode->name);
Packit 022b05
        
Packit 022b05
        memset(newId, 0, 65);
Packit 022b05
        strncpy(newId, smiNode->name, 46);
Packit 022b05
        strcat(newId + (len > 46 ? 46 : len), "MIBtoPIBCompliance");
Packit 022b05
Packit 022b05
        memset(newCompliance, 0, 65);
Packit 022b05
        strncpy(newCompliance, smiNode->name, 46);
Packit 022b05
        strcat(newCompliance + (len > 46 ? 46 : len), "MIBtoPIBModuleComp");
Packit 022b05
Packit 022b05
        memset(newGroup, 0, 65);
Packit 022b05
        strncpy(newGroup, smiNode->name, 51);
Packit 022b05
        strcat(newGroup + (len > 51 ? 51 : len), "MIBtoPIBGroup");
Packit 022b05
Packit 022b05
        fprintf(f, "-- The following three items were added in order " \
Packit 022b05
                "to create a RFC compliant\n-- SPPI module. They do not " \
Packit 022b05
                "provide any usable content.\n-- %s\n-- %s\n-- %s\n\n",
Packit 022b05
                newId, newCompliance, newGroup);
Packit 022b05
        
Packit 022b05
        fprint(f, "%s OBJECT-IDENTITY\n", newId);
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
                              "MIB to PIB conversion.", 0);
Packit 022b05
	fprint(f, "\n");
Packit 022b05
	fprintSegment(f, INDENT, "::= ", 0, 0);
Packit 022b05
	fprint(f, "{ %s %d }\n\n", smiNode->name, (maxid > 128 ? maxid : 128));
Packit 022b05
        
Packit 022b05
        fprint(f, "%s MODULE-COMPLIANCE\n", newCompliance);
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
                              "MIB to PIB conversion.", 0);
Packit 022b05
	fprint(f, "\n");
Packit 022b05
        
Packit 022b05
        fprintSegment(f, INDENT, "MODULE", INDENTVALUE, 0);
Packit 022b05
        fprint(f, "-- this module\n");
Packit 022b05
        
Packit 022b05
        fprintSegment(f, 2 * INDENT, "MANDATORY-GROUPS", INDENTVALUE, 0);
Packit 022b05
        fprint(f, "{ ");
Packit 022b05
        
Packit 022b05
	fprintWrapped(f, INDENTVALUE + 2, newGroup, 0);
Packit 022b05
        fprint(f, "}\n");
Packit 022b05
        
Packit 022b05
	fprintSegment(f, INDENT, "::= ", 0, 0);
Packit 022b05
	fprint(f, "{ %s 1 }\n\n", newId);
Packit 022b05
Packit 022b05
	fprint(f, "%s OBJECT-GROUP\n", newGroup);
Packit 022b05
	fprintSegment(f, INDENT, "OBJECTS", INDENTVALUE, 0);
Packit 022b05
	fprint(f, "{ ");
Packit 022b05
        for (len=0, smiNode2 = smiGetFirstNode(smiModule, SMI_NODEKIND_COLUMN);
Packit 022b05
            smiNode2; len = 1,
Packit 022b05
            smiNode2 = smiGetNextNode(smiNode2, SMI_NODEKIND_COLUMN)) {
Packit 022b05
            if (len)
Packit 022b05
                fprint(f, ", ");
Packit 022b05
	    fprintWrapped(f, INDENTVALUE + 2, smiNode2->name, 0);
Packit 022b05
        }
Packit 022b05
        for (smiNode2 = smiGetFirstNode(smiModule, SMI_NODEKIND_ROW);
Packit 022b05
             smiNode2; smiNode2 = smiGetNextNode(smiNode2, SMI_NODEKIND_ROW)) {
Packit 022b05
            SmiNode *smiParentNode = smiGetParentNode(smiNode2);
Packit 022b05
            size_t len = strlen(smiParentNode->name);
Packit 022b05
            char *instanceId = xmalloc(len + 11);
Packit 022b05
Packit 022b05
            strcpy(instanceId, smiParentNode->name);
Packit 022b05
            if (len > 54)
Packit 022b05
              len = 54;
Packit 022b05
            strcpy(&instanceId[len], "InstanceId");
Packit 022b05
            if (len)
Packit 022b05
                fprint(f, ", ");
Packit 022b05
	    fprintWrapped(f, INDENTVALUE + 2, instanceId, 0);
Packit 022b05
            xfree(instanceId);
Packit 022b05
        }
Packit 022b05
Packit 022b05
	fprint(f, " }\n");
Packit 022b05
Packit 022b05
	fprintSegment(f, INDENT, "STATUS", INDENTVALUE, 0);
Packit 022b05
	fprint(f, "current\n");
Packit 022b05
Packit 022b05
	fprintSegment(f, INDENT, "DESCRIPTION", INDENTVALUE, 0);
Packit 022b05
	fprint(f, "\n");
Packit 022b05
	fprintMultilineString(f, "Added by smidump for automatic" \
Packit 022b05
                              "MIB to PIB conversion.", 0);
Packit 022b05
	fprint(f, "\n");
Packit 022b05
Packit 022b05
	fprintSegment(f, INDENT, "::= ", 0, 0);
Packit 022b05
	fprint(f, "{ %s 2 }\n\n", newId);
Packit 022b05
Packit 022b05
        xfree(newCompliance);
Packit 022b05
        xfree(newGroup);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void doDumpSppi(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    if (smiModule->language != SMI_LANGUAGE_SPPI) /* MIB to PIB conversion */
Packit 022b05
        mibtopib = 1;
Packit 022b05
    else
Packit 022b05
        mibtopib = 0;
Packit 022b05
Packit 022b05
    createImportList(smiModule);
Packit 022b05
    
Packit 022b05
    fprint(f, "--\n");
Packit 022b05
    fprint(f, "-- This SPPI module has been generated by smidump "
Packit 022b05
	   SMI_VERSION_STRING ". Do not edit.\n");
Packit 022b05
    fprint(f, "--\n\n");
Packit 022b05
    fprint(f, "%s%s PIB-DEFINITIONS ::= BEGIN\n\n", smiModule->name,
Packit 022b05
           mibtopib ? "-PIB" : "");
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
    fprintGroups(f, smiModule);
Packit 022b05
    fprintModuleCompliances(f, smiModule);
Packit 022b05
    
Packit 022b05
    fprint(f, "END -- end of module %s.\n", smiModule->name);
Packit 022b05
Packit 022b05
    freeImportList();
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
static void dumpSppi(int modc, SmiModule **modv, int flags, char *output)
Packit 022b05
{
Packit 022b05
    int  i;
Packit 022b05
    FILE *f = stdout;
Packit 022b05
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
	doDumpSppi(f, modv[i]);
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 initSppi()
Packit 022b05
{
Packit 022b05
    static SmidumpDriver driver = {
Packit 022b05
	"sppi",
Packit 022b05
	dumpSppi,
Packit 022b05
	0,
Packit 022b05
	SMIDUMP_DRIVER_CANT_UNITE,
Packit 022b05
	"SPPI (RFC 3159)",
Packit 022b05
	NULL,
Packit 022b05
	NULL
Packit 022b05
    };
Packit 022b05
    
Packit 022b05
    smidumpRegisterDriver(&driver);
Packit 022b05
}