Sophie

Sophie

distrib > Fedora > 14 > i386 > media > os > by-pkgid > e04c30fdccbd194f92dd8f835139c4e8 > files > 35

openhpi-subagent-2.3.4-13.fc14.i686.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>netSnmpIETFWGTable.c</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="NetSNMP subagent development manual"
HREF="book1.html"><LINK
REL="UP"
TITLE="Appendix"
HREF="c641.html"><LINK
REL="PREVIOUS"
TITLE="netSnmpIETFWGTable.h"
HREF="x646.html"><link rel="stylesheet" href="/openhpi.css" type="text/css">
</head
><BODY
CLASS="SECT1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><div id="banner"><div><h1>The OpenHPI Project</h1><small>Open Hardware Platform Interface</small></div></div><table><tr>
<!--#include virtual="/sidebar.html" -->
<td id="maincolumn"><div class="mainsegment">
<DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>NetSNMP subagent development manual</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x646.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Appendix</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
>&nbsp;</TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="AEN649"
>netSnmpIETFWGTable.c</A
></H1
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>/*
 * Note: this file originally auto-generated by mib2c using
 *       : mib2c.array-user.conf,v 5.15 2002/12/18 00:33:10 rstory Exp $
 *
 * $Id: appendix.sgml 4148 2004-02-07 15:14:46Z konradrzeszutek $
 *
 *
 * For help understanding NET-SNMP in general, please check the 
 *     documentation and FAQ at:
 *
 *     http://www.net-snmp.org/
 *
 *
 * For help understanding this code, the agent and how it processes
 *     requests, please check the following references.
 *
 *     http://www.net-snmp.org/tutorial/
 *
 *
 * You can also join the #net-snmp channel on irc.openprojects.net
 *     and ask for help there.
 *
 *
 * And if all else fails, send a detailed message to the developers
 *     describing the problem you are having to:
 *
 *    net-snmp-coders@lists.sourceforge.net
 *
 *
 * Yes, there is lots of code here that you might not use. But it is much
 * easier to remove code than to add it!
 */
#include &#60;net-snmp/net-snmp-config.h&#62;
#include &#60;net-snmp/net-snmp-includes.h&#62;
#include &#60;net-snmp/agent/net-snmp-agent-includes.h&#62;

#include &#60;net-snmp/library/snmp_assert.h&#62;

#include "netSnmpIETFWGTable.h"

static     netsnmp_handler_registration *my_handler = NULL;
static     netsnmp_table_array_callbacks cb;

oid netSnmpIETFWGTable_oid[] = { netSnmpIETFWGTable_TABLE_OID };
size_t netSnmpIETFWGTable_oid_len = OID_LENGTH(netSnmpIETFWGTable_oid);


#ifdef netSnmpIETFWGTable_IDX2
/************************************************************
 * keep binary tree to find context by name
 */
static int netSnmpIETFWGTable_cmp( const void *lhs, const void *rhs );

/************************************************************
 * compare two context pointers here. Return -1 if lhs &#60; rhs,
 * 0 if lhs == rhs, and 1 if lhs &#62; rhs.
 */
static int
netSnmpIETFWGTable_cmp( const void *lhs, const void *rhs )
{
    netSnmpIETFWGTable_context *context_l =
        (netSnmpIETFWGTable_context *)lhs;
    netSnmpIETFWGTable_context *context_r =
        (netSnmpIETFWGTable_context *)rhs;

    /*
     * check primary key, then secondary. Add your own code if
     * there are more than 2 indexes
     */
    int rc;

    /*
     * TODO: implement compare. Remove this ifdef code and
     * add your own code here.
     */
#ifdef TABLE_CONTAINER_TODO
    snmp_log(LOG_ERR,
             "netSnmpIETFWGTable_compare not implemented! Container order undefined\n" );
    return 0;
#endif
    
    /*
     * EXAMPLE:
     *   
     * rc = strncmp( context_l-&#62;xxName, context_r-&#62;xxName,
     *               SNMP_MIN(context_l-&#62;xxName_len, context_r-&#62;xxName_len) );
     *
     * if(rc)
     *   return rc;
     *
     * TODO: fix secondary keys (or delete if there are none)
     *
     * if(context_l-&#62;yy &#60; context_r-&#62;yy) 
     *   return -1;
     *
     * return (context_l-&#62;yy == context_r-&#62;yy) ? 0 : 1;
     */
}

