Blame tools/dump-netsnmp.c

Packit 022b05
/*
Packit 022b05
 * dump-netsnmp.c --
Packit 022b05
 *
Packit 022b05
 *      Operations to generate NET-SNMP mib module implementation code.
Packit 022b05
 *
Packit 022b05
 * Copyright (c) 1999 Frank Strauss, Technical University of Braunschweig.
Packit 022b05
 * Copyright (c) 1999 J. Schoenwaelder, 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-netsnmp.c 8090 2008-04-18 12:56:29Z strauss $
Packit 022b05
 */
Packit 022b05
Packit 022b05
/*
Packit 022b05
 * TODO:
Packit 022b05
 *	  - assume that we build a dynamic loadable module
Packit 022b05
 *	  - update to 4.X version of the UCD API
Packit 022b05
 *	  - generate #defines for deprecated and obsolete objects
Packit 022b05
 *	  - generate stub codes for the various functions
Packit 022b05
 *	  - generate type and range checking code
Packit 022b05
 */
Packit 022b05
Packit 022b05
#include <config.h>
Packit 022b05
Packit 022b05
#include <stdlib.h>
Packit 022b05
#include <stdio.h>
Packit 022b05
#include <string.h>
Packit 022b05
#include <ctype.h>
Packit 022b05
#ifdef HAVE_UNISTD_H
Packit 022b05
#include <unistd.h>
Packit 022b05
#endif
Packit 022b05
#ifdef HAVE_WIN_H
Packit 022b05
#include "win.h"
Packit 022b05
#endif
Packit 022b05
Packit 022b05
#include "smi.h"
Packit 022b05
#include "smidump.h"
Packit 022b05
Packit 022b05
Packit 022b05
static int noMgrStubs = 0;
Packit 022b05
static int noAgtStubs = 0;
Packit 022b05
Packit 022b05
Packit 022b05
static char *getAccessString(SmiAccess access)
Packit 022b05
{
Packit 022b05
    if (access == SMI_ACCESS_READ_WRITE) {
Packit 022b05
	return "RWRITE";
Packit 022b05
    } else if (access == SMI_ACCESS_READ_ONLY) {
Packit 022b05
	return "RONLY";
Packit 022b05
    } else {
Packit 022b05
	return "";
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
static char *getBaseTypeString(SmiBasetype basetype)
Packit 022b05
{
Packit 022b05
    switch(basetype) {
Packit 022b05
    case SMI_BASETYPE_UNKNOWN:
Packit 022b05
	return "ASN_NULL";
Packit 022b05
    case SMI_BASETYPE_POINTER:
Packit 022b05
	return "ASN_NULL";
Packit 022b05
    case SMI_BASETYPE_INTEGER32:
Packit 022b05
    case SMI_BASETYPE_ENUM:
Packit 022b05
	return "ASN_INTEGER";
Packit 022b05
    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
    case SMI_BASETYPE_BITS:
Packit 022b05
	return "ASN_OCTET_STR";
Packit 022b05
    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
	return "ASN_OBJECT_ID";
Packit 022b05
    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
	return "ASN_INTEGER";
Packit 022b05
    case SMI_BASETYPE_INTEGER64:
Packit 022b05
	return "ASN_INTEGER";
Packit 022b05
    case SMI_BASETYPE_UNSIGNED64:
Packit 022b05
	return "ASN_INTEGER";
Packit 022b05
    case SMI_BASETYPE_FLOAT32:
Packit 022b05
    case SMI_BASETYPE_FLOAT64:
Packit 022b05
    case SMI_BASETYPE_FLOAT128:
Packit 022b05
	return "ASN_Real";
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return NULL;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char* translate(char *m)
Packit 022b05
{
Packit 022b05
    char *s;
Packit 022b05
    int i;
Packit 022b05
Packit 022b05
    s = xstrdup(m);
Packit 022b05
    for (i = 0; s[i]; i++) {
Packit 022b05
	if (s[i] == '-') s[i] = '_';
Packit 022b05
    }
Packit 022b05
  
Packit 022b05
    return s;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char* translateUpper(char *m)
Packit 022b05
{
Packit 022b05
    char *s;
Packit 022b05
    int i;
Packit 022b05
Packit 022b05
    s = xstrdup(m);
Packit 022b05
    for (i = 0; s[i]; i++) {
Packit 022b05
	if (s[i] == '-') s[i] = '_';
Packit 022b05
	if (islower((int) s[i])) {
Packit 022b05
	    s[i] = toupper(s[i]);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
  
Packit 022b05
    return s;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char* translateLower(char *m)
Packit 022b05
{
Packit 022b05
    char *s;
Packit 022b05
    int i;
Packit 022b05
Packit 022b05
    s = xstrdup(m);
Packit 022b05
    for (i = 0; s[i]; i++) {
Packit 022b05
	if (s[i] == '-') s[i] = '_';
Packit 022b05
	if (isupper((int) s[i])) {
Packit 022b05
	    s[i] = tolower(s[i]);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
  
Packit 022b05
    return s;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static char* translateFileName(char *m)
Packit 022b05
{
Packit 022b05
    char *s;
Packit 022b05
    int i;
Packit 022b05
Packit 022b05
    s = xstrdup(m);
Packit 022b05
    for (i = 0; s[i]; i++) {
Packit 022b05
	if (s[i] == '_') s[i] = '-';
Packit 022b05
	if (isupper((int) s[i])) {
Packit 022b05
	    s[i] = tolower(s[i]);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
  
Packit 022b05
    return s;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static FILE * createFile(char *name, char *suffix)
Packit 022b05
{
Packit 022b05
    char *fullname;
Packit 022b05
    FILE *f;
Packit 022b05
Packit 022b05
    fullname = xmalloc(strlen(name) + (suffix ? strlen(suffix) : 0) + 2);
Packit 022b05
    strcpy(fullname, name);
Packit 022b05
    if (suffix) {
Packit 022b05
        strcat(fullname, suffix);
Packit 022b05
    }
Packit 022b05
    if (!access(fullname, R_OK)) {
Packit 022b05
        fprintf(stderr, "smidump: %s already exists\n", fullname);
Packit 022b05
        xfree(fullname);
Packit 022b05
        return NULL;
Packit 022b05
    }
Packit 022b05
    f = fopen(fullname, "w");
Packit 022b05
    if (!f) {
Packit 022b05
        fprintf(stderr, "smidump: cannot open %s for writing: ", fullname);
Packit 022b05
        perror(NULL);
Packit 022b05
        xfree(fullname);
Packit 022b05
        exit(1);
Packit 022b05
    }
Packit 022b05
    xfree(fullname);
Packit 022b05
    return f;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int isGroup(SmiNode *smiNode)
Packit 022b05
{
Packit 022b05
    SmiNode *childNode;
Packit 022b05
Packit 022b05
    if (smiNode->nodekind == SMI_NODEKIND_ROW) {
Packit 022b05
	return 1;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    for (childNode = smiGetFirstChildNode(smiNode);
Packit 022b05
	 childNode;
Packit 022b05
	 childNode = smiGetNextChildNode(childNode)) {
Packit 022b05
	if (childNode->nodekind == SMI_NODEKIND_SCALAR) {
Packit 022b05
	    return 1;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return 0;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static int isAccessible(SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    int num = 0;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if ((smiNode->nodekind == SMI_NODEKIND_SCALAR
Packit 022b05
	     || smiNode->nodekind == SMI_NODEKIND_COLUMN)
Packit 022b05
	    && (smiNode->access == SMI_ACCESS_READ_ONLY
Packit 022b05
		|| smiNode->access == SMI_ACCESS_READ_WRITE)) {
Packit 022b05
	    num++;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    return num;
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void printHeaderTypedef(FILE *f, SmiModule *smiModule,
Packit 022b05
			       SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    SmiType *smiType;
Packit 022b05
    char    *cModuleName, *cGroupName, *cName;
Packit 022b05
    unsigned minSize, maxSize;
Packit 022b05
Packit 022b05
    cModuleName = translateLower(smiModule->name);
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "/*\n"
Packit 022b05
	    " * C type definitions for %s::%s.\n"
Packit 022b05
	    " */\n\n",
Packit 022b05
	    smiModule->name, groupNode->name);
Packit 022b05
    
Packit 022b05
    fprintf(f, "typedef struct %s {\n", cGroupName);
Packit 022b05
	    
Packit 022b05
    for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
Packit 022b05
#if 0
Packit 022b05
	    && (smiNode->access == SMI_ACCESS_READ_ONLY
Packit 022b05
		|| smiNode->access == SMI_ACCESS_READ_WRITE)
Packit 022b05
#endif
Packit 022b05
	    ) {
Packit 022b05
	    smiType = smiGetNodeType(smiNode);
Packit 022b05
	    if (!smiType) {
Packit 022b05
		continue;
Packit 022b05
	    }
Packit 022b05
	    
Packit 022b05
	    cName = translate(smiNode->name);
Packit 022b05
	    switch (smiType->basetype) {
Packit 022b05
	    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
		maxSize = smiGetMaxSize(smiType);
Packit 022b05
		minSize = smiGetMinSize(smiType);
Packit 022b05
		fprintf(f,
Packit 022b05
			"    uint32_t  *%s;\n", cName);
Packit 022b05
		if (maxSize != minSize) {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    size_t    _%sLength;\n", cName);
Packit 022b05
		}
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
	    case SMI_BASETYPE_BITS:
Packit 022b05
		maxSize = smiGetMaxSize(smiType);
Packit 022b05
		minSize = smiGetMinSize(smiType);
Packit 022b05
		fprintf(f,
Packit 022b05
			"    u_char    *%s;\n", cName);
Packit 022b05
		if (maxSize != minSize) {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "    size_t    _%sLength;\n", cName);
Packit 022b05
		}
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_ENUM:
Packit 022b05
	    case SMI_BASETYPE_INTEGER32:
Packit 022b05
		fprintf(f,
Packit 022b05
			"    int32_t   *%s;\n", cName);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
		fprintf(f,
Packit 022b05
			"    uint32_t  *%s;\n", cName);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_INTEGER64:
Packit 022b05
		fprintf(f,
Packit 022b05
			"    int64_t   *%s; \n", cName);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_UNSIGNED64:
Packit 022b05
		fprintf(f,
Packit 022b05
			"    uint64_t  *%s; \n", cName);
Packit 022b05
		break;
Packit 022b05
	    default:
Packit 022b05
		fprintf(f,
Packit 022b05
			"    /* ?? */  __%s; \n", cName);
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	    xfree(cName);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    void      *_clientData;\t\t"
Packit 022b05
	    "/* pointer to client data structure */\n");
Packit 022b05
    if (groupNode->nodekind == SMI_NODEKIND_ROW) {
Packit 022b05
	fprintf(f, "    struct %s *_nextPtr;\t"
Packit 022b05
		"/* pointer to next table entry */\n", cGroupName);
Packit 022b05
    }
Packit 022b05
    fprintf(f,
Packit 022b05
	    "\n    /* private space to hold actual values */\n\n");
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
Packit 022b05
#if 0
Packit 022b05
	    && (smiNode->access == SMI_ACCESS_READ_ONLY
Packit 022b05
		|| smiNode->access == SMI_ACCESS_READ_WRITE)
Packit 022b05
#endif
Packit 022b05
	    ) {
Packit 022b05
	    smiType = smiGetNodeType(smiNode);
Packit 022b05
	    if (!smiType) {
Packit 022b05
		continue;
Packit 022b05
	    }
Packit 022b05
	    
Packit 022b05
	    cName = translate(smiNode->name);
Packit 022b05
	    switch (smiType->basetype) {
Packit 022b05
	    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
		maxSize = smiGetMaxSize(smiType);
Packit 022b05
		fprintf(f,
Packit 022b05
			"    uint32_t  __%s[%u];\n", cName, maxSize);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
	    case SMI_BASETYPE_BITS:
Packit 022b05
		maxSize = smiGetMaxSize(smiType);
Packit 022b05
		fprintf(f,
Packit 022b05
			"    u_char    __%s[%u];\n", cName, maxSize);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_ENUM:
Packit 022b05
	    case SMI_BASETYPE_INTEGER32:
Packit 022b05
		fprintf(f,
Packit 022b05
			"    int32_t   __%s;\n", cName);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
		fprintf(f,
Packit 022b05
			"    uint32_t  __%s;\n", cName);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_INTEGER64:
Packit 022b05
		fprintf(f,
Packit 022b05
			"    int64_t   __%s; \n", cName);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_UNSIGNED64:
Packit 022b05
		fprintf(f,
Packit 022b05
			"    uint64_t  __%s; \n", cName);
Packit 022b05
		break;
Packit 022b05
	    default:
Packit 022b05
		fprintf(f,
Packit 022b05
			"    /* ?? */  __%s; \n", cName);
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	    xfree(cName);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f, "} %s_t;\n\n", cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "/*\n"
Packit 022b05
	    " * C manager interface stubs for %s::%s.\n"
Packit 022b05
	    " */\n\n",
Packit 022b05
	    smiModule->name, groupNode->name);
Packit 022b05
	    
Packit 022b05
    fprintf(f, "extern int\n"
Packit 022b05
	    "%s_mgr_get_%s(struct snmp_session *s, %s_t **%s);\n",
Packit 022b05
	    cModuleName, cGroupName, cGroupName, cGroupName);
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "/*\n"
Packit 022b05
	    " * C agent interface stubs for %s::%s.\n"
Packit 022b05
	    " */\n\n",
Packit 022b05
	    smiModule->name, groupNode->name);
Packit 022b05
    
Packit 022b05
    fprintf(f, "extern int\n"
Packit 022b05
	    "%s_agt_read_%s(%s_t *%s);\n",
Packit 022b05
	    cModuleName, cGroupName, cGroupName, cGroupName);
Packit 022b05
    fprintf(f, "extern int\n"
Packit 022b05
	    "%s_agt_register_%s();\n\n",
Packit 022b05
	    cModuleName, cGroupName);
Packit 022b05
    xfree(cGroupName);
Packit 022b05
    xfree(cModuleName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void printHeaderTypedefs(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode   *smiNode;
Packit 022b05
    int       cnt = 0;
Packit 022b05
    char      *cModuleName;
Packit 022b05
    char      *cSmiNodeName;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	if (isGroup(smiNode) && isAccessible(smiNode)) {
Packit 022b05
	    cnt++;
Packit 022b05
	    printHeaderTypedef(f, smiModule, smiNode);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (cnt) {
Packit 022b05
	/*
Packit 022b05
	 * Should this go into the agent implementation module?
Packit 022b05
	 */
Packit 022b05
	cModuleName = translateLower(smiModule->name);
Packit 022b05
	fprintf(f, "typedef struct %s {\n", cModuleName);
Packit 022b05
	for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	     smiNode;
Packit 022b05
	     smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	    if (isGroup(smiNode) && isAccessible(smiNode)) {
Packit 022b05
		cSmiNodeName = translate(smiNode->name);
Packit 022b05
		if (smiNode->nodekind == SMI_NODEKIND_ROW) {
Packit 022b05
		    fprintf(f, "    %s_t\t*%s;\n", cSmiNodeName, cSmiNodeName);
Packit 022b05
		} else {
Packit 022b05
		    fprintf(f, "    %s_t\t%s;\n", cSmiNodeName, cSmiNodeName);
Packit 022b05
		}
Packit 022b05
		xfree(cSmiNodeName);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
	fprintf(f, "} %s_t;\n\n", cModuleName);
Packit 022b05
	xfree(cModuleName);
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void dumpHeader(SmiModule *smiModule, char *baseName)
Packit 022b05
{
Packit 022b05
    char	*pModuleName;
Packit 022b05
    char	*cModuleName;
Packit 022b05
    FILE	*f;
Packit 022b05
Packit 022b05
    pModuleName = translateUpper(smiModule->name);
Packit 022b05
Packit 022b05
    f = createFile(baseName, ".h");
Packit 022b05
    if (! f) {
Packit 022b05
	return;
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    fprintf(f,
Packit 022b05
	    "/*\n"
Packit 022b05
	    " * This C header file has been generated by smidump "
Packit 022b05
	    SMI_VERSION_STRING ".\n"
Packit 022b05
	    " * It is intended to be used with the NET-SNMP package.\n"
Packit 022b05
	    " *\n"
Packit 022b05
	    " * This header is derived from the %s module.\n"
Packit 022b05
	    " *\n * $I" "d$\n"
Packit 022b05
	    " */\n\n", smiModule->name);
Packit 022b05
Packit 022b05
    fprintf(f, "#ifndef _%s_H_\n", pModuleName);
Packit 022b05
    fprintf(f, "#define _%s_H_\n\n", pModuleName);
Packit 022b05
Packit 022b05
    fprintf(f, "#include <stdlib.h>\n\n");
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "#ifdef HAVE_STDINT_H\n"
Packit 022b05
	    "#include <stdint.h>\n"
Packit 022b05
	    "#endif\n\n");
Packit 022b05
Packit 022b05
    printHeaderTypedefs(f, smiModule);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "/*\n"
Packit 022b05
	    " * Initialization function:\n"
Packit 022b05
	    " */\n\n");
Packit 022b05
    cModuleName = translateLower(smiModule->name);
Packit 022b05
    fprintf(f, "void %s_agt_init(void);\n\n", cModuleName);
Packit 022b05
    xfree(cModuleName);
Packit 022b05
Packit 022b05
    fprintf(f, "#endif /* _%s_H_ */\n", pModuleName);
Packit 022b05
Packit 022b05
    fclose(f);
Packit 022b05
    xfree(pModuleName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void printAgtReadMethodDecls(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode   *smiNode;
Packit 022b05
    int       cnt = 0;
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	if (isGroup(smiNode) && isAccessible(smiNode)) {
Packit 022b05
	    cnt++;
Packit 022b05
	    if (cnt == 1) {
Packit 022b05
		fprintf(f,
Packit 022b05
			"/*\n"
Packit 022b05
			" * Forward declaration of read methods for groups of scalars and tables:\n"
Packit 022b05
			" */\n\n");
Packit 022b05
	    }
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "static unsigned char *\nread_%s_stub(struct variable *,"
Packit 022b05
		    " oid *, size_t *, int, size_t *, WriteMethod **);\n",
Packit 022b05
		    smiNode->name);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void printAgtWriteMethodDecls(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode     *smiNode;
Packit 022b05
    int         cnt = 0;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	if (smiNode->access == SMI_ACCESS_READ_WRITE) {
Packit 022b05
	    cnt++;
Packit 022b05
	    if (cnt == 1) {
Packit 022b05
		fprintf(f,
Packit 022b05
			"/*\n"
Packit 022b05
			" * Forward declaration of write methods for writable objects:\n"
Packit 022b05
			" */\n\n");
Packit 022b05
	    }
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "static int\nwrite_%s_stub(int,"
Packit 022b05
		    " u_char *, u_char, int, u_char *, oid *, int);\n",
Packit 022b05
		    smiNode->name);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void printAgtDefinesGroup(FILE *f, SmiNode *groupNode, int cnt)
Packit 022b05
{
Packit 022b05
    char         *cName, *cGroupName;
Packit 022b05
    SmiNode   	 *smiNode;
Packit 022b05
    SmiType   	 *smiType;
Packit 022b05
    int	      	 num = 0;
Packit 022b05
    unsigned int i;
Packit 022b05
    
Packit 022b05
    if (cnt == 1) {
Packit 022b05
	fprintf(f,
Packit 022b05
	"/*\n"
Packit 022b05
	" * Definitions of tags that are used internally to read/write\n"
Packit 022b05
	" * the selected object type. These tags should be unique.\n"
Packit 022b05
	" */\n\n");
Packit 022b05
    }
Packit 022b05
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
Packit 022b05
	    && (smiNode->access == SMI_ACCESS_READ_ONLY
Packit 022b05
		|| smiNode->access == SMI_ACCESS_READ_WRITE)) {
Packit 022b05
	    num++;
Packit 022b05
	    cName = translateUpper(smiNode->name);
Packit 022b05
	    fprintf(f, "#define %-32s %d\n", cName,
Packit 022b05
		    smiNode->oid[smiNode->oidlen-1]);
Packit 022b05
	    xfree(cName);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
Packit 022b05
    if (num) {
Packit 022b05
	fprintf(f, "static oid %s_base[] = {", cGroupName);
Packit 022b05
	for (i = 0; i < groupNode->oidlen; i++) {
Packit 022b05
	    fprintf(f, "%s%d", i ? ", " : "", groupNode->oid[i]);
Packit 022b05
	}
Packit 022b05
	fprintf(f, "};\n\n");
Packit 022b05
	fprintf(f, "struct variable %s_variables[] = {\n", cGroupName);
Packit 022b05
	for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	     smiNode;
Packit 022b05
	     smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	    if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
Packit 022b05
		&& (smiNode->access == SMI_ACCESS_READ_ONLY
Packit 022b05
		    || smiNode->access == SMI_ACCESS_READ_WRITE)) {
Packit 022b05
		smiType = smiGetNodeType(smiNode);
Packit 022b05
		if (!smiType) {
Packit 022b05
		    continue;
Packit 022b05
		}
Packit 022b05
		cName = translateUpper(smiNode->name);
Packit 022b05
		fprintf(f, "    { %s, %s, %s, read_%s_stub, %d, {%d} },\n",
Packit 022b05
			cName, getBaseTypeString(smiType->basetype),
Packit 022b05
			getAccessString(smiNode->access),
Packit 022b05
			cGroupName, 1, smiNode->oid[smiNode->oidlen-1]);
Packit 022b05
		xfree(cName);
Packit 022b05
	    }
Packit 022b05
	}
Packit 022b05
	fprintf(f, "};\n\n");
Packit 022b05
    }
Packit 022b05
Packit 022b05
    xfree(cGroupName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void printAgtDefines(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode   *smiNode;
Packit 022b05
    int       cnt = 0;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	if (isGroup(smiNode)) {
Packit 022b05
	    printAgtDefinesGroup(f, smiNode, ++cnt);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void printAgtRegister(FILE *f, SmiNode *groupNode, int cnt)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    char    *cGroupName;
Packit 022b05
    int     num = 0;
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
Packit 022b05
	    && (smiNode->access == SMI_ACCESS_READ_ONLY
Packit 022b05
		|| smiNode->access == SMI_ACCESS_READ_WRITE)) {
Packit 022b05
	    num++;
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
Packit 022b05
    if (cnt == 1) {
Packit 022b05
	fprintf(f,
Packit 022b05
		"/*\n"
Packit 022b05
		" * Registration functions for the various MIB groups.\n"
Packit 022b05
		" */\n\n");
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
Packit 022b05
    fprintf(f, "int register_%s()\n{\n", cGroupName);
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    return register_mib(\"%s\",\n"
Packit 022b05
	    "         %s_variables,\n"
Packit 022b05
	    "         sizeof(struct variable),\n"
Packit 022b05
	    "         sizeof(%s_variables)/sizeof(struct variable),\n"
Packit 022b05
	    "         %s_base,\n"
Packit 022b05
	    "         sizeof(%s_base)/sizeof(oid));\n",
Packit 022b05
	    cGroupName, cGroupName, cGroupName, cGroupName, cGroupName);
Packit 022b05
    fprintf(f, "};\n\n");
Packit 022b05
Packit 022b05
    xfree(cGroupName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void printAgtInit(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode   *smiNode;
Packit 022b05
    int       cnt = 0;
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	if (isGroup(smiNode)) {
Packit 022b05
	    printAgtRegister(f, smiNode, ++cnt);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void printAgtReadMethod(FILE *f, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiNode   *smiNode;
Packit 022b05
    SmiType   *smiType;
Packit 022b05
    char      *cName, *sName, *lName;
Packit 022b05
Packit 022b05
    sName = translate(groupNode->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "static unsigned char *\nread_%s_stub(struct variable *vp,\n"
Packit 022b05
	    "    oid     *name,\n"
Packit 022b05
	    "    size_t  *length,\n"
Packit 022b05
	    "    int     exact,\n"
Packit 022b05
	    "    size_t  *var_len,\n"
Packit 022b05
	    "    WriteMethod **write_method)\n"
Packit 022b05
	    "{\n", sName);
Packit 022b05
Packit 022b05
    fprintf(f, "    static %s_t %s;\n\n", sName, sName);
Packit 022b05
    
Packit 022b05
    smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
    if (smiNode && smiNode->nodekind == SMI_NODEKIND_SCALAR) {
Packit 022b05
	fprintf(f,
Packit 022b05
		"    /* check whether the instance identifier is valid */\n"
Packit 022b05
		"\n"
Packit 022b05
		"    if (header_generic(vp, name, length, exact, var_len,\n"
Packit 022b05
		"                       write_method) == MATCH_FAILED) {\n"
Packit 022b05
		"        return NULL;\n"
Packit 022b05
		"    }\n"
Packit 022b05
		"\n");
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    /* call the user supplied function to retrieve values */\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "    read_%s(&%s);\n"
Packit 022b05
	    "\n", sName, sName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    /* return the current value of the variable */\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "    switch (vp->magic) {\n"
Packit 022b05
	    "\n");
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
Packit 022b05
	    && (smiNode->access == SMI_ACCESS_READ_ONLY
Packit 022b05
		|| smiNode->access == SMI_ACCESS_READ_WRITE)) {
Packit 022b05
	    cName = translateUpper(smiNode->name);
Packit 022b05
	    lName = translate(smiNode->name);
Packit 022b05
	    smiType = smiGetNodeType(smiNode);
Packit 022b05
	    if (! smiType) {
Packit 022b05
		continue;
Packit 022b05
	    }
Packit 022b05
	    fprintf(f, "    case %s:\n", cName);
Packit 022b05
	    switch (smiType->basetype) {
Packit 022b05
	    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
		fprintf(f,
Packit 022b05
			"        *var_len = %s._%sLength;\n"
Packit 022b05
			"        return (unsigned char *) %s.%s;\n",
Packit 022b05
			sName, lName, sName, lName);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
	    case SMI_BASETYPE_BITS:
Packit 022b05
		fprintf(f,
Packit 022b05
			"        *var_len = %s._%sLength;\n"
Packit 022b05
			"        return (unsigned char *) %s.%s;\n",
Packit 022b05
			sName, lName, sName, lName);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_ENUM:
Packit 022b05
	    case SMI_BASETYPE_INTEGER32:
Packit 022b05
	    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
		fprintf(f,
Packit 022b05
			"        return (unsigned char *) &%s.%s;\n",
Packit 022b05
			sName, lName);
Packit 022b05
		break;
Packit 022b05
	    default:
Packit 022b05
		fprintf(f,
Packit 022b05
			"        /* add code to return the value here */\n");
Packit 022b05
	    }
Packit 022b05
	    fprintf(f, "\n");
Packit 022b05
	    xfree(cName);
Packit 022b05
	    xfree(lName);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    default:\n"
Packit 022b05
	    "         ERROR_MSG(\"\");\n"
Packit 022b05
	    "    }\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "    return NULL;\n"
Packit 022b05
	    "}\n"
Packit 022b05
	    "\n");
Packit 022b05
Packit 022b05
    xfree(sName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void printAgtReadMethods(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode   *smiNode;
Packit 022b05
    int       cnt = 0;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	if (isGroup(smiNode) && isAccessible(smiNode)) {
Packit 022b05
	    cnt++;
Packit 022b05
	    if (cnt == 1) {
Packit 022b05
		fprintf(f,
Packit 022b05
			"/*\n"
Packit 022b05
			" * Read methods for groups of scalars and tables:\n"
Packit 022b05
			" */\n\n");
Packit 022b05
	    }
Packit 022b05
	    printAgtReadMethod(f, smiNode);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void printAgtWriteMethods(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode     *smiNode;
Packit 022b05
    int         cnt = 0;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	if (smiNode->access == SMI_ACCESS_READ_WRITE) {
Packit 022b05
	    cnt++;
Packit 022b05
	    if (cnt == 1) {
Packit 022b05
		fprintf(f,
Packit 022b05
			"/*\n"
Packit 022b05
			" * Forward declaration of write methods for writable objects:\n"
Packit 022b05
			" */\n\n");
Packit 022b05
	    }
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "static int\nwrite_%s_stub(int action,\n"
Packit 022b05
		    "    u_char   *var_val,\n"
Packit 022b05
		    "    u_char   var_val_type,\n"
Packit 022b05
		    "    int      var_val_len,\n"
Packit 022b05
		    "    u_char   *statP,\n"
Packit 022b05
		    "    oid      *name,\n"
Packit 022b05
		    "    int      name_len)\n"
Packit 022b05
		    "{\n", smiNode->name);
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "    return SNMP_ERR_NOERROR;\n"
Packit 022b05
		    "}\n\n");
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void dumpAgtStub(SmiModule *smiModule, char *baseName)
Packit 022b05
{
Packit 022b05
    char	*stubModuleName;
Packit 022b05
    FILE	*f;
Packit 022b05
Packit 022b05
    stubModuleName = xmalloc(strlen(baseName) + 10);
Packit 022b05
    strcpy(stubModuleName, baseName);
Packit 022b05
    strcat(stubModuleName, "-agt-stub");
Packit 022b05
    
Packit 022b05
    f = createFile(stubModuleName, ".c");
Packit 022b05
    if (! f) {
Packit 022b05
	xfree(stubModuleName);
Packit 022b05
        return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "/*\n"
Packit 022b05
	    " * This C file has been generated by smidump "
Packit 022b05
	    SMI_VERSION_STRING ".\n"
Packit 022b05
	    " * It is intended to be used with the NET-SNMP agent library.\n"
Packit 022b05
	    " *\n"
Packit 022b05
	    " * This C file is derived from the %s module.\n"
Packit 022b05
	    " *\n * $I" "d$\n"
Packit 022b05
	    " */\n\n", smiModule->name );
Packit 022b05
	
Packit 022b05
    fprintf(f,
Packit 022b05
	    "#include <stdio.h>\n"
Packit 022b05
	    "#include <string.h>\n"
Packit 022b05
	    "#include <malloc.h>\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "#include \"%s.h\"\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "#include <ucd-snmp/asn1.h>\n"
Packit 022b05
	    "#include <ucd-snmp/snmp.h>\n"
Packit 022b05
	    "#include <ucd-snmp/snmp_api.h>\n"
Packit 022b05
	    "#include <ucd-snmp/snmp_impl.h>\n"
Packit 022b05
	    "#include <ucd-snmp/snmp_vars.h>\n"
Packit 022b05
	    "\n",
Packit 022b05
	    baseName);
Packit 022b05
Packit 022b05
    printAgtReadMethodDecls(f, smiModule);
Packit 022b05
    printAgtWriteMethodDecls(f, smiModule);
Packit 022b05
    printAgtDefines(f, smiModule);
Packit 022b05
    printAgtInit(f, smiModule);
Packit 022b05
Packit 022b05
    printAgtReadMethods(f, smiModule);
Packit 022b05
    printAgtWriteMethods(f, smiModule);
Packit 022b05
Packit 022b05
    fclose(f);
Packit 022b05
    xfree(stubModuleName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void printMgrOidDefinitions(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode      *smiNode;
Packit 022b05
    char         *cName;
Packit 022b05
    unsigned int i;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
Packit 022b05
	    && smiNode->access != SMI_ACCESS_NOTIFY) {
Packit 022b05
	    cName = translate(smiNode->name);
Packit 022b05
  	    fprintf(f, "static oid %s[] = {", cName);
Packit 022b05
	    for (i = 0; i < smiNode->oidlen; i++) {
Packit 022b05
		fprintf(f, "%s%u", i ? ", " : "", smiNode->oid[i]);
Packit 022b05
	    }
Packit 022b05
	    fprintf(f, "};\n");
Packit 022b05
	    xfree(cName);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    fprintf(f, "\n");
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void printMgrGetScalarAssignement(FILE *f, SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    SmiType *smiType;
Packit 022b05
    char    *cGroupName, *cName;
Packit 022b05
    unsigned maxSize, minSize;
Packit 022b05
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
Packit 022b05
    for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
Packit 022b05
	    && (smiNode->access == SMI_ACCESS_READ_ONLY
Packit 022b05
		|| smiNode->access == SMI_ACCESS_READ_WRITE)) {
Packit 022b05
Packit 022b05
	    smiType = smiGetNodeType(smiNode);
Packit 022b05
	    if (!smiType) {
Packit 022b05
		continue;
Packit 022b05
	    }
Packit 022b05
	    
Packit 022b05
	    cName = translate(smiNode->name);
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "        if (vars->name_length > sizeof(%s)/sizeof(oid)\n"
Packit 022b05
		    "            && memcmp(vars->name, %s, sizeof(%s)) == 0) {\n",
Packit 022b05
		    cName, cName, cName);
Packit 022b05
	    switch (smiType->basetype) {
Packit 022b05
	    case SMI_BASETYPE_INTEGER32:
Packit 022b05
	    case SMI_BASETYPE_UNSIGNED32:
Packit 022b05
	    case SMI_BASETYPE_ENUM:
Packit 022b05
		fprintf(f,
Packit 022b05
			"            (*%s)->__%s = *vars->val.integer;\n"
Packit 022b05
			"            (*%s)->%s = &((*%s)->__%s);\n",
Packit 022b05
			cGroupName, cName,
Packit 022b05
			cGroupName, cName, cGroupName, cName);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_OCTETSTRING:
Packit 022b05
	    case SMI_BASETYPE_BITS:
Packit 022b05
		maxSize = smiGetMaxSize(smiType);
Packit 022b05
		minSize = smiGetMinSize(smiType);
Packit 022b05
		fprintf(f,
Packit 022b05
			"            memcpy((*%s)->__%s, vars->val.string, vars->val_len);\n",
Packit 022b05
			cGroupName, cName);
Packit 022b05
		if (minSize != maxSize) {
Packit 022b05
		    fprintf(f,
Packit 022b05
			    "            (*%s)->_%sLength = vars->val_len;\n",
Packit 022b05
			    cGroupName, cName);
Packit 022b05
		}
Packit 022b05
		fprintf(f,
Packit 022b05
			"            (*%s)->%s = (*%s)->__%s;\n",
Packit 022b05
			cGroupName, cName, cGroupName, cName);
Packit 022b05
		break;
Packit 022b05
	    case SMI_BASETYPE_OBJECTIDENTIFIER:
Packit 022b05
		break;
Packit 022b05
	    default:
Packit 022b05
		break;
Packit 022b05
	    }
Packit 022b05
	    fprintf(f,
Packit 022b05
		    "        }\n");
Packit 022b05
	    xfree(cName);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    xfree(cGroupName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void printMgrGetMethod(FILE *f, SmiModule *smiModule,
Packit 022b05
			      SmiNode *groupNode)
Packit 022b05
{
Packit 022b05
    SmiNode *smiNode;
Packit 022b05
    char    *cModuleName, *cGroupName;
Packit 022b05
Packit 022b05
    cModuleName = translateLower(smiModule->name);
Packit 022b05
    cGroupName = translate(groupNode->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "int %s_mgr_get_%s(struct snmp_session *s, %s_t **%s)\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    struct snmp_session *peer;\n"
Packit 022b05
	    "    struct snmp_pdu *request, *response;\n"
Packit 022b05
	    "    struct variable_list *vars;\n"
Packit 022b05
	    "    int status;\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cModuleName, cGroupName, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    request = snmp_pdu_create(SNMP_MSG_GETNEXT);\n");
Packit 022b05
	    
Packit 022b05
    for (smiNode = smiGetFirstChildNode(groupNode);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextChildNode(smiNode)) {
Packit 022b05
	if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
Packit 022b05
	    && (smiNode->access == SMI_ACCESS_READ_ONLY
Packit 022b05
		|| smiNode->access == SMI_ACCESS_READ_WRITE)) {
Packit 022b05
	    fprintf(f,
Packit 022b05
	    "    snmp_add_null_var(request, %s, sizeof(%s)/sizeof(oid));\n",
Packit 022b05
		    smiNode->name, smiNode->name);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "\n"
Packit 022b05
	    "    peer = snmp_open(s);\n"
Packit 022b05
	    "    if (!peer) {\n"
Packit 022b05
	    "        snmp_free_pdu(request);\n"
Packit 022b05
	    "        return -1;\n"
Packit 022b05
	    "    }\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "    status = snmp_synch_response(peer, request, &response);\n"
Packit 022b05
	    "    if (status != STAT_SUCCESS) {\n"
Packit 022b05
	    "        if (response) snmp_free_pdu(response);\n"
Packit 022b05
	    "        snmp_close(peer);\n"
Packit 022b05
	    "        return -2;\n"
Packit 022b05
	    "    }\n"
Packit 022b05
	    "\n");
Packit 022b05
Packit 022b05
    /* generate code for error checking and handling */
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    *%s = (%s_t *) malloc(sizeof(%s_t));\n"
Packit 022b05
	    "    if (! *%s) {\n"
Packit 022b05
	    "        if (response) snmp_free_pdu(response);\n"
Packit 022b05
	    "        snmp_close(peer);\n"
Packit 022b05
	    "        return -4;\n"
Packit 022b05
	    "    }\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cGroupName, cGroupName, cGroupName, cGroupName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    for (vars = response->variables; vars; vars = vars->next_variable) {\n");
Packit 022b05
    printMgrGetScalarAssignement(f, groupNode);
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    }\n"
Packit 022b05
	    "\n");
Packit 022b05
Packit 022b05
Packit 022b05
#if 0
Packit 022b05
    if (response->errstat != SNMP_ERR_NOERROR) {
Packit 022b05
	return -3;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    /* copy to data structures */
Packit 022b05
Packit 022b05
    /* cleanup */
Packit 022b05
Packit 022b05
#endif
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "    if (response) snmp_free_pdu(response);\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "    if (snmp_close(peer) == 0) {\n"
Packit 022b05
	    "        return -5;\n"
Packit 022b05
	    "    }\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "    return 0;\n"
Packit 022b05
	    "}\n\n");
Packit 022b05
Packit 022b05
    xfree(cGroupName);
Packit 022b05
    xfree(cModuleName);
Packit 022b05
}
Packit 022b05
 
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void printMgrGetMethods(FILE *f, SmiModule *smiModule)
Packit 022b05
{
Packit 022b05
    SmiNode   *smiNode;
Packit 022b05
    int       cnt = 0;
Packit 022b05
    
Packit 022b05
    for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
Packit 022b05
	 smiNode;
Packit 022b05
	 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
Packit 022b05
	if (isGroup(smiNode) && isAccessible(smiNode)) {
Packit 022b05
	    cnt++;
Packit 022b05
	    printMgrGetMethod(f, smiModule, smiNode);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
    
Packit 022b05
    if (cnt) {
Packit 022b05
	fprintf(f, "\n");
Packit 022b05
    }
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void dumpMgrStub(SmiModule *smiModule, char *baseName)
Packit 022b05
{
Packit 022b05
    char	*stubModuleName;
Packit 022b05
    FILE	*f;
Packit 022b05
Packit 022b05
    stubModuleName = xmalloc(strlen(baseName) + 10);
Packit 022b05
    strcpy(stubModuleName, baseName);
Packit 022b05
    strcat(stubModuleName, "-mgr-stub");
Packit 022b05
    
Packit 022b05
    f = createFile(stubModuleName, ".c");
Packit 022b05
    if (! f) {
Packit 022b05
	xfree(stubModuleName);
Packit 022b05
        return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "/*\n"
Packit 022b05
	    " * This C file has been generated by smidump "
Packit 022b05
	    SMI_VERSION_STRING ".\n"
Packit 022b05
	    " * It is intended to be used with the NET-SNMP library.\n"
Packit 022b05
	    " *\n"
Packit 022b05
	    " * This C file is derived from the %s module.\n"
Packit 022b05
	    " *\n * $I" "d$\n"
Packit 022b05
	    " */\n\n", smiModule->name );
Packit 022b05
	
Packit 022b05
    fprintf(f,
Packit 022b05
	    "#include <stdlib.h>\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "#include <ucd-snmp/asn1.h>\n"
Packit 022b05
	    "#include <ucd-snmp/snmp.h>\n"
Packit 022b05
	    "#include <ucd-snmp/snmp_api.h>\n"
Packit 022b05
	    "#include <ucd-snmp/snmp_client.h>\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "#include \"%s.h\"\n"
Packit 022b05
	    "\n",
Packit 022b05
	    baseName);
Packit 022b05
Packit 022b05
    printMgrOidDefinitions(f, smiModule);
Packit 022b05
    
Packit 022b05
    printMgrGetMethods(f, smiModule);
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
    fclose(f);
Packit 022b05
    xfree(stubModuleName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void dumpAgtImpl(SmiModule *smiModule, char *baseName)
Packit 022b05
{
Packit 022b05
    char	*stubModuleName, *cModuleName;
Packit 022b05
    FILE	*f;
Packit 022b05
Packit 022b05
    stubModuleName = xmalloc(strlen(baseName) + 10);
Packit 022b05
    strcpy(stubModuleName, baseName);
Packit 022b05
    strcat(stubModuleName, "-agt");
Packit 022b05
    
Packit 022b05
Packit 022b05
    f = createFile(stubModuleName, ".c");
Packit 022b05
    if (! f) {
Packit 022b05
	xfree(stubModuleName);
Packit 022b05
        return;
Packit 022b05
    }
Packit 022b05
Packit 022b05
    cModuleName = translateLower(smiModule->name);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "/*\n"
Packit 022b05
	    " * This C file has been generated by smidump "
Packit 022b05
	    SMI_VERSION_STRING ".\n"
Packit 022b05
	    " * It is intended to be used with the NET-SNMP agent library.\n"
Packit 022b05
	    " *\n"
Packit 022b05
	    " * This C file is derived from the %s module.\n"
Packit 022b05
	    " *\n * $I" "d$\n"
Packit 022b05
	    " */\n\n", smiModule->name );
Packit 022b05
	
Packit 022b05
    fprintf(f,
Packit 022b05
	    "#include <stdio.h>\n"
Packit 022b05
	    "#include <string.h>\n"
Packit 022b05
	    "#include <malloc.h>\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "#include \"%s.h\"\n"
Packit 022b05
	    "\n"
Packit 022b05
	    "#include <ucd-snmp/asn1.h>\n"
Packit 022b05
	    "#include <ucd-snmp/snmp.h>\n"
Packit 022b05
	    "#include <ucd-snmp/snmp_api.h>\n"
Packit 022b05
	    "#include <ucd-snmp/snmp_impl.h>\n"
Packit 022b05
	    "#include <ucd-snmp/snmp_vars.h>\n"
Packit 022b05
	    "\n",
Packit 022b05
	    baseName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "static oid %s_caps[] = {0,0};\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cModuleName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "void init_%s(void)\n"
Packit 022b05
	    "{\n"
Packit 022b05
#if 0
Packit 022b05
	    /* create an entry in the sysORTable */
Packit 022b05
	    
Packit 022b05
	    register_sysORTable(if_mib_caps, sizeof(if_mib_caps),
Packit 022b05
				"IF-MIB implementation version 0.0.");
Packit 022b05
	    
Packit 022b05
	    /* register the various parts of the MIB */
Packit 022b05
	    
Packit 022b05
	    register_interfaces();
Packit 022b05
	    register_ifEntry();
Packit 022b05
	    
Packit 022b05
	    /* register essential callbacks */
Packit 022b05
	    
Packit 022b05
	    snmp_register_callback(SNMP_CALLBACK_LIBRARY,
Packit 022b05
				   SNMP_CALLBACK_SHUTDOWN,
Packit 022b05
				   term_if_mib, NULL);
Packit 022b05
#endif
Packit 022b05
	    "}\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cModuleName);
Packit 022b05
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "void deinit_%s()\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    unregister_sysORTable(%s_caps, sizeof(%s_caps));\n"
Packit 022b05
	    "}\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cModuleName, cModuleName, cModuleName);
Packit 022b05
Packit 022b05
    fprintf(f,
Packit 022b05
	    "int term_%s()\n"
Packit 022b05
	    "{\n"
Packit 022b05
	    "    deinit_%s();\n"
Packit 022b05
	    "    return 0;\n"
Packit 022b05
	    "}\n"
Packit 022b05
	    "\n",
Packit 022b05
	    cModuleName, cModuleName);
Packit 022b05
Packit 022b05
    xfree(cModuleName);
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
    fclose(f);
Packit 022b05
    xfree(stubModuleName);
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
static void dumpNetSnmp(int modc, SmiModule **modv, int flags, char *output)
Packit 022b05
{
Packit 022b05
    char	*baseName;
Packit 022b05
    int		i;
Packit 022b05
Packit 022b05
    if (flags & SMIDUMP_FLAG_UNITE) {
Packit 022b05
	/* not implemented yet */
Packit 022b05
    } else {
Packit 022b05
	for (i = 0; i < modc; i++) {
Packit 022b05
	    baseName = output ? output : translateFileName(modv[i]->name);
Packit 022b05
	    dumpHeader(modv[i], baseName);
Packit 022b05
	    if (! noAgtStubs) {
Packit 022b05
		dumpAgtStub(modv[i], baseName);
Packit 022b05
		dumpAgtImpl(modv[i], baseName);
Packit 022b05
	    }
Packit 022b05
	    if (! noMgrStubs) {
Packit 022b05
		dumpMgrStub(modv[i], baseName);
Packit 022b05
	    }
Packit 022b05
	    if (! output) xfree(baseName);
Packit 022b05
	}
Packit 022b05
    }
Packit 022b05
Packit 022b05
}
Packit 022b05
Packit 022b05
Packit 022b05
Packit 022b05
void initNetsnmp()
Packit 022b05
{
Packit 022b05
    static SmidumpDriverOption opt[] = {
Packit 022b05
	{ "no-mgr-stubs", OPT_FLAG, &noMgrStubs, 0,
Packit 022b05
	  "do not generate manager stub code"},
Packit 022b05
	{ "no-agt-stubs", OPT_FLAG, &noAgtStubs, 0,
Packit 022b05
	  "do not generate agent stub code"},
Packit 022b05
        { 0, OPT_END, 0, 0 }
Packit 022b05
    };
Packit 022b05
Packit 022b05
    static SmidumpDriver driver = {
Packit 022b05
	"netsnmp",
Packit 022b05
	dumpNetSnmp,
Packit 022b05
	SMI_FLAG_NODESCR,
Packit 022b05
	SMIDUMP_DRIVER_CANT_UNITE,
Packit 022b05
	"ANSI C code for the NET-SNMP package",
Packit 022b05
	opt,
Packit 022b05
	NULL
Packit 022b05
    };
Packit 022b05
Packit 022b05
    smidumpRegisterDriver(&driver);
Packit 022b05
}