mfd-interface.m2c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:42k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. #############################################################  -*- c -*-
  2. ## generic include for XXX. Do not use directly.
  3. ##
  4. ## $Id: mfd-interface.m2c,v 1.43.2.3 2005/02/25 22:36:22 rstory Exp $
  5. ########################################################################
  6. @if $m2c_mark_boundary == 1@
  7. /** START code generated by $RCSfile: mfd-interface.m2c,v $ $Revision: 1.43.2.3 $ */
  8. @end@
  9. ########################################################################
  10. ##
  11. ########################################################################
  12. @open ${name}_interface.h@
  13. @eval $hack = "Id"@
  14. /*
  15.  * Note: this file originally auto-generated by mib2c using
  16.  *       version $Revision: 1.43.2.3 $ of $RCSfile: mfd-interface.m2c,v $
  17.  *
  18.  * $$hack:$
  19.  */
  20. /** @defgroup interface: Routines to interface to Net-SNMP
  21.  *
  22.  * warning This code should not be modified, called directly,
  23.  *          or used to interpret functionality. It is subject to
  24.  *          change at any time.
  25.  * 
  26.  * @{
  27.  */
  28. @include m2c-internal-warning.m2i@
  29. ##
  30. @eval $m2c_save = "$name"@
  31. @eval $name = "${name}_INTERFACE"@
  32. @include generic-header-top.m2i@
  33. @eval $name = $m2c_save@
  34. #include "${name}.h"
  35. /* ********************************************************************
  36.  * Table declarations
  37.  */
  38. @foreach $table table@
  39. @    include m2c_setup_table.m2i@
  40. /* PUBLIC interface initialization routine */
  41. void _${context}_initialize_interface(${context}_registration_ptr user_ctx,
  42.                                     u_long flags);
  43. @   if $m2c_data_allocate == 1@
  44. @      eval $m2c_tmp = "${context}_data *"@
  45. @      if $m2c_data_init == 1@
  46. @         eval $m2c_tmp = "$m2c_tmp, void *"@
  47. @      @end@
  48. @   elsif $m2c_data_init == 1@
  49. @      eval $m2c_tmp = "void *"@
  50. @   else@
  51. @      eval $m2c_tmp = "void"@
  52. @   end@
  53.     ${context}_rowreq_ctx * ${context}_allocate_rowreq_ctx($m2c_tmp);
  54. void ${context}_release_rowreq_ctx(${context}_rowreq_ctx *rowreq_ctx);
  55. int ${context}_index_to_oid(netsnmp_index *oid_idx,
  56.                             ${context}_mib_index *mib_idx);
  57. int ${context}_index_from_oid(netsnmp_index *oid_idx,
  58.                               ${context}_mib_index *mib_idx);
  59. /*
  60.  * access to certain internals. use with caution!
  61.  */
  62. void ${context}_valid_columns_set(netsnmp_column_info *vc);
  63. @end@ # for each
  64. @eval $m2c_save = "$name"@
  65. @eval $name = "${name}_INTERFACE"@
  66. @include generic-header-bottom.m2i@
  67. @eval $name = $m2c_save@
  68. ########################################################################
  69. ##
  70. @open ${name}_interface.c@
  71. /*
  72.  * Note: this file originally auto-generated by mib2c using
  73.  *       version $Revision: 1.43.2.3 $ of $RCSfile: mfd-interface.m2c,v $ 
  74.  *
  75.  * $$hack:$
  76.  */
  77. @include m2c-internal-warning.m2i@
  78. @include generic-source-includes.m2i@
  79. #include <net-snmp/library/container.h>
  80. #include "${name}_interface.h"
  81. @eval $m2c_processing_type = 'i'@
  82. @foreach $table table@
  83. @   include m2c_setup_table.m2i@
  84. @   include details-table.m2i@
  85. ########################################################################
  86. typedef struct ${context}_interface_ctx_s {
  87.    netsnmp_container              *container;
  88.    netsnmp_cache                  *cache; /* optional cache */
  89.    ${context}_registration_ptr      user_ctx;
  90.    
  91.    netsnmp_table_registration_info  tbl_info;
  92.    netsnmp_baby_steps_access_methods access_multiplexer;
  93. } ${context}_interface_ctx;
  94. static ${context}_interface_ctx ${context}_if_ctx;
  95. static void _${context}_container_init(
  96.     ${context}_interface_ctx *if_ctx);
  97. static Netsnmp_Node_Handler _mfd_${context}_pre_request;
  98. static Netsnmp_Node_Handler _mfd_${context}_post_request;
  99. static Netsnmp_Node_Handler _mfd_${context}_object_lookup;
  100. static Netsnmp_Node_Handler _mfd_${context}_get_values;
  101. @   if $m2c_table_settable@
  102. static Netsnmp_Node_Handler _mfd_${context}_check_objects;
  103. static Netsnmp_Node_Handler _mfd_${context}_undo_setup;
  104. static Netsnmp_Node_Handler _mfd_${context}_set_values;
  105. static Netsnmp_Node_Handler _mfd_${context}_undo_cleanup;
  106. static Netsnmp_Node_Handler _mfd_${context}_undo_values;
  107. static Netsnmp_Node_Handler _mfd_${context}_commit;
  108. static Netsnmp_Node_Handler _mfd_${context}_undo_commit;
  109. @      if $m2c_irreversible_commit == 1@
  110. static Netsnmp_Node_Handler _mfd_${context}_irreversible_commit;
  111. @      end@
  112. @      if $m2c_table_dependencies == 1@
  113. static Netsnmp_Node_Handler _mfd_${context}_check_dependencies;
  114. @      end@
  115. NETSNMP_STATIC_INLINE int _${context}_undo_column( ${context}_rowreq_ctx *rowreq_ctx,
  116.                                                    netsnmp_variable_list *var, int column );
  117. @if $m2c_table_row_creation == 1@
  118. NETSNMP_STATIC_INLINE int _${context}_check_indexes(${context}_rowreq_ctx * rowreq_ctx);
  119. @end@
  120. @   end@ # writable
  121. @   if ("$m2c_data_context" eq "generated") && (($m2c_undo_embed == 0) || ($m2c_data_allocate == 1))@
  122. ${context}_data *${context}_allocate_data(void);
  123. @   end@
  124. /**
  125.  * @internal
  126.  * Initialize the table $context 
  127.  *    (Define its contents and how it's structured)
  128.  */
  129. void
  130. _${context}_initialize_interface(${context}_registration_ptr reg_ptr,  u_long flags)
  131. {
  132.     netsnmp_baby_steps_access_methods *access_multiplexer =
  133.         &${context}_if_ctx.access_multiplexer;
  134.     netsnmp_table_registration_info *tbl_info = &${context}_if_ctx.tbl_info;
  135.     netsnmp_handler_registration *reginfo;
  136.     netsnmp_mib_handler *handler;
  137.     int    mfd_modes = 0;
  138.     DEBUGMSGTL(("internal:${context}:_${context}_initialize_interface","calledn"));
  139.     /*************************************************
  140.      *
  141.      * save interface context for ${context}
  142.      */
  143.     /*
  144.      * Setting up the table's definition
  145.      */
  146.     netsnmp_table_helper_add_indexes(tbl_info,
  147.     @foreach $tabledx index@
  148.                                   $tabledx.type, /** index: $tabledx */
  149.     @end@
  150.                              0);
  151.     /*  Define the minimum and maximum accessible columns.  This
  152.         optimizes retrival. */
  153.     tbl_info->min_column = $context.uc_MIN_COL;
  154.     tbl_info->max_column = $context.uc_MAX_COL;
  155.     /*
  156.      * save users context
  157.      */
  158.     ${context}_if_ctx.user_ctx = reg_ptr;
  159.     /*
  160.      * call data access initialization code
  161.      */
  162.     ${context}_init_data(reg_ptr);
  163.     /*
  164.      * set up the container
  165.      */
  166.     _${context}_container_init(&${context}_if_ctx);
  167.     if (NULL == ${context}_if_ctx.container) {
  168.         snmp_log(LOG_ERR,"could not initialize container for ${context}n");
  169.         return;
  170.     }
  171.     
  172.     /*
  173.      * access_multiplexer: REQUIRED wrapper for get request handling
  174.      */
  175.     access_multiplexer->object_lookup = _mfd_${context}_object_lookup;
  176.     access_multiplexer->get_values = _mfd_${context}_get_values;
  177.     /*
  178.      * no wrappers yet
  179.      */
  180.     access_multiplexer->pre_request = _mfd_${context}_pre_request;
  181.     access_multiplexer->post_request = _mfd_${context}_post_request;
  182. ##
  183. @   if $m2c_table_settable@
  184.     /*
  185.      * REQUIRED wrappers for set request handling
  186.      */
  187.     access_multiplexer->object_syntax_checks = _mfd_${context}_check_objects;
  188.     access_multiplexer->undo_setup = _mfd_${context}_undo_setup;
  189.     access_multiplexer->undo_cleanup = _mfd_${context}_undo_cleanup;
  190.     access_multiplexer->set_values = _mfd_${context}_set_values;
  191.     access_multiplexer->undo_sets = _mfd_${context}_undo_values;
  192.     /*
  193.      * no wrappers yet
  194.      */
  195.     access_multiplexer->commit = _mfd_${context}_commit;
  196.     access_multiplexer->undo_commit = _mfd_${context}_undo_commit;
  197. @   if $m2c_irreversible_commit == 1@
  198.     access_multiplexer->irreversible_commit = _mfd_${context}_irreversible_commit;
  199. @   end@
  200. ##
  201. @      if $m2c_table_dependencies == 1@
  202.     
  203.     /*
  204.      * REQUIRED for tables with dependencies
  205.      */
  206.     access_multiplexer->consistency_checks = _mfd_${context}_check_dependencies;
  207. @      end@
  208. @   end@ # writable
  209.     /*************************************************
  210.      *
  211.      * Create a registration, save our reg data, register table.
  212.      */
  213.     DEBUGMSGTL(("$name:init_$context",
  214.                 "Registering $context as a mibs-for-dummies table.n"));  
  215.     handler = netsnmp_baby_steps_access_multiplexer_get(access_multiplexer);
  216.     reginfo = netsnmp_handler_registration_create("${context}", handler,
  217.                                                   ${context}_oid,
  218.                                                   ${context}_oid_size,
  219.                                                   HANDLER_CAN_BABY_STEP |
  220. @if $m2c_table_settable == 1@
  221.                                                   HANDLER_CAN_RWRITE
  222. @else@
  223.                                                   HANDLER_CAN_RONLY
  224. @end@
  225.                                                   );
  226.     if(NULL == reginfo) {
  227.         snmp_log(LOG_ERR,"error registering table ${context}n");
  228.         return;
  229.     }
  230.     reginfo->my_reg_void = &${context}_if_ctx;
  231.     /*************************************************
  232.      *
  233.      * set up baby steps handler, create it and inject it
  234.      */
  235.     if( access_multiplexer->object_lookup )
  236.         mfd_modes |= BABY_STEP_OBJECT_LOOKUP;
  237.     if( access_multiplexer->set_values )
  238.         mfd_modes |= BABY_STEP_SET_VALUES;
  239.     if( access_multiplexer->irreversible_commit )
  240.         mfd_modes |= BABY_STEP_IRREVERSIBLE_COMMIT;
  241.     if( access_multiplexer->object_syntax_checks )
  242.         mfd_modes |= BABY_STEP_CHECK_OBJECT;
  243.     if( access_multiplexer->pre_request )
  244.         mfd_modes |= BABY_STEP_PRE_REQUEST;
  245.     if( access_multiplexer->post_request )
  246.         mfd_modes |= BABY_STEP_POST_REQUEST;
  247.     
  248.     if( access_multiplexer->undo_setup )
  249.         mfd_modes |= BABY_STEP_UNDO_SETUP;
  250.     if( access_multiplexer->undo_cleanup )
  251.         mfd_modes |= BABY_STEP_UNDO_CLEANUP;
  252.     if( access_multiplexer->undo_sets )
  253.         mfd_modes |= BABY_STEP_UNDO_SETS;
  254.     
  255.     if( access_multiplexer->row_creation )
  256.         mfd_modes |= BABY_STEP_ROW_CREATE;
  257.     if( access_multiplexer->consistency_checks )
  258.         mfd_modes |= BABY_STEP_CHECK_CONSISTENCY;
  259.     if( access_multiplexer->commit )
  260.         mfd_modes |= BABY_STEP_COMMIT;
  261.     if( access_multiplexer->undo_commit )
  262.         mfd_modes |= BABY_STEP_UNDO_COMMIT;
  263.     
  264.     handler = netsnmp_baby_steps_handler_get(mfd_modes);
  265.     netsnmp_inject_handler(reginfo, handler);
  266.     /*************************************************
  267.      *
  268.      * inject row_merge helper with prefix rootoid_len + 2 (entry.col)
  269.      */
  270.     handler = netsnmp_get_row_merge_handler(reginfo->rootoid_len + 2);
  271.     netsnmp_inject_handler(reginfo, handler);
  272.     /*************************************************
  273.      *
  274.      * inject container_table helper
  275.      */
  276.     handler =
  277.         netsnmp_container_table_handler_get(tbl_info,
  278.                                             ${context}_if_ctx.container,
  279.                                             TABLE_CONTAINER_KEY_NETSNMP_INDEX);
  280.     netsnmp_inject_handler( reginfo, handler );
  281.     /*************************************************
  282.      *
  283.      * inject cache helper
  284.      */
  285.     if(NULL != ${context}_if_ctx.cache) {
  286.         handler = netsnmp_cache_handler_get(${context}_if_ctx.cache);
  287.         netsnmp_inject_handler( reginfo, handler );
  288.     }
  289.     /*
  290.      * register table
  291.      */
  292.     netsnmp_register_table(reginfo, tbl_info);
  293. } /* _${context}_initialize_interface */
  294. void
  295. ${context}_valid_columns_set(netsnmp_column_info *vc)
  296. {
  297.     ${context}_if_ctx.tbl_info.valid_columns = vc;
  298. } /* ${context}_valid_columns_set */
  299. @include generic-table-indexes-to-oid.m2i@
  300. @include generic-table-indexes-from-oid.m2i@
  301. ########################################################################
  302. ##
  303. @    if (($m2c_data_allocate == 1) || ($m2c_undo_embed == 0)) && ("$m2c_data_context" eq "generated")@
  304. @        eval $m2c_gda_todo_suppress = 1@ # no todo comments
  305. @        include generic-data-allocate.m2i@ # resets suppress
  306. @    end@
  307. ########################################################################
  308. /* *********************************************************************
  309.  * @internal
  310.  * allocate resources for a ${context}_rowreq_ctx
  311.  */
  312. ${context}_rowreq_ctx *
  313. @if $m2c_data_allocate == 1@
  314. @   eval $m2c_tmp = "${context}_data *data"@
  315. @   if $m2c_data_init == 1@
  316. @     eval $m2c_tmp = "$m2c_tmp, void *user_init_ctx"@
  317. @   end@
  318. @elsif $m2c_data_init == 1@
  319. @   eval $m2c_tmp = "void *user_init_ctx"@
  320. @else@
  321. @   eval $m2c_tmp = "void"@
  322. @end@
  323. ${context}_allocate_rowreq_ctx($m2c_tmp)
  324. {
  325.     ${context}_rowreq_ctx *rowreq_ctx =
  326.                   SNMP_MALLOC_TYPEDEF(${context}_rowreq_ctx);
  327.     DEBUGMSGTL(("internal:${context}:${context}_allocate_rowreq_ctx","calledn"));
  328.     if(NULL == rowreq_ctx) {
  329.         snmp_log(LOG_ERR,"Couldn't allocate memory for a "
  330.                  "${context}_rowreq_ctx.n");
  331.     }
  332. @if $m2c_data_allocate == 1@
  333.     else {
  334.         if(NULL != data) {
  335. @   if $m2c_data_transient == 0@
  336.             /*
  337.              * for non-transient data, track when we got data from user
  338.              */
  339.             rowreq_ctx->rowreq_flags |= MFD_ROW_DATA_FROM_USER;
  340. @   end@
  341.             rowreq_ctx->data = data;
  342.         }
  343.         else if (NULL == (rowreq_ctx->data = ${context}_allocate_data())) {
  344.             SNMP_FREE(rowreq_ctx);
  345.             return NULL;
  346.         }
  347.     }
  348.     /*
  349.      * undo context will be allocated when needed (in *_undo_setup)
  350.      */
  351. @end@
  352.     rowreq_ctx->oid_idx.oids = rowreq_ctx->oid_tmp;
  353.     rowreq_ctx->${context}_data_list = NULL;
  354.     rowreq_ctx->${context}_reg = ${context}_if_ctx.user_ctx;
  355. @if $m2c_data_init == 1@
  356.     if(SNMPERR_SUCCESS !=
  357.         ${context}_rowreq_ctx_init(rowreq_ctx, user_init_ctx)) {
  358.        ${context}_release_rowreq_ctx(rowreq_ctx);
  359.        rowreq_ctx = NULL;
  360.     }
  361. @end@
  362.     return rowreq_ctx;
  363. } /* ${context}_allocate_rowreq_ctx */
  364. /*
  365.  * @internal
  366.  * release resources for a ${context}_rowreq_ctx
  367.  */
  368. void
  369. ${context}_release_rowreq_ctx(${context}_rowreq_ctx *rowreq_ctx)
  370. {
  371.     DEBUGMSGTL(("internal:${context}:${context}_release_rowreq_ctx","calledn"));
  372.     netsnmp_assert(NULL != rowreq_ctx);
  373.     
  374. @if $m2c_data_init == 1@
  375.     ${context}_rowreq_ctx_cleanup(rowreq_ctx);
  376. @end@
  377. @if $m2c_data_allocate == 1@
  378. @   if $m2c_data_transient == 0@
  379.     /*
  380.      * for non-transient data, don't free data we got from the user
  381.      */
  382.     if ((rowreq_ctx->data) &&
  383.         !(rowreq_ctx->rowreq_flags & MFD_ROW_DATA_FROM_USER))
  384. @   else@
  385.     if (rowreq_ctx->data)
  386. @   end@ # // transient
  387.         ${context}_release_data(rowreq_ctx->data);
  388.  
  389. @end@ 
  390. @if $m2c_undo_embed == 0@
  391.     if(rowreq_ctx->undo)
  392.         ${context}_release_data(rowreq_ctx->undo);
  393.  
  394. @end@ 
  395.     /*
  396.      * free index oid pointer
  397.      */
  398.     if(rowreq_ctx->oid_idx.oids != rowreq_ctx->oid_tmp)
  399.         free(rowreq_ctx->oid_idx.oids);
  400.     SNMP_FREE(rowreq_ctx);
  401. } /* ${context}_release_rowreq_ctx */
  402. ########################################################################
  403. ##
  404. /**
  405.  * @internal
  406.  * wrapper
  407.  */
  408. static int
  409. _mfd_${context}_pre_request(netsnmp_mib_handler *handler,
  410.                             netsnmp_handler_registration *reginfo,
  411.                             netsnmp_agent_request_info *agtreq_info,
  412.                             netsnmp_request_info *requests)
  413. {
  414.     int rc = ${context}_pre_request(${context}_if_ctx.user_ctx);
  415.     if (MFD_SUCCESS != rc) {
  416.         /*
  417.          * nothing we can do about it but log it
  418.          */
  419.         DEBUGMSGTL(("internal:${context}","error %d from "
  420.                     "${context}_pre_requestn", rc));
  421.         netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
  422.     }
  423.     
  424.     return SNMP_ERR_NOERROR;
  425. } /* _mfd_${context}_pre_request */
  426. /**
  427.  * @internal
  428.  * wrapper
  429.  */
  430. static int
  431. _mfd_${context}_post_request(netsnmp_mib_handler *handler,
  432.                              netsnmp_handler_registration *reginfo,
  433.                              netsnmp_agent_request_info *agtreq_info,
  434.                              netsnmp_request_info *requests)
  435. {
  436.     ${context}_rowreq_ctx *rowreq_ctx;
  437.     int rc = ${context}_post_request(${context}_if_ctx.user_ctx);
  438.     if (MFD_SUCCESS != rc) {
  439.         /*
  440.          * nothing we can do about it but log it
  441.          */
  442.         DEBUGMSGTL(("internal:${context}","error %d from "
  443.                     "${context}_post_requestn", rc));
  444.     }
  445.     
  446.     /*
  447.      * if there are no errors, check for and handle row creation/deletion
  448.      */
  449.     rc = netsnmp_check_requests_error(requests);
  450.     if ((SNMP_ERR_NOERROR == rc) &&
  451.         (NULL !=
  452.          (rowreq_ctx = netsnmp_container_table_row_extract(requests)))) {
  453.         if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
  454.             rowreq_ctx->rowreq_flags &= ~MFD_ROW_CREATED;
  455.             CONTAINER_INSERT(${context}_if_ctx.container, rowreq_ctx);
  456.         }
  457.         else if (rowreq_ctx->rowreq_flags & MFD_ROW_DELETED) {
  458.             CONTAINER_REMOVE(${context}_if_ctx.container, rowreq_ctx);
  459.             ${context}_release_rowreq_ctx(rowreq_ctx);
  460.         }
  461.     }
  462.     return SNMP_ERR_NOERROR;
  463. } /* _mfd_${context}_post_request */
  464. ########################################################################
  465. ##
  466. /**
  467.  * @internal
  468.  * wrapper
  469.  */
  470. static int
  471. _mfd_${context}_object_lookup(netsnmp_mib_handler *handler,
  472.                          netsnmp_handler_registration *reginfo,
  473.                          netsnmp_agent_request_info *agtreq_info,
  474.                          netsnmp_request_info *requests)
  475. {
  476.     ${context}_rowreq_ctx *rowreq_ctx =
  477.                   netsnmp_container_table_row_extract(requests);
  478.     
  479.     DEBUGMSGTL(("internal:${context}:_mfd_${context}_object_lookup","calledn"));
  480.     /*
  481.      * get our context from mfd
  482.      * ${context}_interface_ctx *if_ctx =
  483.      *             (${context}_interface_ctx *)reginfo->my_reg_void;
  484.      */
  485.     if(NULL == rowreq_ctx) {
  486. @   if $m2c_table_row_creation == 0@
  487.         netsnmp_request_set_error_all(requests, SNMP_ERR_NOCREATION);
  488. @   else@
  489.         int rc = MFD_SUCCESS;
  490.         netsnmp_table_request_info *tblreq_info;
  491.         netsnmp_index oid_idx;
  492.         ${context}_mib_index mib_idx;
  493.         tblreq_info = netsnmp_extract_table_info(requests);
  494.         if(NULL == tblreq_info) {
  495.             snmp_log(LOG_ERR, "request had no table infon");
  496.             return MFD_ERROR;
  497.         }
  498.         /*
  499.          * try to parse oid
  500.          */
  501.         oid_idx.oids = tblreq_info->index_oid;
  502.         oid_idx.len = tblreq_info->index_oid_len;
  503.         rc = ${context}_index_from_oid(&oid_idx, &mib_idx);
  504.         if(MFD_SUCCESS != rc) {
  505.             DEBUGMSGT(("$context", "error parsing indexn"));
  506.             netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
  507.         }
  508.         else {
  509.             /*
  510.              * allocate new context
  511.              */
  512. @   eval $m2c_tmp = ""@
  513. @   if ($m2c_data_allocate == 1) || ($m2c_data_init == 1)@
  514. @      eval $m2c_tmp = "NULL"@
  515. @      if ($m2c_data_allocate == 1) && ($m2c_data_init == 1)@
  516. @         eval $m2c_tmp = "$m2c_tmp, NULL"@
  517. @      @end@
  518. @   end@
  519.             rowreq_ctx = ${context}_allocate_rowreq_ctx($m2c_tmp);
  520.             if (NULL == rowreq_ctx)
  521.                 return MFD_ERROR; /* msg already logged */
  522.             memcpy(&rowreq_ctx->tbl_idx, &mib_idx, sizeof(mib_idx));
  523.             /*
  524.              * check indexes
  525.              */
  526.             rc = _${context}_check_indexes(rowreq_ctx);
  527.             if(MFD_SUCCESS != rc) {
  528.                 netsnmp_assert((rc == SNMP_ERR_NOCREATION) ||
  529.                                (rc == SNMP_ERR_INCONSISTENTNAME));
  530.                 netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
  531.                 ${context}_release_rowreq_ctx(rowreq_ctx);
  532.             }
  533.             else {
  534.                 rowreq_ctx->rowreq_flags |= MFD_ROW_CREATED;
  535.                 netsnmp_container_table_row_insert(requests, rowreq_ctx);
  536.             }
  537.         }
  538. @   end@ // row creation
  539.     }
  540.     else {
  541.         ${context}_row_prep(rowreq_ctx);
  542.     }
  543.     return SNMP_ERR_NOERROR;
  544. } /* _mfd_${context}_object_lookup */
  545. ########################################################################
  546. ##
  547. /***********************************************************************
  548.  *
  549.  * GET processing
  550.  *
  551.  ***********************************************************************/
  552. /*
  553.  * @internal
  554.  * Retrieve the value for a particular column
  555.  */
  556. NETSNMP_STATIC_INLINE int
  557. _${context}_get_column( ${context}_rowreq_ctx *rowreq_ctx,
  558.                        netsnmp_variable_list *var, int column )
  559. {
  560.     int rc = SNMPERR_SUCCESS;
  561.     
  562.     DEBUGMSGTL(("internal:${context}:_mfd_${context}_get_column","calledn"));
  563.     netsnmp_assert(NULL != rowreq_ctx);
  564.     switch(column) {
  565. @   foreach $node internalindex@
  566. @      include m2c_setup_node.m2i@
  567. @      if $node.accessible == 1@
  568.     /* (INDEX) $m2c_node_summary */
  569.     case COLUMN_$node.uc:
  570.     var->type = $node.type;
  571. @         if $m2c_node_needlength == 1@
  572.     /*
  573.      * NOTE: val_len is in bytes, ${node}_len might not be (e.g. oids)
  574.      */
  575.         if (var->val_len < (rowreq_ctx->tbl_idx.${node}_len *
  576.                             sizeof(rowreq_ctx->tbl_idx.${node}[0]))) {
  577.            var->val.string = malloc(rowreq_ctx->tbl_idx.${node}_len *
  578.                                     sizeof(rowreq_ctx->tbl_idx.${node}[0]));
  579.         }
  580.         var->val_len = rowreq_ctx->tbl_idx.${node}_len * sizeof(rowreq_ctx->tbl_idx.${node}[0]);
  581.         memcpy( var->val.string, rowreq_ctx->tbl_idx.$node, var->val_len );
  582. @         else@
  583.         var->val_len = sizeof($m2c_decl);
  584.         (*var->val.integer) = rowreq_ctx->tbl_idx.$node;
  585. @         end@
  586.         break;
  587. @      end@ ## accessible
  588. @   end@ ## index
  589. @   foreach $node nonindex@
  590. @      include m2c_setup_node.m2i@
  591. @      if $node.accessible == 1@
  592.     /* $m2c_node_summary */
  593.     case COLUMN_$node.uc:
  594. @         if $m2c_node_needlength == 0@
  595.     var->val_len = sizeof($m2c_decl);
  596. @         end@
  597.     var->type = $node.type;
  598. rc = ${node}_get(rowreq_ctx, $m2c_node_var_ref );
  599.         break;
  600.  @      end@ # accessible
  601. @   end@ # for each column
  602.      default:
  603.          snmp_log(LOG_ERR,"unknown column %d in _${context}_get_columnn", column);
  604.          break;
  605.     }
  606.     return rc;
  607. } /* _${context}_get_column */
  608. ########################################################################
  609. ##
  610. int
  611. _mfd_${context}_get_values(netsnmp_mib_handler *handler,
  612.                          netsnmp_handler_registration *reginfo,
  613.                          netsnmp_agent_request_info *agtreq_info,
  614.                          netsnmp_request_info *requests)
  615. {
  616.     ${context}_rowreq_ctx *rowreq_ctx =
  617.                   netsnmp_container_table_row_extract(requests);
  618.     netsnmp_table_request_info * tri;
  619.     u_char                     * old_string;
  620.     void                      (*dataFreeHook)(void *);
  621.     int                        rc;
  622.     DEBUGMSGTL(("internal:${context}:_mfd_${context}_get_values","calledn"));
  623.     netsnmp_assert(NULL != rowreq_ctx);
  624.     
  625.     for(;requests; requests = requests->next) {
  626.         /*
  627.          * save old pointer, so we can free it if replaced
  628.          */
  629.         old_string = requests->requestvb->val.string;
  630.         dataFreeHook = requests->requestvb->dataFreeHook;
  631.         if(NULL == requests->requestvb->val.string) {
  632.             requests->requestvb->val.string = requests->requestvb->buf;
  633.             requests->requestvb->val_len = sizeof(requests->requestvb->buf);
  634.         }
  635.         else if(requests->requestvb->buf == requests->requestvb->val.string) {
  636.             if(requests->requestvb->val_len != sizeof(requests->requestvb->buf))
  637.                 requests->requestvb->val_len = sizeof(requests->requestvb->buf);
  638.         }
  639.         /*
  640.          * get column data
  641.          */
  642.         tri = netsnmp_extract_table_info(requests);
  643.         if(NULL == tri)
  644.             continue;
  645.         
  646.         rc = _${context}_get_column(rowreq_ctx, requests->requestvb, tri->colnum);
  647.         if(rc) {
  648.             if(MFD_SKIP == rc) {
  649.                 requests->requestvb->type = ASN_PRIV_RETRY;
  650.                 rc = SNMP_ERR_NOERROR;
  651.             }
  652.         }
  653.         else if (NULL == requests->requestvb->val.string) {
  654.             snmp_log(LOG_ERR,"NULL varbind data pointer!n");
  655.             rc = SNMP_ERR_GENERR;
  656.         }
  657.         if(rc)
  658.             netsnmp_request_set_error(requests, SNMP_VALIDATE_ERR(rc));
  659.         /*
  660.          * if the buffer wasn't used previously for the old data (i.e. it
  661.          * was allcoated memory)  and the get routine replaced the pointer,
  662.          * we need to free the previous pointer.
  663.          */
  664.         if(old_string && (old_string != requests->requestvb->buf) &&
  665.            (requests->requestvb->val.string != old_string)) {
  666.             if(dataFreeHook)
  667.                 (*dataFreeHook)(old_string);
  668.             else
  669.                 free(old_string);
  670.         }
  671.     } /* for results */
  672.     return SNMP_ERR_NOERROR;
  673. } /* _mfd_${context}_get_values */
  674. ########################################################################
  675. ##
  676. /***********************************************************************
  677.  *
  678.  * SET processing
  679.  *
  680.  ***********************************************************************/
  681. @if $m2c_table_settable == 0@
  682. /*
  683.  * NOT APPLICABLE (per MIB or user setting)
  684.  */
  685. @else@
  686. /*----------------------------------------------------------------------
  687.  *
  688.  * SET: Syntax checks
  689.  *
  690.  *---------------------------------------------------------------------*/
  691. /*
  692.  * @internal
  693.  * Check the syntax for a particular column
  694.  */
  695. NETSNMP_STATIC_INLINE int
  696. _${context}_check_column( ${context}_rowreq_ctx *rowreq_ctx,
  697.                          netsnmp_variable_list *var, int column )
  698. {
  699.     int rc = SNMPERR_SUCCESS;
  700.     
  701.     DEBUGMSGTL(("internal:${context}:_${context}_check_column","calledn"));
  702.     netsnmp_assert(NULL != rowreq_ctx);
  703.     switch(column) {
  704. @   foreach $node internalindex@
  705. @      include m2c_setup_node.m2i@
  706. @      if $node.settable == 1@
  707.     /* (INDEX) $m2c_node_summary */
  708.     case COLUMN_$node.uc:
  709.         return SNMP_ERR_NOTWRITABLE; /* can not change index of active row */
  710.         break;
  711. @      end@ ## settable
  712. @   end@ ## index
  713. @   foreach $node nonindex@
  714. @      include m2c_setup_node.m2i@
  715. @      if $node.settable == 0@
  716. @          next@
  717. @      end@
  718.     /* $m2c_node_summary */
  719.     case COLUMN_$node.uc:
  720. @      include node-varbind-validate.m2i@
  721.     if(SNMPERR_SUCCESS == rc) {
  722.         rc = ${node}_check_value( rowreq_ctx, $m2c_node_var_val );
  723.         if((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc) &&
  724.            (MFD_NOT_VALID_NOW != rc)) {
  725.             snmp_log(LOG_ERR, "bad rc %d from ${node}_check_valuen", rc);
  726.             rc = SNMP_ERR_GENERR;
  727.         }
  728.     }
  729.         break;
  730. @   end@ # for each nonindex
  731.         default: /** We shouldn't get here */
  732.             rc = SNMP_ERR_GENERR;
  733.             snmp_log(LOG_ERR, "unknown column %d in _${context}_check_columnn", column);
  734.     }
  735.     return rc;
  736. } /* _${context}_check_column */
  737. ##----------------------------------------------------------------------
  738. int
  739. _mfd_${context}_check_objects(netsnmp_mib_handler *handler,
  740.                          netsnmp_handler_registration *reginfo,
  741.                          netsnmp_agent_request_info *agtreq_info,
  742.                          netsnmp_request_info *requests)
  743. {
  744.     ${context}_rowreq_ctx *rowreq_ctx =
  745.                   netsnmp_container_table_row_extract(requests);
  746.     netsnmp_table_request_info * tri;
  747.     int                          rc;
  748.     DEBUGMSGTL(("internal:${context}:_mfd_${context}_check_objects","calledn"));
  749.     netsnmp_assert(NULL != rowreq_ctx);
  750.     
  751.     for(;requests; requests = requests->next) {
  752.         /*
  753.          * get column number from table request info, and check that column
  754.          */
  755.         tri = netsnmp_extract_table_info(requests);
  756.         if(NULL == tri)
  757.             continue;
  758.         rc = _${context}_check_column(rowreq_ctx, requests->requestvb, tri->colnum);
  759.         if(rc) {
  760.             netsnmp_request_set_error(requests, SNMP_VALIDATE_ERR(rc));
  761.             break;
  762.         }
  763.     } /* for results */
  764.     return SNMP_ERR_NOERROR;
  765. } /* _mfd_${context}_check_objects */
  766. ##----------------------------------------------------------------------
  767. @if $m2c_table_row_creation == 1@
  768. NETSNMP_STATIC_INLINE int
  769. _${context}_check_indexes(${context}_rowreq_ctx * rowreq_ctx)
  770. {
  771.     int                          rc;
  772.     DEBUGMSGTL(("internal:${context}:_${context}_check_indexes","calledn"));
  773.     netsnmp_assert(NULL != rowreq_ctx);
  774. ##
  775. @if $m2c_table_external_indexes != 0@
  776.     /*
  777.      * check that the corresponding row exists
  778.      */
  779. @   foreach $node externalindex@
  780. @      include m2c_setup_node.m2i@
  781.     /* (INDEX) $m2c_node_summary */
  782.     rc = ${context}_${node}_check_index( rowreq_ctx );
  783.     if(MFD_SUCCESS != rc)
  784.         return SNMP_ERR_NOCREATION;
  785. @   end@ # for each nonindex
  786. @end@ # external index
  787. @   foreach $node internalindex@
  788. @      include m2c_setup_node.m2i@
  789.     /* (INDEX) $m2c_node_summary */
  790.         rc = ${node}_check_index( rowreq_ctx );
  791.        if(MFD_SUCCESS != rc)
  792.            return SNMP_ERR_NOCREATION;
  793. @   end@ # for each internalindex
  794.     /*
  795.      * if individual parts look ok, check them as a whole
  796.      */
  797.     return ${context}_validate_index( rowreq_ctx->${context}_reg, rowreq_ctx );
  798. } /* _${context}_check_indexes */
  799. @end@ # $m2c_table_row_creation
  800. @      if $m2c_table_dependencies == 1@
  801. /*----------------------------------------------------------------------
  802.  *
  803.  * SET: check dependencies
  804.  *
  805.  *---------------------------------------------------------------------*/
  806. /*
  807.  * @internal
  808.  * Check dependencies wrapper
  809.  */
  810. static int
  811. _mfd_${context}_check_dependencies(netsnmp_mib_handler *handler,
  812.                          netsnmp_handler_registration *reginfo,
  813.                          netsnmp_agent_request_info *agtreq_info,
  814.                          netsnmp_request_info *requests)
  815. {
  816.     int                    rc;
  817.     ${context}_rowreq_ctx *rowreq_ctx =
  818.                   netsnmp_container_table_row_extract(requests);
  819.     DEBUGMSGTL(("internal:${context}:_mfd_${context}_check_dependencies","calledn"));
  820.     netsnmp_assert(NULL != rowreq_ctx);
  821.     rc = ${context}_check_dependencies(rowreq_ctx);
  822.     if(rc){
  823.         DEBUGMSGTL(("verbose:${context}:mfd","error %d from "
  824.                     "${context}_check_dependenciesn", rc));
  825.         netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
  826.     }
  827.     return SNMP_ERR_NOERROR;
  828. } /* _mfd_${context}_check_dependencies */
  829. @end@ // dependencies
  830. /*----------------------------------------------------------------------
  831.  *
  832.  * SET: Undo setup
  833.  *
  834.  *---------------------------------------------------------------------*/
  835. /*
  836.  * @internal
  837.  * Set the value for a particular column
  838.  */
  839. NETSNMP_STATIC_INLINE int
  840. _${context}_undo_setup_column( ${context}_rowreq_ctx *rowreq_ctx, int column )
  841. {
  842.     int rc = SNMPERR_SUCCESS;
  843.     
  844.     DEBUGMSGTL(("internal:${context}:_${context}_undo_setup_column","calledn"));
  845.     netsnmp_assert(NULL != rowreq_ctx);
  846.     switch(column) {
  847. @   foreach $node nonindex@
  848. @      include m2c_setup_node.m2i@
  849. @      if $node.settable == 1@
  850.     /* $m2c_node_summary */
  851.     case COLUMN_$node.uc:
  852.         rowreq_ctx->column_set_flags |= FLAG_$node.uc;
  853.         rc = ${node}_undo_setup(rowreq_ctx );
  854.         break;
  855.  @      end@ # settable
  856. @   end@ # for each column
  857.      default:
  858.          snmp_log(LOG_ERR,"unknown column %d in _${context}_undo_setup_columnn", column);
  859.          break;
  860.     }
  861.     return rc;
  862. } /* _${context}_undo_setup_column */
  863. ##----------------------------------------------------------------------
  864. /**
  865.  * @internal
  866.  * undo setup
  867.  */
  868. int
  869. _mfd_${context}_undo_setup(netsnmp_mib_handler *handler,
  870.                          netsnmp_handler_registration *reginfo,
  871.                          netsnmp_agent_request_info *agtreq_info,
  872.                          netsnmp_request_info *requests)
  873. {
  874.     int                    rc;
  875.     ${context}_rowreq_ctx *rowreq_ctx =
  876.                   netsnmp_container_table_row_extract(requests);
  877.     DEBUGMSGTL(("internal:${context}:_mfd_${context}_undo_setup","calledn"));
  878.     netsnmp_assert(NULL != rowreq_ctx);
  879. @if $m2c_undo_embed == 0@
  880.     /*
  881.      * allocate undo context
  882.      */
  883.     rowreq_ctx->undo = ${context}_allocate_data();
  884.     if(NULL == rowreq_ctx->undo) {
  885.         /** msg already logged */
  886.         netsnmp_request_set_error_all(requests, SNMP_ERR_RESOURCEUNAVAILABLE);
  887.         return SNMP_ERR_NOERROR;
  888.     }
  889. @end@
  890.     /*
  891.      * row undo setup
  892.      */
  893.     rowreq_ctx->column_set_flags = 0;
  894.     rc = ${context}_undo_setup(rowreq_ctx);
  895.     if (MFD_SUCCESS != rc)  {
  896.         DEBUGMSGTL(("verbose:${context}:mfd","error %d from "
  897.                     "${context}_undo_setupn", rc));
  898.         netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
  899.     }
  900.     else {
  901.         /*
  902.          * column undo setup
  903.          */
  904.         netsnmp_table_request_info * tri;
  905.         for(;requests; requests = requests->next) {
  906.             /*
  907.              * set column data
  908.              */
  909.             tri = netsnmp_extract_table_info(requests);
  910.             if(NULL == tri)
  911.                 continue;
  912.             
  913.             rc = _${context}_undo_setup_column(rowreq_ctx, tri->colnum);
  914.             if(MFD_SUCCESS != rc)  {
  915.                 DEBUGMSGTL(("verbose:${context}:mfd","error %d from "
  916.                             "${context}_undo_setup_columnn", rc));
  917.                 netsnmp_set_request_error(agtreq_info, requests, SNMP_VALIDATE_ERR(rc));
  918.             }
  919.         } /* for results */
  920.     }
  921.     
  922.     return SNMP_ERR_NOERROR;
  923. } /* _mfd_${context}_undo_setup */
  924. /**
  925.  * @internal
  926.  * undo setup
  927.  */
  928. int
  929. _mfd_${context}_undo_cleanup(netsnmp_mib_handler *handler,
  930.                              netsnmp_handler_registration *reginfo,
  931.                              netsnmp_agent_request_info *agtreq_info,
  932.                              netsnmp_request_info *requests)
  933. {
  934.     ${context}_rowreq_ctx *rowreq_ctx =
  935.                   netsnmp_container_table_row_extract(requests);
  936.     int rc;
  937.     DEBUGMSGTL(("internal:${context}:_mfd_${context}_undo_cleanup","calledn"));
  938.     /*
  939.      * failed row create in early stages has no rowreq_ctx
  940.      */
  941.     if (NULL == rowreq_ctx)
  942.         return MFD_SUCCESS;
  943.     /*
  944.      * call user cleanup
  945.      */
  946.     rc = ${context}_undo_cleanup(rowreq_ctx);
  947.     if (MFD_SUCCESS != rc) {
  948.         /*
  949.          * nothing we can do about it but log it
  950.          */
  951.         DEBUGMSGTL(("verbose:${context}:mfd","error %d from "
  952.                     "${context}_undo_cleanupn", rc));
  953.     }
  954. @if $m2c_undo_embed == 0@
  955.     /*
  956.      * release undo context, if needed
  957.      */
  958.     if(rowreq_ctx->undo) {
  959.          ${context}_release_data(rowreq_ctx->undo);
  960.          rowreq_ctx->undo = NULL;
  961.     }
  962. @end@
  963.     /*
  964.      * clear set flags
  965.      */
  966.     rowreq_ctx->column_set_flags = 0;
  967.     return SNMP_ERR_NOERROR;
  968. } /* _mfd_${context}_undo_cleanup */
  969. /*----------------------------------------------------------------------
  970.  *
  971.  * SET: Set values
  972.  *
  973.  *---------------------------------------------------------------------*/
  974. /*
  975.  * @internal
  976.  * Set the value for a particular column
  977.  */
  978. NETSNMP_STATIC_INLINE int
  979. _${context}_set_column( ${context}_rowreq_ctx *rowreq_ctx,
  980.                        netsnmp_variable_list *var, int column )
  981. {
  982.     int rc = SNMPERR_SUCCESS;
  983.     
  984.     DEBUGMSGTL(("internal:${context}:_${context}_set_column","calledn"));
  985.     netsnmp_assert(NULL != rowreq_ctx);
  986.     switch(column) {
  987. @   foreach $node nonindex@
  988. @      include m2c_setup_node.m2i@
  989. @      if $node.settable == 1@
  990.     /* $m2c_node_summary */
  991.     case COLUMN_$node.uc:
  992. @         if $m2c_node_needlength == 0@
  993.         if(var->val_len != sizeof($m2c_decl)) {
  994.             rc = SNMP_ERR_WRONGLENGTH;
  995.             snmp_log(LOG_ERR,
  996.                      "varbind size of %d does not match expected size %dn",
  997.                      var->val_len, sizeof($m2c_decl));
  998.             break;
  999.         }
  1000. @         end@
  1001.         rowreq_ctx->column_set_flags |= FLAG_$node.uc;
  1002.         rc = ${node}_set(rowreq_ctx, $m2c_node_var_val );
  1003.         break;
  1004.  @      end@ # settable
  1005. @   end@ # for each column
  1006.      default:
  1007.          snmp_log(LOG_ERR,"unknown column %d in _${context}_set_columnn", column);
  1008.          break;
  1009.     }
  1010.     
  1011.     return rc;
  1012. } /* _${context}_set_column */
  1013. ########################################################################
  1014. ##
  1015. int
  1016. _mfd_${context}_set_values(netsnmp_mib_handler *handler,
  1017.                          netsnmp_handler_registration *reginfo,
  1018.                          netsnmp_agent_request_info *agtreq_info,
  1019.                          netsnmp_request_info *requests)
  1020. {
  1021.     ${context}_rowreq_ctx *rowreq_ctx =
  1022.                   netsnmp_container_table_row_extract(requests);
  1023.     netsnmp_table_request_info * tri;
  1024.     int                          rc = SNMP_ERR_NOERROR;
  1025.     DEBUGMSGTL(("internal:${context}:_mfd_${context}_set_values","calledn"));
  1026.     netsnmp_assert(NULL != rowreq_ctx);
  1027.     
  1028.     rowreq_ctx->column_set_flags = 0;
  1029.     for(;requests; requests = requests->next) {
  1030.         /*
  1031.          * set column data
  1032.          */
  1033.         tri = netsnmp_extract_table_info(requests);
  1034.         if(NULL == tri)
  1035.             continue;
  1036.         
  1037.         rc = _${context}_set_column(rowreq_ctx,
  1038.                                     requests->requestvb, tri->colnum);
  1039.         if(MFD_SUCCESS != rc)  {
  1040.             DEBUGMSGTL(("verbose:${context}:mfd","error %d from "
  1041.                         "${context}_set_columnn", rc));
  1042.             netsnmp_set_request_error(agtreq_info, requests, SNMP_VALIDATE_ERR(rc));
  1043.         }
  1044.     } /* for results */
  1045.     return SNMP_ERR_NOERROR;
  1046. } /* _mfd_${context}_set_values */
  1047. /*----------------------------------------------------------------------
  1048.  *
  1049.  * SET: commit
  1050.  *
  1051.  *---------------------------------------------------------------------*/
  1052. /**
  1053.  * @internal
  1054.  * commit the values
  1055.  */
  1056. int
  1057. _mfd_${context}_commit(netsnmp_mib_handler *handler,
  1058.                          netsnmp_handler_registration *reginfo,
  1059.                          netsnmp_agent_request_info *agtreq_info,
  1060.                          netsnmp_request_info *requests)
  1061. {
  1062.     int                    rc;
  1063.     ${context}_rowreq_ctx *rowreq_ctx =
  1064.                   netsnmp_container_table_row_extract(requests);
  1065.     DEBUGMSGTL(("internal:${context}:_mfd_${context}_commit","calledn"));
  1066.     netsnmp_assert(NULL != rowreq_ctx);
  1067.     
  1068.     rc = ${context}_commit(rowreq_ctx);
  1069.     if (MFD_SUCCESS != rc) {
  1070.         DEBUGMSGTL(("verbose:${context}:mfd","error %d from "
  1071.                     "${context}_commitn", rc));
  1072.         netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
  1073.     }
  1074.     return SNMP_ERR_NOERROR;
  1075. }
  1076. int
  1077. _mfd_${context}_undo_commit(netsnmp_mib_handler *handler,
  1078.                          netsnmp_handler_registration *reginfo,
  1079.                          netsnmp_agent_request_info *agtreq_info,
  1080.                          netsnmp_request_info *requests)
  1081. {
  1082.     int                    rc;
  1083.     ${context}_rowreq_ctx *rowreq_ctx =
  1084.                   netsnmp_container_table_row_extract(requests);
  1085.     DEBUGMSGTL(("internal:${context}:_mfd_${context}_undo_commit","calledn"));
  1086.     netsnmp_assert(NULL != rowreq_ctx);
  1087.     rc = ${context}_undo_commit(rowreq_ctx);
  1088.     if (MFD_SUCCESS != rc) {
  1089.         /*
  1090.          * nothing we can do about it but log it
  1091.          */
  1092.         DEBUGMSGTL(("verbose:${context}:mfd","error %d from "
  1093.                     "${context}_undo_commitn", rc));
  1094.     }
  1095.     return SNMP_ERR_NOERROR;
  1096. } /* _mfd_${context}_commit */
  1097. /*----------------------------------------------------------------------
  1098.  *
  1099.  * SET: Undo
  1100.  *
  1101.  *---------------------------------------------------------------------*/
  1102. /**
  1103.  * @internal
  1104.  * undo the value for a particular column
  1105.  */
  1106. NETSNMP_STATIC_INLINE int
  1107. _${context}_undo_column( ${context}_rowreq_ctx *rowreq_ctx,
  1108.                        netsnmp_variable_list *var, int column )
  1109. {
  1110.     int rc = SNMPERR_SUCCESS;
  1111.     
  1112.     DEBUGMSGTL(("internal:${context}:_${context}_undo_column","calledn"));
  1113.     netsnmp_assert(NULL != rowreq_ctx);
  1114.     switch(column) {
  1115. @   foreach $node nonindex@
  1116. @      include m2c_setup_node.m2i@
  1117. @      if $node.settable == 1@
  1118.     /* $m2c_node_summary */
  1119.     case COLUMN_$node.uc:
  1120.         rc = ${node}_undo(rowreq_ctx);
  1121.         break;
  1122.  @      end@ # settable
  1123. @   end@ # for each column
  1124.      default:
  1125.          snmp_log(LOG_ERR,"unknown column %d in _${context}_undo_columnn", column);
  1126.          break;
  1127.     }
  1128.     return rc;
  1129. } /* _${context}_undo_column */
  1130. ########################################################################
  1131. ##
  1132. int
  1133. _mfd_${context}_undo_values(netsnmp_mib_handler *handler,
  1134.                          netsnmp_handler_registration *reginfo,
  1135.                          netsnmp_agent_request_info *agtreq_info,
  1136.                          netsnmp_request_info *requests)
  1137. {
  1138.     int                    rc;
  1139.     ${context}_rowreq_ctx *rowreq_ctx =
  1140.                   netsnmp_container_table_row_extract(requests);
  1141.     netsnmp_table_request_info * tri;
  1142.     DEBUGMSGTL(("internal:${context}:_mfd_${context}_undo_values","calledn"));
  1143.     netsnmp_assert(NULL != rowreq_ctx);
  1144.     
  1145.     for(;requests; requests = requests->next) {
  1146.         /*
  1147.          * set column data
  1148.          */
  1149.         tri = netsnmp_extract_table_info(requests);
  1150.         if(NULL == tri)
  1151.             continue;
  1152.         
  1153.         rc = _${context}_undo_column(rowreq_ctx, requests->requestvb,
  1154.                                      tri->colnum);
  1155.         if (MFD_SUCCESS != rc) {
  1156.             /*
  1157.              * nothing we can do about it but log it
  1158.              */
  1159.             DEBUGMSGTL(("verbose:${context}:mfd","error %d from "
  1160.                         "${context}_undo_columnn", rc));
  1161.         }
  1162.     } /* for results */
  1163.     return SNMP_ERR_NOERROR;
  1164. } /* _mfd_${context}_undo_values */
  1165. @   if $m2c_irreversible_commit == 1@
  1166. /*----------------------------------------------------------------------
  1167.  *
  1168.  * SET: irreversible commit
  1169.  *
  1170.  *---------------------------------------------------------------------*/
  1171. /**
  1172.  * @internal
  1173.  * commit irreversible actions
  1174.  */
  1175. int
  1176. _mfd_${context}_irreversible_commit(netsnmp_mib_handler *handler,
  1177.                          netsnmp_handler_registration *reginfo,
  1178.                          netsnmp_agent_request_info *agtreq_info,
  1179.                          netsnmp_request_info *requests)
  1180. {
  1181.     int                    rc;
  1182.     ${context}_rowreq_ctx *rowreq_ctx =
  1183.                   netsnmp_container_table_row_extract(requests);
  1184.     
  1185.     DEBUGMSGTL(("internal:${context}:_mfd_${context}_irreversible:commit","calledn"));
  1186.    
  1187.     netsnmp_assert(NULL != rowreq_ctx);
  1188.     
  1189.     rc = ${context}_irreversible_commit(rowreq_ctx);
  1190.     if (MFD_SUCCESS != rc) {
  1191.         netsnmp_request_set_error_all(requests, SNMP_ERR_COMMITFAILED);
  1192.         DEBUGMSGTL(("verbose:${context}:mfd","error %d from "
  1193.                     "${context}_irreversible_commitn", rc));
  1194.     }
  1195.     
  1196.     return SNMP_ERR_NOERROR;
  1197. } /* _mfd_${context}_irreversible_commit */
  1198. @end@
  1199. @end@ # settable
  1200. /***********************************************************************
  1201.  *
  1202.  * DATA ACCESS
  1203.  *
  1204.  ***********************************************************************/
  1205. @    include mfd-access-${m2c_table_access}-defines.m2i@
  1206. @end@ # foreach table
  1207. ##
  1208. ########################################################################
  1209. @if $m2c_mark_boundary == 1@
  1210. /** END code generated by $RCSfile: mfd-interface.m2c,v $ $Revision: 1.43.2.3 $ */
  1211. @end@