/************************************************************
 * search tree
 */
/** TODO: set additional indexes as parameters */
netSnmpIETFWGTable_context *
netSnmpIETFWGTable_get( const char *name, int len )
{
    netSnmpIETFWGTable_context tmp;

    /** we should have a secondary index */
    netsnmp_assert(cb.container-&#62;next != NULL);
    
    /*
     * TODO: implement compare. Remove this ifdef code and
     * add your own code here.
     */
#ifdef TABLE_CONTAINER_TODO
    snmp_log(LOG_ERR, "netSnmpIETFWGTable_get not implemented!\n" );
    return NULL;
#endif

    /*
     * EXAMPLE:
     *
     * if(len &#62; sizeof(tmp.xxName))
     *   return NULL;
     *
     * strncpy( tmp.xxName, name, sizeof(tmp.xxName) );
     * tmp.xxName_len = len;
     *
     * return CONTAINER_FIND(cb.container-&#62;next, &#38; tmp);
     */
}
#endif

static void
print_string(netsnmp_index *i, void *v)
{
    int a;
    printf("item %p = [",i);
    for (a = 1; a &#60;= i-&#62;oids[0]; a++)
	printf("%c", (char) i-&#62;oids[a]);
    printf("]\n");
}

/************************************************************
 * Initializes the netSnmpIETFWGTable module
 */
void
init_netSnmpIETFWGTable(void)
{
   netsnmp_index index;
   oid index_oid[MAX_OID_LEN];
   char *index_char[] = {"hickory","joe","hickory","bob","new orleans","help"};
   char *chair = "John Black";
   int i,j;
   netSnmpIETFWGTable_context *ctx;

   initialize_table_netSnmpIETFWGTable();

   for (i = 0; i&#60; 6; i++) {
     /*
       First value of an index that is ASN_OCTET_STR is 
       the length of the string.
     */
	index_oid[0] = strlen(index_char[i]);
	/* The rest is the data copied. */
	for (j = 0; j &#60; index_oid[0];j++) {
		index_oid[j+1] = *(index_char[i]+j);	

	}
        index.oids = (oid *) &#38; index_oid;
        index.len = index_oid[0]+1;
	ctx = NULL;
	/* Search for it first. */
	ctx = CONTAINER_FIND (cb.container, &#38; index);
	if (!ctx) {
	  /* No dice. We add the new row */
		ctx = netSnmpIETFWGTable_create_row( &#38; index);
		printf("inserting %s\n", ctx-&#62;	 nsIETFWGName);
		CONTAINER_INSERT (cb.container, ctx);
	}

   } 
   /*
    Since we are done adding the rows, let us display them for the fun.
    The easy way:
   */

   CONTAINER_FOR_EACH(cb.container, print_string, NULL);

   /*     
   We do not like 'joe', so we remove him.
   */
   index_oid[0] = 3;
   index_oid[1] = 'j'; index_oid[2] = 'o'; index_oid[3] = 'e';
   index.oids = (oid *) &#38; index_oid;
   index.len = 4;
   ctx = CONTAINER_FIND(cb.container, &#38; index);
   if (ctx) {
        CONTAINER_REMOVE( cb.container, &#38; index);
        netSnmpIETFWGTable_delete_row ( ctx );
        printf("Removed joe\n");
   }

   /*
    * Modify 'bob'
    */
   index_oid[0] = 3;
   index_oid[1] = 'b'; index_oid[2] = 'o'; index_oid[3] = 'b';
   index.oids = (oid *) &#38; index_oid;
   index.len = 4;
   ctx = CONTAINER_FIND(cb.container, &#38; index);
   if (ctx) {
        /* Modify the context to our content. */
	ctx-&#62;nsIETFWGChair1_len = strlen(chair);
	memcpy(ctx-&#62;nsIETFWGChair1, chair, ctx-&#62;nsIETFWGChair1_len);
   }




   /*
     Print the hard way:
   */
   
   ctx = CONTAINER_FIRST(cb.container);
   printf("Find first = %p %s\n",ctx, ctx-&#62;nsIETFWGName);
    while( ctx ) {
        ctx = CONTAINER_NEXT(cb.container,ctx);
        if(ctx)
            printf("Find next = %p %s\n",ctx, ctx-&#62;nsIETFWGName);
        else
            printf("Find next = %p\n",ctx);
    }

  
}

/************************************************************
 * the *_row_copy routine
 */
static int netSnmpIETFWGTable_row_copy(netSnmpIETFWGTable_context * dst,
                         netSnmpIETFWGTable_context * src)
{
    if(!dst||!src)
        return 1;
        
    /*
     * copy index, if provided
     */
    if(dst-&#62;index.oids)
        free(dst-&#62;index.oids);
    if(snmp_clone_mem( (void*)&#38; dst-&#62;index.oids, src-&#62;index.oids,
                           src-&#62;index.len * sizeof(oid) )) {
        dst-&#62;index.oids = NULL;
        return 1;
    }
    dst-&#62;index.len = src-&#62;index.len;
    

    /*
     * copy components into the context structure
     */
    memcpy( dst-&#62;nsIETFWGName, src-&#62;nsIETFWGName, src-&#62;nsIETFWGName_len );
    dst-&#62;nsIETFWGName_len = src-&#62;nsIETFWGName_len;

    memcpy( dst-&#62;nsIETFWGChair1, src-&#62;nsIETFWGChair1, src-&#62;nsIETFWGChair1_len );
    dst-&#62;nsIETFWGChair1_len = src-&#62;nsIETFWGChair1_len;

    memcpy( dst-&#62;nsIETFWGChair2, src-&#62;nsIETFWGChair2, src-&#62;nsIETFWGChair2_len );
    dst-&#62;nsIETFWGChair2_len = src-&#62;nsIETFWGChair2_len;

    return 0;
}

#ifdef netSnmpIETFWGTable_SET_HANDLING

/*
 * the *_extract_index routine
 */
int
netSnmpIETFWGTable_extract_index( netSnmpIETFWGTable_context * ctx, netsnmp_index * hdr )
{
    /*
     * temporary local storage for extracting oid index
     */
    netsnmp_variable_list var_nsIETFWGName;
    int err;

    /*
     * copy index, if provided
     */
    if(hdr) {
        netsnmp_assert(ctx-&#62;index.oids == NULL);
        if(snmp_clone_mem( (void*)&#38; ctx-&#62;index.oids, hdr-&#62;oids,
                           hdr-&#62;len * sizeof(oid) )) {
            return -1;
        }
        ctx-&#62;index.len = hdr-&#62;len;
    }

    /**
     * Create variable to hold each component of the index
     */
       memset( &#38; var_nsIETFWGName, 0x00, sizeof(var_nsIETFWGName) );
       var_nsIETFWGName.type = ASN_OCTET_STR;
       /** TODO: link this index to the next, or NULL for the last one */
#ifdef TABLE_CONTAINER_TODO
    snmp_log(LOG_ERR, "netSnmpIETFWGTable_extract_index index list not implemented!\n" );
    return 0;
#else
       var_nsIETFWGName.next_variable = NULL;
#endif


    /*
     * parse the oid into the individual components
     */
    err = parse_oid_indexes( hdr-&#62;oids, hdr-&#62;len, &#38; var_nsIETFWGName );
    if (err == SNMP_ERR_NOERROR) {
       /*
        * copy components into the context structure
        */
              /** skipping external index nsIETFWGName */
                if(var_nsIETFWGName.val_len &#62; sizeof(ctx-&#62;nsIETFWGName))
                   err = -1;
                else
                    memcpy( ctx-&#62;nsIETFWGName, var_nsIETFWGName.val.string, var_nsIETFWGName.val_len );
                ctx-&#62;nsIETFWGName_len = var_nsIETFWGName.val_len;
   
   
           /*
            * TODO: check index for valid values. For EXAMPLE:
            *
              * if ( XXX_check_value( var_nsIETFWGName.val.string, XXX ) ) {
          *    err = -1;
          * }
          */
    }

    /*
     * parsing may have allocated memory. free it.
     */
    snmp_reset_var_buffers( &#38; var_nsIETFWGName );

    return err;
}

/************************************************************
 * the *_can_delete routine is called to determine if a row
 * can be deleted.
 *
 * return 1 if the row can be deleted
 * return 0 if the row cannot be deleted
 */
int netSnmpIETFWGTable_can_delete(netSnmpIETFWGTable_context *undo_ctx,
                    netSnmpIETFWGTable_context *row_ctx,
                    netsnmp_request_group * rg)
{
    /*
     * probably shouldn't delete a row that we can't
     * deactivate.
     *
    if(netSnmpIETFWGTable_can_deactivate(undo_ctx,row_ctx,rg) != 1)
        return 0;

     *
     * TODO: check for other deletion requirements here
     */
    return 1;
}

#ifdef netSnmpIETFWGTable_ROW_CREATION
/************************************************************
 * the *_create_row routine is called by the table handler
 * to create a new row for a given index. If you need more
 * information (such as column values) to make a decision
 * on creating rows, you must create an initial row here
 * (to hold the column values), and you can examine the
 * situation in more detail in the *_set_reserve1 or later
 * states of set processing. Simple check for a NULL undo_ctx
 * in those states and do detailed creation checking there.
 *
 * returns a newly allocated netSnmpIETFWGTable_context
 *   structure if the specified indexes are not illegal
 * returns NULL for errors or illegal index values.
 */
netSnmpIETFWGTable_context *
netSnmpIETFWGTable_create_row( netsnmp_index* hdr)
{
    netSnmpIETFWGTable_context * ctx =
        SNMP_MALLOC_TYPEDEF(netSnmpIETFWGTable_context);
    if(!ctx)
        return NULL;
        
    /*
     * TODO: check indexes, if necessary.
     */
    if(netSnmpIETFWGTable_extract_index( ctx, hdr )) {
        free(ctx-&#62;index.oids);
        free(ctx);
        return NULL;
    }

    /* netsnmp_mutex_init(ctx-&#62;lock);
       netsnmp_mutex_lock(ctx-&#62;lock); */

    /*
     * TODO: initialize any default values here. This is also
     * first place you really should allocate any memory for
     * yourself to use.  If you allocated memory earlier,
     * make sure you free it for earlier error cases!
     */
    ctx-&#62;nsIETFWGChair1_len = 0;
    ctx-&#62;nsIETFWGChair2_len = 0;

    return ctx;
}
#endif

/************************************************************
 * the *_duplicate row routine
 */
netSnmpIETFWGTable_context *
netSnmpIETFWGTable_duplicate_row( netSnmpIETFWGTable_context * row_ctx)
{
    netSnmpIETFWGTable_context * dup;

    if(!row_ctx)
        return NULL;

    dup = SNMP_MALLOC_TYPEDEF(netSnmpIETFWGTable_context);
    if(!dup)
        return NULL;
        
    if(netSnmpIETFWGTable_row_copy(dup,row_ctx)) {
        free(dup);
        dup = NULL;
    }

    return dup;
}

/************************************************************
 * the *_delete_row method is called to delete a row.
 */
netsnmp_index * netSnmpIETFWGTable_delete_row( netSnmpIETFWGTable_context * ctx )
{
  /* netsnmp_mutex_destroy(ctx-&#62;lock); */

    if(ctx-&#62;index.oids)
        free(ctx-&#62;index.oids);

    /*
     * TODO: release any memory you allocated here...
     */

    /*
     * release header
     */
    free( ctx );

    return NULL;
}


/************************************************************
 * RESERVE is used to check the syntax of all the variables
 * provided, that the values being set are sensible and consistent,
 * and to allocate any resources required for performing the SET.
 * After this stage, the expectation is that the set ought to
 * succeed, though this is not guaranteed. (In fact, with the UCD
 * agent, this is done in two passes - RESERVE1, and
 * RESERVE2, to allow for dependancies between variables).
 *
 * BEFORE calling this routine, the agent will call duplicate_row
 * to create a copy of the row (unless this is a new row; i.e.
 * row_created == 1).
 *
 * next state -&#62; SET_RESERVE2 || SET_FREE
 */
void netSnmpIETFWGTable_set_reserve1( netsnmp_request_group *rg )
{
    netSnmpIETFWGTable_context *row_ctx =
            (netSnmpIETFWGTable_context *)rg-&#62;existing_row;
    netSnmpIETFWGTable_context *undo_ctx =
            (netSnmpIETFWGTable_context *)rg-&#62;undo_info;
    netsnmp_variable_list *var;
    netsnmp_request_group_item *current;
    int rc;


    /*
     * TODO: loop through columns, check syntax and lengths. For
     * columns which have no dependencies, you could also move
     * the value/range checking here to attempt to catch error
     * cases as early as possible.
     */
    for( current = rg-&#62;list; current; current = current-&#62;next ) {

        var = current-&#62;ri-&#62;requestvb;
        rc = SNMP_ERR_NOERROR;

        switch(current-&#62;tri-&#62;colnum) {

        case COLUMN_NSIETFWGCHAIR1:
            /** OCTETSTR = ASN_OCTET_STR */
            rc = netsnmp_check_vb_type_and_size(var, ASN_OCTET_STR,
                                                sizeof(row_ctx-&#62;nsIETFWGChair1));
        break;

        case COLUMN_NSIETFWGCHAIR2:
            /** OCTETSTR = ASN_OCTET_STR */
            rc = netsnmp_check_vb_type_and_size(var, ASN_OCTET_STR,
                                                sizeof(row_ctx-&#62;nsIETFWGChair2));
        break;

        default: /** We shouldn't get here */
            rc = SNMP_ERR_GENERR;
            snmp_log(LOG_ERR, "unknown column in "
                     "netSnmpIETFWGTable_set_reserve1\n");
        }

        if (rc)
           netsnmp_set_mode_request_error(MODE_SET_BEGIN, current-&#62;ri, rc );
        rg-&#62;status = SNMP_MAX( rg-&#62;status, current-&#62;ri-&#62;status );
    }

    /*
     * done with all the columns. Could check row related
     * requirements here.
     */
}

void netSnmpIETFWGTable_set_reserve2( netsnmp_request_group *rg )
{
    netSnmpIETFWGTable_context *row_ctx = (netSnmpIETFWGTable_context *)rg-&#62;existing_row;
    netSnmpIETFWGTable_context *undo_ctx = (netSnmpIETFWGTable_context *)rg-&#62;undo_info;
    netsnmp_request_group_item *current;
    netsnmp_variable_list *var;
    int rc;

    rg-&#62;rg_void = rg-&#62;list-&#62;ri;

    /*
     * TODO: loop through columns, check for valid
     * values and any range constraints.
     */
    for( current = rg-&#62;list; current; current = current-&#62;next ) {

        var = current-&#62;ri-&#62;requestvb;
        rc = SNMP_ERR_NOERROR;

        switch(current-&#62;tri-&#62;colnum) {

        case COLUMN_NSIETFWGCHAIR1:
            /** OCTETSTR = ASN_OCTET_STR */
                    /*
                     * TODO: routine to check valid values
                     *
                     * EXAMPLE:
                     *
                    * if ( XXX_check_value( var-&#62;val.string, XXX ) ) {
                *    rc = SNMP_ERR_INCONSISTENTVALUE;
                *    rc = SNMP_ERR_BADVALUE;
                * }
                */
        break;

        case COLUMN_NSIETFWGCHAIR2:
            /** OCTETSTR = ASN_OCTET_STR */
	  if (var-&#62;val_len &#62; 255)
                rc = SNMP_ERR_WRONGLENGTH;
        break;

        default: /** We shouldn't get here */
            netsnmp_assert(0); /** why wasn't this caught in reserve1? */
        }

        if (rc)
           netsnmp_set_mode_request_error(MODE_SET_BEGIN, current-&#62;ri, rc);
    }

    /*
     * done with all the columns. Could check row related
     * requirements here.
     */
}

/************************************************************
 * Assuming that the RESERVE phases were successful, the next
 * stage is indicated by the action value ACTION. This is used
 * to actually implement the set operation. However, this must
 * either be done into temporary (persistent) storage, or the
 * previous value stored similarly, in case any of the subsequent
 * ACTION calls fail.
 *
 * In your case, changes should be made to row_ctx. A copy of
 * the original row is in undo_ctx.
 */
void netSnmpIETFWGTable_set_action( netsnmp_request_group *rg )
{
    netsnmp_variable_list *var;
    netSnmpIETFWGTable_context *row_ctx = (netSnmpIETFWGTable_context *)rg-&#62;existing_row;
    netSnmpIETFWGTable_context *undo_ctx = (netSnmpIETFWGTable_context *)rg-&#62;undo_info;
    netsnmp_request_group_item *current;


    /*
     * TODO: loop through columns, copy varbind values
     * to context structure for the row.
     */
    for( current = rg-&#62;list; current; current = current-&#62;next ) {

        var = current-&#62;ri-&#62;requestvb;

        switch(current-&#62;tri-&#62;colnum) {

        case COLUMN_NSIETFWGCHAIR1:
            /** OCTETSTR = ASN_OCTET_STR */
            memcpy(row_ctx-&#62;nsIETFWGChair1,var-&#62;val.string,var-&#62;val_len);
            row_ctx-&#62;nsIETFWGChair1_len = var-&#62;val_len;
        break;

        case COLUMN_NSIETFWGCHAIR2:
            /** OCTETSTR = ASN_OCTET_STR */
            memcpy(row_ctx-&#62;nsIETFWGChair2,var-&#62;val.string,var-&#62;val_len);
            row_ctx-&#62;nsIETFWGChair2_len = var-&#62;val_len;
        break;

        default: /** We shouldn't get here */
            netsnmp_assert(0); /** why wasn't this caught in reserve1? */
        }
    }

    /*
     * done with all the columns. Could check row related
     * requirements here.
     */
    /*
     * TODO: if you have dependencies on other tables, this would be
     * a good place to check those, too.
     */
}

/************************************************************
 * Only once the ACTION phase has completed successfully, can
 * the final COMMIT phase be run. This is used to complete any
 * writes that were done into temporary storage, and then release
 * any allocated resources. Note that all the code in this phase
 * should be "safe" code that cannot possibly fail (cue
 * hysterical laughter). The whole intent of the ACTION/COMMIT
 * division is that all of the fallible code should be done in
 * the ACTION phase, so that it can be backed out if necessary.
 *
 * BEFORE calling this routine, the agent will update the
 * container (inserting a row if row_created == 1, or removing
 * the row if row_deleted == 1).
 *
 * AFTER calling this routine, the agent will delete the
 * undo_info.
 */
void netSnmpIETFWGTable_set_commit( netsnmp_request_group *rg )
{
    netsnmp_variable_list *var;
    netSnmpIETFWGTable_context *row_ctx = (netSnmpIETFWGTable_context *)rg-&#62;existing_row;
    netSnmpIETFWGTable_context *undo_ctx = (netSnmpIETFWGTable_context *)rg-&#62;undo_info;
    netsnmp_request_group_item *current;

    /*
     * loop through columns
     */
    for( current = rg-&#62;list; current; current = current-&#62;next ) {

        var = current-&#62;ri-&#62;requestvb;

        switch(current-&#62;tri-&#62;colnum) {

        case COLUMN_NSIETFWGCHAIR1:
            /** OCTETSTR = ASN_OCTET_STR */
        break;

        case COLUMN_NSIETFWGCHAIR2:
            /** OCTETSTR = ASN_OCTET_STR */
        break;

        default: /** We shouldn't get here */
            netsnmp_assert(0); /** why wasn't this caught in reserve1? */
        }
    }

    /*
     * done with all the columns. Could check row related
     * requirements here.
     */
}

/************************************************************
 * If either of the RESERVE calls fail, the write routines
 * are called again with the FREE action, to release any resources
 * that have been allocated. The agent will then return a failure
 * response to the requesting application.
 *
 * AFTER calling this routine, the agent will delete undo_info.
 */
void netSnmpIETFWGTable_set_free( netsnmp_request_group *rg )
{
    netsnmp_variable_list *var;
    netSnmpIETFWGTable_context *row_ctx = (netSnmpIETFWGTable_context *)rg-&#62;existing_row;
    netSnmpIETFWGTable_context *undo_ctx = (netSnmpIETFWGTable_context *)rg-&#62;undo_info;
    netsnmp_request_group_item *current;

    /*
     * loop through columns
     */
    for( current = rg-&#62;list; current; current = current-&#62;next ) {

        var = current-&#62;ri-&#62;requestvb;

        switch(current-&#62;tri-&#62;colnum) {

        case COLUMN_NSIETFWGCHAIR1:
            /** OCTETSTR = ASN_OCTET_STR */
        break;

        case COLUMN_NSIETFWGCHAIR2:
            /** OCTETSTR = ASN_OCTET_STR */
        break;

        default: /** We shouldn't get here */
            /** should have been logged in reserve1 */
        }
    }

    /*
     * done with all the columns. Could check row related
     * requirements here.
     */
}

/************************************************************
 * If the ACTION phase does fail (for example due to an apparently
 * valid, but unacceptable value, or an unforeseen problem), then
 * the list of write routines are called again, with the UNDO
 * action. This requires the routine to reset the value that was
 * changed to its previous value (assuming it was actually changed),
 * and then to release any resources that had been allocated. As
 * with the FREE phase, the agent will then return an indication
 * of the error to the requesting application.
 *
 * BEFORE calling this routine, the agent will update the container
 * (remove any newly inserted row, re-insert any removed row).
 *
 * AFTER calling this routing, the agent will call row_copy
 * to restore the data in existing_row from the date in undo_info.
 * Then undo_info will be deleted (or existing row, if row_created
 * == 1).
 */
void netSnmpIETFWGTable_set_undo( netsnmp_request_group *rg )
{
    netsnmp_variable_list *var;
    netSnmpIETFWGTable_context *row_ctx = (netSnmpIETFWGTable_context *)rg-&#62;existing_row;
    netSnmpIETFWGTable_context *undo_ctx = (netSnmpIETFWGTable_context *)rg-&#62;undo_info;
    netsnmp_request_group_item *current;

    /*
     * loop through columns
     */
    for( current = rg-&#62;list; current; current = current-&#62;next ) {

        var = current-&#62;ri-&#62;requestvb;

        switch(current-&#62;tri-&#62;colnum) {

        case COLUMN_NSIETFWGCHAIR1:
            /** OCTETSTR = ASN_OCTET_STR */
        break;

        case COLUMN_NSIETFWGCHAIR2:
            /** OCTETSTR = ASN_OCTET_STR */
        break;

        default: /** We shouldn't get here */
            netsnmp_assert(0); /** why wasn't this caught in reserve1? */
        }
    }

    /*
     * done with all the columns. Could check row related
     * requirements here.
     */
}

#endif /** netSnmpIETFWGTable_SET_HANDLING */


/************************************************************
 *
 * Initialize the netSnmpIETFWGTable table by defining its contents and how it's structured
 */
void
initialize_table_netSnmpIETFWGTable(void)
{
    netsnmp_table_registration_info *table_info;

    if(my_handler) {
        snmp_log(LOG_ERR, "initialize_table_netSnmpIETFWGTable_handler called again\n");
        return;
    }

    memset(&#38; cb, 0x00, sizeof(cb));

    /** create the table structure itself */
    table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);

    /* if your table is read only, it's easiest to change the
       HANDLER_CAN_RWRITE definition below to HANDLER_CAN_RONLY */
    my_handler = netsnmp_create_handler_registration("netSnmpIETFWGTable",
                                             netsnmp_table_array_helper_handler,
                                             netSnmpIETFWGTable_oid,
                                             netSnmpIETFWGTable_oid_len,
                                             HANDLER_CAN_RWRITE);
            
    if (!my_handler || !table_info) {
        snmp_log(LOG_ERR, "malloc failed in "
                 "initialize_table_netSnmpIETFWGTable_handler\n");
        return; /** mallocs failed */
    }

    /***************************************************
     * Setting up the table's definition
     */
    /*
     * TODO: add any external indexes here.
     */

    /*
     * internal indexes
     */
        /** index: nsIETFWGName */
        netsnmp_table_helper_add_index(table_info, ASN_OCTET_STR);

    table_info-&#62;min_column = netSnmpIETFWGTable_COL_MIN;
    table_info-&#62;max_column = netSnmpIETFWGTable_COL_MAX;

    /***************************************************
     * registering the table with the master agent
     */
    cb.get_value = netSnmpIETFWGTable_get_value;
    cb.container = netsnmp_container_find("netSnmpIETFWGTable_primary:"
                                          "netSnmpIETFWGTable:"
                                          "table_container");
#ifdef netSnmpIETFWGTable_IDX2
    netsnmp_container_add_index(cb.container,
                                netsnmp_container_find("netSnmpIETFWGTable_secondary:"
                                                       "netSnmpIETFWGTable:"
                                                       "table_container"));
    cb.container-&#62;next-&#62;compare = netSnmpIETFWGTable_cmp;
#endif
#ifdef netSnmpIETFWGTable_SET_HANDLING
    cb.can_set = 1;
#ifdef netSnmpIETFWGTable_ROW_CREATION
    cb.create_row = (UserRowMethod*)netSnmpIETFWGTable_create_row;
#endif
    cb.duplicate_row = (UserRowMethod*)netSnmpIETFWGTable_duplicate_row;
    cb.delete_row = (UserRowMethod*)netSnmpIETFWGTable_delete_row;
    cb.row_copy = (Netsnmp_User_Row_Operation *)netSnmpIETFWGTable_row_copy;
/*
    cb.can_activate = (Netsnmp_User_Row_Action *)netSnmpIETFWGTable_can_activate;
    cb.can_deactivate = (Netsnmp_User_Row_Action *)netSnmpIETFWGTable_can_deactivate;
*/
    cb.can_delete = (Netsnmp_User_Row_Action *)netSnmpIETFWGTable_can_delete;

    cb.set_reserve1 = netSnmpIETFWGTable_set_reserve1;
    cb.set_reserve2 = netSnmpIETFWGTable_set_reserve2;
    cb.set_action = netSnmpIETFWGTable_set_action;
    cb.set_commit = netSnmpIETFWGTable_set_commit;
    cb.set_free = netSnmpIETFWGTable_set_free;
    cb.set_undo = netSnmpIETFWGTable_set_undo;
#endif
    DEBUGMSGTL(("initialize_table_netSnmpIETFWGTable",
                "Registering table netSnmpIETFWGTable "
                "as a table array\n"));
    netsnmp_table_container_register(my_handler, table_info, &#38; cb,
                                     cb.container, 1);
}

/************************************************************
 * netSnmpIETFWGTable_get_value
 */
int netSnmpIETFWGTable_get_value(
            netsnmp_request_info *request,
            netsnmp_index *item,
            netsnmp_table_request_info *table_info )
{
    netsnmp_variable_list *var = request-&#62;requestvb;
    netSnmpIETFWGTable_context *context = (netSnmpIETFWGTable_context *)item;

    switch(table_info-&#62;colnum) {

        case COLUMN_NSIETFWGNAME:
            /** OCTETSTR = ASN_OCTET_STR */
            snmp_set_var_typed_value(var, ASN_OCTET_STR,
                         (char*)&#38; context-&#62;nsIETFWGName,
                         context-&#62;nsIETFWGName_len );
        break;
    
        case COLUMN_NSIETFWGCHAIR1:
            /** OCTETSTR = ASN_OCTET_STR */
            snmp_set_var_typed_value(var, ASN_OCTET_STR,
                         (char*)&#38; context-&#62;nsIETFWGChair1,
                         context-&#62;nsIETFWGChair1_len );
        break;
    
        case COLUMN_NSIETFWGCHAIR2:
            /** OCTETSTR = ASN_OCTET_STR */
            snmp_set_var_typed_value(var, ASN_OCTET_STR,
                         (char*)&#38; context-&#62;nsIETFWGChair2,
                         context-&#62;nsIETFWGChair2_len );
        break;
    
    default: /** We shouldn't get here */
        snmp_log(LOG_ERR, "unknown column in "
                 "netSnmpIETFWGTable_get_value\n");
        return SNMP_ERR_GENERR;
    }
    return SNMP_ERR_NOERROR;
}

/************************************************************
 * netSnmpIETFWGTable_get_by_idx
 */
const netSnmpIETFWGTable_context *
netSnmpIETFWGTable_get_by_idx(netsnmp_index * hdr)
{
    return (const netSnmpIETFWGTable_context *)
        CONTAINER_FIND(cb.container, hdr );
}


	</PRE
></TD
></TR
></TABLE
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x646.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>&nbsp;</TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>netSnmpIETFWGTable.h</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c641.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>&nbsp;</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>