=== modified file 'agent/agent_trap.c'
--- agent/agent_trap.c	2010-10-23 08:33:56 +0000
+++ agent/agent_trap.c	2010-10-25 10:51:01 +0000
@@ -78,36 +78,29 @@
 
 struct trap_sink *sinks = NULL;
 
-extern struct timeval starttime;
-
-oid             objid_enterprisetrap[] = { NETSNMP_NOTIFICATION_MIB };
-oid             trap_version_id[] = { NETSNMP_SYSTEM_MIB };
-int             enterprisetrap_len;
-int             trap_version_id_len;
+const oid       objid_enterprisetrap[] = { NETSNMP_NOTIFICATION_MIB };
+const oid       trap_version_id[] = { NETSNMP_SYSTEM_MIB };
+const int       enterprisetrap_len = OID_LENGTH(objid_enterprisetrap);
+const int       trap_version_id_len = OID_LENGTH(trap_version_id);
 
 #define SNMPV2_TRAPS_PREFIX	SNMP_OID_SNMPMODULES,1,1,5
-oid             trap_prefix[]    = { SNMPV2_TRAPS_PREFIX };
-oid             cold_start_oid[] = { SNMPV2_TRAPS_PREFIX, 1 };  /* SNMPv2-MIB */
-oid             warm_start_oid[] = { SNMPV2_TRAPS_PREFIX, 2 };  /* SNMPv2-MIB */
-oid             link_down_oid[]  = { SNMPV2_TRAPS_PREFIX, 3 };  /* IF-MIB */
-oid             link_up_oid[]    = { SNMPV2_TRAPS_PREFIX, 4 };  /* IF-MIB */
-oid             auth_fail_oid[]  = { SNMPV2_TRAPS_PREFIX, 5 };  /* SNMPv2-MIB */
-oid             egp_xxx_oid[]    = { SNMPV2_TRAPS_PREFIX, 99 }; /* ??? */
+const oid       trap_prefix[]    = { SNMPV2_TRAPS_PREFIX };
+const oid       cold_start_oid[] = { SNMPV2_TRAPS_PREFIX, 1 };  /* SNMPv2-MIB::coldStart */
+const size_t    cold_start_oid_len = OID_LENGTH(cold_start_oid);
 
 #define SNMPV2_TRAP_OBJS_PREFIX	SNMP_OID_SNMPMODULES,1,1,4
-oid             snmptrap_oid[] = { SNMPV2_TRAP_OBJS_PREFIX, 1, 0 };
-oid             snmptrapenterprise_oid[] =
-    { SNMPV2_TRAP_OBJS_PREFIX, 3, 0 };
-oid             sysuptime_oid[] = { SNMP_OID_MIB2, 1, 3, 0 };
-size_t          snmptrap_oid_len;
-size_t          snmptrapenterprise_oid_len;
-size_t          sysuptime_oid_len;
+const oid       snmptrap_oid[] = { SNMPV2_TRAP_OBJS_PREFIX, 1, 0 };
+const oid       snmptrapenterprise_oid[] = { SNMPV2_TRAP_OBJS_PREFIX, 3, 0 };
+const oid       sysuptime_oid[] = { SNMP_OID_MIB2, 1, 3, 0 };
+const size_t    snmptrap_oid_len = OID_LENGTH(snmptrap_oid);
+const size_t    snmptrapenterprise_oid_len = OID_LENGTH(snmptrapenterprise_oid);
+const size_t    sysuptime_oid_len = OID_LENGTH(sysuptime_oid);
 
 #define SNMPV2_COMM_OBJS_PREFIX	SNMP_OID_SNMPMODULES,18,1
-oid             agentaddr_oid[] = { SNMPV2_COMM_OBJS_PREFIX, 3, 0 };
-size_t          agentaddr_oid_len;
-oid             community_oid[] = { SNMPV2_COMM_OBJS_PREFIX, 4, 0 };
-size_t          community_oid_len;
+const oid       agentaddr_oid[] = { SNMPV2_COMM_OBJS_PREFIX, 3, 0 };
+const size_t    agentaddr_oid_len = OID_LENGTH(agentaddr_oid);
+const oid       community_oid[] = { SNMPV2_COMM_OBJS_PREFIX, 4, 0 };
+const size_t    community_oid_len = OID_LENGTH(community_oid);
 #if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
 char           *snmp_trapcommunity = NULL;
 #endif
@@ -141,18 +134,12 @@
 void
 init_traps(void)
 {
-    enterprisetrap_len  = OID_LENGTH(objid_enterprisetrap);
-    trap_version_id_len = OID_LENGTH(trap_version_id);
-    snmptrap_oid_len    = OID_LENGTH(snmptrap_oid);
-    snmptrapenterprise_oid_len = OID_LENGTH(snmptrapenterprise_oid);
-    sysuptime_oid_len   = OID_LENGTH(sysuptime_oid);
-    agentaddr_oid_len   = OID_LENGTH(agentaddr_oid);
-    community_oid_len   = OID_LENGTH(community_oid);
 }
 
 static void
 free_trap_session(struct trap_sink *sp)
 {
+    DEBUGMSGTL(("trap", "freeing callback trap session (%p, %p)\n", sp, sp->sesp));
     snmp_close(sp->sesp);
     free(sp);
 }
@@ -168,7 +155,7 @@
          * something else wants to handle notification registrations 
          */
         struct agent_add_trap_args args;
-        DEBUGMSGTL(("trap", "adding callback trap sink\n"));
+        DEBUGMSGTL(("trap", "adding callback trap sink (%p)\n", ss));
         args.ss = ss;
         args.confirm = confirm;
         snmp_call_callbacks(SNMP_CALLBACK_APPLICATION,
@@ -197,8 +184,9 @@
 int
 remove_trap_session(netsnmp_session * ss)
 {
-    struct trap_sink *sp = sinks, *prev = 0;
+    struct trap_sink *sp = sinks, *prev = NULL;
 
+    DEBUGMSGTL(("trap", "removing trap sessions\n"));
     while (sp) {
         if (sp->sesp == ss) {
             if (prev) {
@@ -216,6 +204,7 @@
             /*
              * free_trap_session(sp);  
              */
+            DEBUGMSGTL(("trap", "removing trap session (%p, %p)\n", sp, sp->sesp));
             free(sp);
             return 1;
         }
@@ -318,6 +307,7 @@
 snmpd_free_trapsinks(void)
 {
     struct trap_sink *sp = sinks;
+    DEBUGMSGTL(("trap", "freeing trap sessions\n"));
     while (sp) {
         sinks = sinks->next;
         free_trap_session(sp);
@@ -325,7 +315,7 @@
     }
 }
 
-        /*******************
+	/*******************
 	 *
 	 * Trap handling
 	 *
@@ -338,7 +328,6 @@
     netsnmp_pdu           *template_v1pdu;
     netsnmp_variable_list *first_vb, *vblist;
     netsnmp_variable_list *var;
-    size_t                 len;
 
     /*
      * Make a copy of the v2 Trap PDU
@@ -418,9 +407,10 @@
                              snmptrapenterprise_oid,
                              snmptrapenterprise_oid_len);
         if (var) {
-            memdup((u_char**)&template_v1pdu->enterprise,
-                   (const u_char*)var->val.objid, var->val_len);
             template_v1pdu->enterprise_length = var->val_len/sizeof(oid);
+            template_v1pdu->enterprise =
+                snmp_duplicate_objid(var->val.objid,
+                                     template_v1pdu->enterprise_length);
         } else {
             template_v1pdu->enterprise        = NULL;
             template_v1pdu->enterprise_length = 0;		/* XXX ??? */
@@ -430,10 +420,10 @@
          * For enterprise-specific traps, split the snmpTrapOID value
          *   into enterprise and specific trap
          */
-        len = vblist->val_len / sizeof(oid);
+        size_t len = vblist->val_len / sizeof(oid);
         if ( len <= 2 ) {
             snmp_log(LOG_WARNING,
-                     "send_trap: v2 trapOID too short (%d)\n", len);
+                     "send_trap: v2 trapOID too short (%d)\n", (int)len);
             snmp_free_pdu(template_v1pdu);
             return NULL;
         }
@@ -443,8 +433,8 @@
         if (vblist->val.objid[len-1] == 0)
             len--;
         SNMP_FREE(template_v1pdu->enterprise);
-        memdup((u_char**)&template_v1pdu->enterprise,
-               (u_char *)vblist->val.objid, len*sizeof(oid));
+        template_v1pdu->enterprise =
+            snmp_duplicate_objid(vblist->val.objid, len);
         template_v1pdu->enterprise_length = len;
     }
     var = find_varbind_in_list( vblist, agentaddr_oid,
@@ -502,8 +492,8 @@
         enterprise[enterprise_len++] = template_v1pdu->specific_type;
     } else {
         memcpy(enterprise, cold_start_oid, sizeof(cold_start_oid));
-	enterprise[9]  = template_v1pdu->trap_type+1;
-        enterprise_len = sizeof(cold_start_oid)/sizeof(oid);
+        enterprise[cold_start_oid_len - 1]  = template_v1pdu->trap_type + 1; //FIXME magic BUG! ck
+        enterprise_len = cold_start_oid_len;
     }
 
     var = NULL;
@@ -607,7 +597,7 @@
  *			
  * @param specific is the specific trap value.
  *
- * @param enterprise is an enterprise oid in which you want to send specifc 
+ * @param enterprise is an enterprise oid in which you want to send specific 
  *	traps from. 
  *
  * @param enterprise_length is the length of the enterprise oid, use macro,
@@ -627,9 +617,9 @@
  */
 int
 netsnmp_send_traps(int trap, int specific,
-                          oid * enterprise, int enterprise_length,
+                          const oid * enterprise, int enterprise_length,
                           netsnmp_variable_list * vars,
-                          char * context, int flags)
+                          const char * context, int flags)
 {
     netsnmp_pdu           *template_v1pdu;
     netsnmp_pdu           *template_v2pdu;
@@ -720,7 +710,7 @@
                 !snmp_varlist_add_variable( &(template_v2pdu->variables),
                      snmptrapenterprise_oid, snmptrapenterprise_oid_len,
                      ASN_OBJECT_ID,
-                     (char*)enterprise, enterprise_length*sizeof(oid))) {
+                     (u_char*)enterprise, enterprise_length*sizeof(oid))) {
                 snmp_log(LOG_WARNING,
                      "send_trap: failed to add snmpEnterprise to v2 trap\n");
                 snmp_free_pdu(template_v2pdu);
@@ -754,7 +744,7 @@
         template_v1pdu->time          = netsnmp_get_agent_uptime();
 
         if (snmp_clone_mem((void **) &template_v1pdu->enterprise,
-                       enterprise, enterprise_length * sizeof(oid))) {
+                       (void *)enterprise, enterprise_length * sizeof(oid))) {
             snmp_log(LOG_WARNING,
                      "send_trap: failed to set v1 enterprise OID\n");
             snmp_free_varbind(vblist);
@@ -795,6 +785,13 @@
       *pdu_in_addr_t = get_myaddr();
     }
 
+	/* A context name was provided, so copy it and its length to the v2 pdu
+	 * template. */
+	if (context != NULL)
+	{
+		template_v2pdu->contextName    = strdup(context);
+		template_v2pdu->contextNameLen = strlen(context);
+	}
 
     /*
      *  Now loop through the list of trap sinks
@@ -832,7 +829,7 @@
 void
 send_enterprise_trap_vars(int trap,
                           int specific,
-                          oid * enterprise, int enterprise_length,
+                          const oid * enterprise, int enterprise_length,
                           netsnmp_variable_list * vars)
 {
     netsnmp_send_traps(trap, specific,
@@ -889,14 +886,14 @@
 {
     netsnmp_pdu    *pdu;
     int            result;
-    char           tmp[SPRINT_MAX_LEN];
+    u_char           tmp[SPRINT_MAX_LEN];
     int            len;
 
 
     if (!sess || !template_pdu)
         return;
 
-    DEBUGMSGTL(("trap", "sending trap type=%d, version=%d\n",
+    DEBUGMSGTL(("trap", "sending trap type=%d, version=%ld\n",
                 template_pdu->command, sess->version));
 
 #ifndef NETSNMP_DISABLE_SNMPV1
@@ -951,6 +948,21 @@
                                   OID_LENGTH(trap_version_id), vars);
 }
 
+/* Send a trap under a context */
+void send_trap_vars_with_context(int trap, int specific, 
+              netsnmp_variable_list *vars, const char *context)
+{
+    if (trap == SNMP_TRAP_ENTERPRISESPECIFIC)
+        netsnmp_send_traps(trap, specific, objid_enterprisetrap,
+                                  OID_LENGTH(objid_enterprisetrap), vars,
+								  context, 0);
+    else
+        netsnmp_send_traps(trap, specific, trap_version_id,
+                                  OID_LENGTH(trap_version_id), vars, 
+								  context, 0);
+    	
+}
+
 /**
  * Sends an SNMPv1 trap (or the SNMPv2 equivalent) to the list of  
  * configured trap destinations (or "sinks"), using the provided 
@@ -1009,6 +1021,25 @@
     send_trap_vars(-1, -1, vars);
 }
 
+/**
+ * Similar to send_v2trap(), with the added ability to specify a context.  If
+ * the last parameter is NULL, then this call is equivalent to send_v2trap().
+ *
+ * @param vars is used to supply the list of variable bindings for the trap.
+ * 
+ * @param context is used to specify the context of the trap.
+ *
+ * @return void
+ *
+ * @see send_v2trap
+ */
+void send_v3trap(netsnmp_variable_list *vars, const char *context)
+{
+    netsnmp_send_traps(-1, -1, 
+                       trap_version_id, OID_LENGTH(trap_version_id),
+                       vars, context, 0);
+}
+
 void
 send_trap_pdu(netsnmp_pdu *pdu)
 {
@@ -1173,8 +1204,8 @@
 void
 snmpd_parse_config_trapsess(const char *word, char *cptr)
 {
-    char           *argv[MAX_ARGS], *cp = cptr, tmp[SPRINT_MAX_LEN];
-    int             argn, arg;
+    char           *argv[MAX_ARGS], *cp = cptr;
+    int             argn, arg, rc;
     netsnmp_session session, *ss;
     size_t          len;
 
@@ -1188,6 +1219,8 @@
      */
     argv[0] = strdup("snmpd-trapsess"); /* bogus entry for getopt() */
     for (argn = 1; cp && argn < MAX_ARGS; argn++) {
+        char            tmp[SPRINT_MAX_LEN];
+
         cp = copy_nword(cp, tmp, SPRINT_MAX_LEN);
         argv[argn] = strdup(tmp);
     }
@@ -1215,21 +1248,18 @@
     if (ss->version == SNMP_VERSION_3 &&
         traptype != SNMP_MSG_INFORM   &&
         ss->securityEngineIDLen == 0) {
+            u_char          tmp[SPRINT_MAX_LEN];
+
             len = snmpv3_get_engineID( tmp, sizeof(tmp));
             memdup(&ss->securityEngineID, tmp, len);
             ss->securityEngineIDLen = len;
     }
 
 #ifndef NETSNMP_DISABLE_SNMPV1
-    if (ss->version == SNMP_VERSION_1) {
-        add_trap_session(ss, SNMP_MSG_TRAP, 0, SNMP_VERSION_1);
-    } else {
-#endif
-        add_trap_session(ss, traptype, (traptype == SNMP_MSG_INFORM),
-                         ss->version);
-#ifndef NETSNMP_DISABLE_SNMPV1
-    }
-#endif
+    if (ss->version == SNMP_VERSION_1)
+        traptype = SNMP_MSG_TRAP;
+#endif
+    add_trap_session(ss, traptype, (traptype == SNMP_MSG_INFORM), ss->version);
 }
 
 #if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)

=== modified file 'agent/helpers/table.c'
--- agent/helpers/table.c	2010-10-23 08:33:56 +0000
+++ agent/helpers/table.c	2010-10-24 17:06:04 +0000
@@ -108,10 +108,22 @@
 netsnmp_register_table(netsnmp_handler_registration *reginfo,
                        netsnmp_table_registration_info *tabreq)
 {
-    netsnmp_inject_handler(reginfo, netsnmp_get_table_handler(tabreq));
+    int rc = netsnmp_inject_handler(reginfo, netsnmp_get_table_handler(tabreq));
+    if (SNMPERR_SUCCESS != rc)
+        return rc;
+
     return netsnmp_register_handler(reginfo);
 }
 
+int
+netsnmp_unregister_table(netsnmp_handler_registration *reginfo)
+{
+    /* Locate "this" reginfo */
+    /* SNMP_FREE(reginfo->myvoid); */
+    /* reginfo->myvoid = NULL; */
+    return netsnmp_unregister_handler(reginfo);
+}
+
 /** Extracts the processed table information from a given request.
  *  Call this from subhandlers on a request to extract the processed
  *  netsnmp_request_info information.  The resulting information includes the
@@ -150,8 +162,8 @@
     int             oid_index_pos;
     unsigned int    oid_column_pos;
     unsigned int    tmp_idx;
-    size_t	    tmp_len;
-    int             incomplete, out_of_range, cleaned_up = 0;
+    int             tmp_len;
+    int             incomplete, out_of_range;
     int             status = SNMP_ERR_NOERROR, need_processing = 0;
     oid            *tmp_name;
     netsnmp_table_request_info *tbl_req_info;
@@ -211,15 +223,15 @@
          * a valid table info pointer).
          */
         if(NULL == netsnmp_extract_table_info(requests)) {
-            DEBUGMSGTL(("table:helper","no table info for set - skipping\n"));
+            DEBUGMSGTL(("helper:table","no table info for set - skipping\n"));
         }
         else
             need_processing = 1;
     }
     else {
         /*
-         * for RESERVE1 and GETS, only continue if we have at least
-         * one valid request.
+         * for GETS, only continue if we have at least one valid request.
+         * for RESERVE1, only continue if we have indexes for all requests.
          */
            
     /*
@@ -229,6 +241,7 @@
     for (request = requests; request; request = request->next) {
         netsnmp_variable_list *var = request->requestvb;
 
+        DEBUGMSGT(("verbose:table", "request for OID: "));
         DEBUGMSGOID(("verbose:table", var->name, var->name_length));
         DEBUGMSG(("verbose:table", "\n"));
 
@@ -260,7 +273,7 @@
                 DEBUGMSGOID(("helper:table:set", var->name, var->name_length));
                 out_len = 0;
                 if (sprint_realloc_by_type(&buf, &buf_len, &out_len, 1,
-                                           var, 0, 0, 0)) {
+                                           var, NULL, NULL, NULL)) {
                     DEBUGMSG(("helper:table:set"," type=%d(%02x), value=%s\n",
                               var->type, var->type, buf));
                 } else {
@@ -291,11 +304,11 @@
          * length) 
          */
         if (reginfo->rootoid_len > var->name_length)
-            tmp_len = var->name_length;
+            tmp_len = (int)var->name_length;
         else
-            tmp_len = reginfo->rootoid_len;
+            tmp_len = (int)reginfo->rootoid_len;
         if (snmp_oid_compare(reginfo->rootoid, reginfo->rootoid_len,
-                             var->name, tmp_len) > 0) {
+                             var->name, (size_t)tmp_len) > 0) {
             if (reqinfo->mode == MODE_GETNEXT) {
                 if (var->name != var->name_loc)
                     SNMP_FREE(var->name);
@@ -352,6 +365,11 @@
         tbl_req_info = netsnmp_extract_table_info(request);
         if (NULL == tbl_req_info) {
             tbl_req_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_request_info);
+            if (tbl_req_info == NULL) {
+                table_helper_cleanup(reqinfo, request,
+                                     SNMP_ERR_GENERR);
+                continue;
+            }
             tbl_req_info->reg_info = tbl_info;
             tbl_req_info->indexes = snmp_clone_varbind(tbl_info->indexes);
             tbl_req_info->number_indexes = 0;       /* none yet */
@@ -447,8 +465,8 @@
                  */
                 tbl_req_info->index_oid_len =
                     var->name_length - oid_index_pos;
-                DEBUGMSGTL(("helper:table", "    have %d bytes of index\n",
-                            tbl_req_info->index_oid_len));
+                DEBUGMSGTL(("helper:table", "    have %lu bytes of index\n",
+                            (unsigned long)tbl_req_info->index_oid_len));
                 netsnmp_assert(tbl_req_info->index_oid_len < MAX_OID_LEN);
                 memcpy(tbl_req_info->index_oid, &var->name[oid_index_pos],
                        tbl_req_info->index_oid_len * sizeof(oid));
@@ -489,7 +507,7 @@
             incomplete = 1;
             tmp_len = -1;
         } else
-            tmp_len = tbl_req_info->index_oid_len;
+            tmp_len = (int)tbl_req_info->index_oid_len;
 
 
         /*
@@ -512,13 +530,8 @@
                 /*
                  * no sense in trying anymore if this is a GET/SET. 
                  *
-                 * Reject requests of the form 'myObject'   (no instance)
+                 * FIXME: Reject requests of the form 'myObject'   (no instance)
                  */
-                if (reqinfo->mode != MODE_GETNEXT) {
-                    table_helper_cleanup(reqinfo, requests,
-                                         SNMP_NOSUCHINSTANCE);
-                    cleaned_up = 1;
-                }
                 tmp_len = 0;
                 tmp_name = (oid *) & tmp_len;
                 break;
@@ -526,7 +539,7 @@
             /*
              * try and parse current index 
              */
-            if (parse_one_oid_index(&tmp_name, &tmp_len,
+            if (parse_one_oid_index(&tmp_name, (size_t*)&tmp_len,
                                     vb, 1) != SNMPERR_SUCCESS) {
                 incomplete = 1;
                 tmp_len = -1;   /* is this necessary? Better safe than
@@ -549,12 +562,11 @@
         }                       /** for loop */
 
         DEBUGIF("helper:table:results") {
-            DEBUGMSGTL(("helper:table:results", "  found %d indexes\n",
-                        tbl_req_info->number_indexes));
-            if (!cleaned_up) {
                 unsigned int    count;
                 u_char         *buf = NULL;
                 size_t          buf_len = 0, out_len = 0;
+                DEBUGMSGTL(("helper:table:results", "  found %d indexes\n",
+                            tbl_req_info->number_indexes));
                 DEBUGMSGTL(("helper:table:results",
                             "  column: %d, indexes: %d",
                             tbl_req_info->colnum,
@@ -564,7 +576,7 @@
                      count++, vb = vb->next_variable) {
                     out_len = 0;
                     if (sprint_realloc_by_type(&buf, &buf_len, &out_len, 1,
-                                               vb, 0, 0, 0)) {
+                                               vb, NULL, NULL, NULL)) {
                         DEBUGMSG(("helper:table:results",
                                   "   index: type=%d(%02x), value=%s",
                                   vb->type, vb->type, buf));
@@ -584,19 +596,32 @@
                     free(buf);
                 }
                 DEBUGMSG(("helper:table:results", "\n"));
-            }
         }
 
 
         /*
-         * do we have sufficent index info to continue?
+         * do we have sufficient index info to continue?
          */
 
         if ((reqinfo->mode != MODE_GETNEXT) &&
             ((tbl_req_info->number_indexes != tbl_info->number_indexes) ||
              (tmp_len != -1))) {
+            
             DEBUGMSGTL(("helper:table",
                         "invalid index(es) for table - skipping\n"));
+
+            if ( MODE_IS_SET(reqinfo->mode) ) {
+                /*
+                 * no point in continuing without indexes for set.
+                 */
+                netsnmp_assert(reqinfo->mode == MODE_SET_RESERVE1);
+                /** clear first request so we wont try to run FREE mode */
+                netsnmp_free_request_data_sets(requests);
+                /** set actual error */
+                table_helper_cleanup(reqinfo, request, SNMP_ERR_NOCREATION);
+                need_processing = 0; /* don't call next handler */
+                break;
+            }
             table_helper_cleanup(reqinfo, request, SNMP_NOSUCHINSTANCE);
             continue;
         }
@@ -710,6 +735,17 @@
                      */
                     request->requestvb->type = ASN_NULL;
                 }
+
+#if 0
+            } else {
+                table_info = netsnmp_extract_table_info(request);
+                table_info->colnum = netsnmp_table_next_column(table_info);
+                if (table_info->colnum) {
+                    DEBUGMSGT(("sparse", "XXX next column would be: %d\n", table_info->colnum));
+                    //XXX request->processed = 1;     //FIXME all should OK, but it does't work! ck
+                }
+#endif
+
             }
         }
     }
@@ -733,10 +769,35 @@
 netsnmp_sparse_table_register(netsnmp_handler_registration *reginfo,
                        netsnmp_table_registration_info *tabreq)
 {
-    netsnmp_inject_handler(reginfo,
-        netsnmp_create_handler(SPARSE_TABLE_HANDLER_NAME,
-                               sparse_table_helper_handler));
-    netsnmp_inject_handler(reginfo, netsnmp_get_table_handler(tabreq));
+    netsnmp_mib_handler *handler1, *handler2;
+    int rc;
+
+    handler1 = netsnmp_create_handler(SPARSE_TABLE_HANDLER_NAME,
+                                     sparse_table_helper_handler);
+    if (NULL == handler1)
+        return SNMP_ERR_GENERR;
+
+    handler2 = netsnmp_get_table_handler(tabreq);
+    if (NULL == handler2 ) {
+        netsnmp_handler_free(handler1);
+        return SNMP_ERR_GENERR;
+    }
+
+    rc = netsnmp_inject_handler(reginfo, handler1);
+    if (SNMPERR_SUCCESS != rc) {
+        netsnmp_handler_free(handler1);
+        netsnmp_handler_free(handler2);
+        return rc;
+    }
+
+    rc = netsnmp_inject_handler(reginfo, handler2);
+    if (SNMPERR_SUCCESS != rc) {
+        /** handler1 is in reginfo... remove and free?? */
+        netsnmp_handler_free(handler2);
+        return rc;
+    }
+
+    /** both handlers now in reginfo, so nothing to do on error */
     return netsnmp_register_handler(reginfo);
 }
 
@@ -929,6 +990,26 @@
     return 0;
 }
 
+void
+netsnmp_table_registration_info_free(netsnmp_table_registration_info *tri)
+{
+    if (NULL == tri)
+        return;
+
+    if (NULL != tri->indexes)
+        snmp_free_varbind(tri->indexes);
+
+#if 0
+    /*
+     * sigh... example use of valid_columns points to static memory,
+     * so freeing it would be bad... we'll just have to live with any
+     * leaks, for now...
+     */
+#endif
+
+    free(tri);
+}
+
 /** @} */
 
 /*
@@ -1054,30 +1135,16 @@
  *
  */
 void
-#if HAVE_STDARG_H
 netsnmp_table_helper_add_indexes(netsnmp_table_registration_info *tinfo,
                                  ...)
-#else
-netsnmp_table_helper_add_indexes(va_alist)
-     va_dcl
-#endif
 {
     va_list         debugargs;
     int             type;
 
-#if HAVE_STDARG_H
     va_start(debugargs, tinfo);
-#else
-    netsnmp_table_registration_info *tinfo;
-
-    va_start(debugargs);
-    tinfo = va_arg(debugargs, netsnmp_table_registration_info *);
-#endif
-
     while ((type = va_arg(debugargs, int)) != 0) {
         netsnmp_table_helper_add_index(tinfo, type);
     }
-
     va_end(debugargs);
 }
 
@@ -1096,7 +1163,7 @@
 {
     netsnmp_oid_stash_node **stashp = NULL;
     stashp = (netsnmp_oid_stash_node **)
-        netsnmp_agent_get_list_data(reqinfo, storage_name);
+        netsnmp_agent_get_list_data(reqinfo, (const char *) storage_name);
 
     if (!stashp) {
         /*
@@ -1108,7 +1175,7 @@
             return NULL;        /* ack. out of mem */
 
         netsnmp_agent_add_list_data(reqinfo,
-                                    netsnmp_create_data_list(storage_name,
+                                    netsnmp_create_data_list((const char *) storage_name,
                                                              stashp,
                                                              _row_stash_data_list_free));
     }

=== modified file 'agent/helpers/table_data.c'
--- agent/helpers/table_data.c	2010-10-23 08:33:56 +0000
+++ agent/helpers/table_data.c	2010-10-24 00:31:41 +0000
@@ -81,17 +81,16 @@
     if (row->indexes) {
         newrow->indexes = snmp_clone_varbind(newrow->indexes);
         if (!newrow->indexes) {
-            free (newrow);
+            free(newrow);
             return NULL;
         }
     }
 
     if (row->index_oid) {
-        memdup((u_char **) & newrow->index_oid,
-               (u_char *) row->index_oid,
-               row->index_oid_len * sizeof(oid));
+        newrow->index_oid =
+            snmp_duplicate_objid(row->index_oid, row->index_oid_len);
         if (!newrow->index_oid) {
-            free (newrow);
+            free(newrow);
             return NULL;
         }
     }
@@ -341,9 +340,8 @@
     if (old_row->indexes)
         new_row->indexes = snmp_clone_varbind(old_row->indexes);
     if (old_row->index_oid)
-        memdup((u_char **) & new_row->index_oid,
-               (u_char *)    old_row->index_oid,
-               old_row->index_oid_len * sizeof(oid));
+        new_row->index_oid =
+            snmp_duplicate_objid(old_row->index_oid, old_row->index_oid_len);
     /* XXX - Doesn't copy table-specific row structure */
     return 0;
 }
@@ -414,6 +412,13 @@
     return netsnmp_register_table_data(reginfo, table, table_info);
 }
 
+int
+netsnmp_unregister_table_data(netsnmp_handler_registration *reginfo)
+{
+    /* free table; */
+    return netsnmp_unregister_table(reginfo);
+}
+
 /*
  * The helper handler that takes care of passing a specific row of
  * data down to the lower handler(s).  It sets request->processed if

=== modified file 'agent/helpers/table_dataset.c'
--- agent/helpers/table_dataset.c	2010-10-23 08:33:56 +0000
+++ agent/helpers/table_dataset.c	2010-10-24 16:39:11 +0000
@@ -508,7 +508,7 @@
                 continue;
             }
             stashp = (netsnmp_oid_stash_node **)
-                netsnmp_table_get_or_create_row_stash(reqinfo, buf);
+                netsnmp_table_get_or_create_row_stash(reqinfo, (u_char *) buf);
 
             newrowstash
                 = netsnmp_oid_stash_get_data(*stashp, suffix, suffix_len);
@@ -581,6 +581,10 @@
                                                 data->type,
                                                 data->data.voidp,
                                                 data->data_len);
+            else {  // FIXME: This is a BUG at least for 5.4.3, it seems we need this! ck
+                DEBUGMSGTL(("table_set_add_table", "set request error=NOSUCHINSTANCE\n"));
+                netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
+            }
             break;
 
         case MODE_SET_RESERVE1:
@@ -686,7 +690,7 @@
              * modify row and set new value 
              */
             SNMP_FREE(data->data.string);
-            data->data.string =
+            data->data.string = (u_char *)
                 netsnmp_strdup_and_null(request->requestvb->val.string,
                                         request->requestvb->val_len);
             if (!data->data.string) {
@@ -1254,7 +1258,7 @@
 
         SNMP_FREE(data->data.voidp);
         if (value_len) {
-            if (memdup(&data->data.string, value, (value_len)) !=
+            if (memdup(&data->data.string, (u_char *) value, (value_len)) !=
                 SNMPERR_SUCCESS) {
                 snmp_log(LOG_CRIT, "no memory in netsnmp_set_row_column");
                 return SNMPERR_MALLOC;

=== modified file 'agent/mibgroup/notification-log-mib/notification_log.c'
--- agent/mibgroup/notification-log-mib/notification_log.c	2010-10-23 08:33:56 +0000
+++ agent/mibgroup/notification-log-mib/notification_log.c	2010-10-25 11:14:20 +0000
@@ -217,7 +217,8 @@
                 "adding index nlmLogVariableIndex of type ASN_UNSIGNED to table nlmLogVariableTable\n"));
     netsnmp_table_dataset_add_index(table_set, ASN_UNSIGNED);
 
-    /*
+#if 0
+    /* FIXME https://sourceforge.net/tracker/?func=detail&atid=112694&aid=1840230&group_id=12694 This is a BUG! ck
      * adding column nlmLogVariableIndex of type ASN_UNSIGNED and access
      * of NoAccess 
      */
@@ -226,6 +227,8 @@
     netsnmp_table_set_add_default_row(table_set,
                                       COLUMN_NLMLOGVARIABLEINDEX,
                                       ASN_UNSIGNED, 0, NULL, 0);
+#endif
+
     /*
      * adding column nlmLogVariableID of type ASN_OBJECT_ID and access of
      * ReadOnly 
@@ -585,6 +588,7 @@
     u_long          vbcount = 0;
     u_long          tmpul;
     int             col;
+    int             trap_type_found = 0;  /* true if nlmLogNotificationID was found as varbindings (not for v1 trap)! ck */
 
     if (!nlmLogVarTable
         || netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
@@ -612,13 +616,15 @@
     gettimeofday(&now, NULL);
     tmpl = netsnmp_timeval_uptime(&now);
     netsnmp_set_row_column(row, COLUMN_NLMLOGTIME, ASN_TIMETICKS,
-                           (u_char *) & tmpl, sizeof(tmpl));
+                           (char *) & tmpl, sizeof(tmpl));
     time(&timetnow);
     logdate = date_n_time(&timetnow, &logdate_size);
     netsnmp_set_row_column(row, COLUMN_NLMLOGDATEANDTIME, ASN_OCTET_STR,
-                           logdate, logdate_size);
+                           (char *)logdate, logdate_size);
+
+#if 1   // FIXME: may be not needed at master agent! ck
     netsnmp_set_row_column(row, COLUMN_NLMLOGENGINEID, ASN_OCTET_STR,
-                           pdu->securityEngineID,
+                           (char *)pdu->securityEngineID,
                            pdu->securityEngineIDLen);
     if (transport && transport->domain == netsnmpUDPDomain) {
         /*
@@ -643,21 +649,26 @@
     if (transport)
         netsnmp_set_row_column(row, COLUMN_NLMLOGENGINETDOMAIN,
                                      ASN_OBJECT_ID,
-                                     (const u_char *) transport->domain,
+                                     (const char *) transport->domain,
                                      sizeof(oid) * transport->domain_length);
     netsnmp_set_row_column(row, COLUMN_NLMLOGCONTEXTENGINEID,
-                           ASN_OCTET_STR, pdu->contextEngineID,
+                           ASN_OCTET_STR, (char *)pdu->contextEngineID,
                            pdu->contextEngineIDLen);
     netsnmp_set_row_column(row, COLUMN_NLMLOGCONTEXTNAME, ASN_OCTET_STR,
                            pdu->contextName, pdu->contextNameLen);
+#endif
 
     for (vptr = pdu->variables; vptr; vptr = vptr->next_variable) {
         if (snmp_oid_compare(snmptrapoid, snmptrapoid_len,
                              vptr->name, vptr->name_length) == 0) {
+            //FIXME: this is only true for v2/v3 trap pdu!
+            //BUG at all versions of net-snmp including v5.6! ck
+            DEBUGMSGTL(("notification_log",
+                        "adding the nlmLogNotificationID to the table\n"));
             netsnmp_set_row_column(row, COLUMN_NLMLOGNOTIFICATIONID,
-                                   ASN_OBJECT_ID, vptr->val.string,
+                                   ASN_OBJECT_ID, (char *)vptr->val.string,
                                    vptr->val_len);
-
+            trap_type_found=1;    // found, OK
         } else {
             netsnmp_table_row *myrow;
             myrow = netsnmp_create_table_data_row();
@@ -677,7 +688,7 @@
              * OID 
              */
             netsnmp_set_row_column(myrow, COLUMN_NLMLOGVARIABLEID,
-                                   ASN_OBJECT_ID, (u_char *) vptr->name,
+                                   ASN_OBJECT_ID, (char *) vptr->name,
                                    vptr->name_length * sizeof(oid));
 
             /*
@@ -739,16 +750,36 @@
                 continue;
             }
             netsnmp_set_row_column(myrow, COLUMN_NLMLOGVARIABLEVALUETYPE,
-                                   ASN_INTEGER, (u_char *) & tmpul,
+                                   ASN_INTEGER, (char *) & tmpul,
                                    sizeof(tmpul));
             netsnmp_set_row_column(myrow, col, vptr->type,
-                                   vptr->val.string, vptr->val_len);
+                                   (char *)vptr->val.string, vptr->val_len);
             DEBUGMSGTL(("notification_log",
                         "adding a row to the variables table\n"));
             netsnmp_table_dataset_add_row(nlmLogVarTable, myrow);
         }
     }
 
+    if (!trap_type_found) {
+        //XXX We should reuse constants from "agent/agent_trap.c"
+        static const oid    cold_start_oid[] = {1,3,6,1,6,3,1,1,5,1};
+        static const size_t cold_start_oid_len = OID_LENGTH(cold_start_oid);
+        oid                 enterprise[MAX_OID_LEN];
+
+        DEBUGMSGTL(("notification_log",
+                    "adding the v1 trap_type %d as nlmLogNotificationID to the table\n",
+                    pdu->trap_type));
+
+        {   /***XXX check this: SNMPv2-MIB::coldStart calulation XXX***/
+            memcpy(enterprise, cold_start_oid, cold_start_oid_len * sizeof(oid));
+            enterprise[cold_start_oid_len - 1]  = pdu->trap_type + 1;   //FIXME magic v1trap! ck
+
+            netsnmp_set_row_column(row, COLUMN_NLMLOGNOTIFICATIONID,
+                                   ASN_OBJECT_ID, (char *)enterprise,
+                                   cold_start_oid_len * sizeof(oid));
+        }
+    }
+
     /*
      * store the row 
      */

=== modified file 'agent/mibgroup/notification/snmpNotifyFilterProfileTable.c'
--- agent/mibgroup/notification/snmpNotifyFilterProfileTable.c	2010-10-23 08:33:56 +0000
+++ agent/mibgroup/notification/snmpNotifyFilterProfileTable.c	2010-10-23 12:04:53 +0000
@@ -401,7 +401,7 @@
          */
         tmpvar = StorageTmp->snmpNotifyFilterProfileName;
         tmplen = StorageTmp->snmpNotifyFilterProfileNameLen;
-        StorageTmp->snmpNotifyFilterProfileName = calloc(1, var_val_len + 1);
+        StorageTmp->snmpNotifyFilterProfileName = (char*)calloc(1, var_val_len + 1);
         if (NULL == StorageTmp->snmpNotifyFilterProfileName)
             return SNMP_ERR_RESOURCEUNAVAILABLE;
         break;
@@ -648,6 +648,8 @@
 
             StorageNew =
                 SNMP_MALLOC_STRUCT(snmpNotifyFilterProfileTable_data);
+            if (StorageNew == NULL)
+                return SNMP_ERR_GENERR;
             memdup((u_char **) & (StorageNew->snmpTargetParamsName),
                    vars->val.string, vars->val_len);
             StorageNew->snmpTargetParamsNameLen = vars->val_len;
@@ -802,7 +804,7 @@
      * put requested info into var structure 
      */
     snmp_varlist_add_variable(&vars, NULL, 0, ASN_PRIV_IMPLIED_OCTET_STR,
-                              (u_char *) paramName, paramName_len);
+                              (const u_char *) paramName, paramName_len);
 
     /*
      * get the data from the header_complex storage 

=== modified file 'agent/mibgroup/notification/snmpNotifyTable.c'
--- agent/mibgroup/notification/snmpNotifyTable.c	2010-10-23 08:33:56 +0000
+++ agent/mibgroup/notification/snmpNotifyTable.c	2010-10-23 12:01:09 +0000
@@ -101,8 +101,8 @@
     size_t                 profileNameLen;
     struct vacm_viewEntry *vp, *head;
     int                    vb_oid_excluded = 0;
-    extern oid             snmptrap_oid[];
-    extern size_t          snmptrap_oid_len;
+    extern const oid       snmptrap_oid[];
+    extern const size_t    snmptrap_oid_len;
 
     netsnmp_assert(NULL != paramName);
     netsnmp_assert(NULL != pdu);
@@ -210,7 +210,7 @@
     netsnmp_pdu    *template_pdu = (netsnmp_pdu *) serverarg;
     int             count = 0, send = 0;
 
-    DEBUGMSGTL(("send_notifications", "starting: pdu=%x, vars=%x\n",
+    DEBUGMSGTL(("send_notifications", "starting: pdu=%p, vars=%p\n",
                 template_pdu, template_pdu->variables));
 
     for (hptr = snmpNotifyTableStorage; hptr; hptr = hptr->next) {
@@ -338,6 +338,8 @@
         pptr->secModel = ss->securityModel;
         pptr->secLevel = ss->securityLevel;
         pptr->secName = (char *) malloc(ss->securityNameLen + 1);
+        if (pptr->secName == NULL)
+            return 0;
         memcpy((void *) pptr->secName, (void *) ss->securityName,
                ss->securityNameLen);
         pptr->secName[ss->securityNameLen] = 0;
@@ -353,6 +355,8 @@
         pptr->secName = NULL;
         if (ss->community && (ss->community_len > 0)) {
             pptr->secName = (char *) malloc(ss->community_len + 1);
+            if (pptr->secName == NULL)
+                return 0;
             memcpy((void *) pptr->secName, (void *) ss->community,
                    ss->community_len);
             pptr->secName[ss->community_len] = 0;
@@ -370,6 +374,8 @@
      * notify table 
      */
     nptr = SNMP_MALLOC_STRUCT(snmpNotifyTable_data);
+    if (nptr == NULL)
+        return 0;
     nptr->snmpNotifyName = strdup(buf);
     nptr->snmpNotifyNameLen = strlen(buf);
     nptr->snmpNotifyTag = strdup(buf);
@@ -442,9 +448,13 @@
     snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA,
                            store_snmpNotifyTable, NULL);
 
+#ifndef NETSNMP_DISABLE_SNMPV1
+    // FIXME: why should we do that without v1? ck
     snmp_register_callback(SNMP_CALLBACK_APPLICATION,
                            SNMPD_CALLBACK_SEND_TRAP1, send_notifications,
                            NULL);
+#endif
+
     snmp_register_callback(SNMP_CALLBACK_APPLICATION,
                            SNMPD_CALLBACK_SEND_TRAP2, send_notifications,
                            NULL);
@@ -538,12 +548,14 @@
     line =
         read_config_read_data(ASN_INTEGER, line,
                               &StorageTmp->snmpNotifyStorageType, &tmpint);
+    if (!StorageTmp->snmpNotifyStorageType)
+        StorageTmp->snmpNotifyStorageType = ST_READONLY;
 
     line =
         read_config_read_data(ASN_INTEGER, line,
                               &StorageTmp->snmpNotifyRowStatus, &tmpint);
-
-
+    if (!StorageTmp->snmpNotifyRowStatus)
+        StorageTmp->snmpNotifyRowStatus = RS_ACTIVE;
 
 
     snmpNotifyTable_add(StorageTmp);
@@ -749,10 +761,10 @@
         if (var_val_type != ASN_OCTET_STR) {
             return SNMP_ERR_WRONGTYPE;
         }
-        if (var_val_len < 0 || var_val_len > 255) {
+        if (var_val_len > 255) {
             return SNMP_ERR_WRONGLENGTH;
         }
-        if (!snmpTagValid(var_val, var_val_len)) {
+        if (!snmpTagValid((char *) var_val, var_val_len)) {
             return SNMP_ERR_WRONGVALUE;
         }
         break;
@@ -764,7 +776,7 @@
          */
         tmpvar = StorageTmp->snmpNotifyTag;
         tmplen = StorageTmp->snmpNotifyTagLen;
-        StorageTmp->snmpNotifyTag = calloc(1, var_val_len + 1);
+        StorageTmp->snmpNotifyTag = (char*)calloc(1, var_val_len + 1);
         if (NULL == StorageTmp->snmpNotifyTag)
             return SNMP_ERR_RESOURCEUNAVAILABLE;
         break;
@@ -1020,7 +1032,7 @@
             if (StorageNew == NULL) {
                 return SNMP_ERR_RESOURCEUNAVAILABLE;
             }
-            StorageNew->snmpNotifyName = calloc( 1, vp->val_len + 1 );
+            StorageNew->snmpNotifyName = (char*)calloc( 1, vp->val_len + 1 );
             if (StorageNew->snmpNotifyName == NULL) {
                 return SNMP_ERR_RESOURCEUNAVAILABLE;
             }

=== modified file 'include/net-snmp/agent/agent_trap.h'
--- include/net-snmp/agent/agent_trap.h	2010-10-23 08:33:56 +0000
+++ include/net-snmp/agent/agent_trap.h	2010-10-23 12:39:39 +0000
@@ -14,16 +14,20 @@
 void            send_easy_trap(int, int);
 void            send_trap_pdu(netsnmp_pdu *);
 void            send_v2trap(netsnmp_variable_list *);
+void            send_v3trap(netsnmp_variable_list *vars, const char *context);
 void            send_trap_vars(int, int, netsnmp_variable_list *);
+void            send_trap_vars_with_context(int trap, int specific, 
+                                            netsnmp_variable_list *vars,
+                                            const char *context);
 void            send_enterprise_trap_vars(int trap, int specific,
-                                          oid * enterprise,
+                                          const oid * enterprise,
                                           int enterprise_length,
                                           netsnmp_variable_list * vars);
 int             netsnmp_send_traps(int trap, int specific,
-                          oid * enterprise, int enterprise_length,
+                          const oid * enterprise, int enterprise_length,
                           netsnmp_variable_list * vars,
-                          /* These next two are currently unused */
-                          char * context, int flags);
+                          /* flags are currently unused */
+                          const char * context, int flags);
 void            snmpd_parse_config_authtrap(const char *, char *);
 void            snmpd_parse_config_trapsink(const char *, char *);
 void            snmpd_parse_config_trap2sink(const char *, char *);

=== modified file 'include/net-snmp/library/snmp_client.h'
--- include/net-snmp/library/snmp_client.h	2010-10-23 08:33:56 +0000
+++ include/net-snmp/library/snmp_client.h	2010-10-23 13:29:37 +0000
@@ -71,7 +71,7 @@
     netsnmp_variable_list *find_varbind_of_type(netsnmp_variable_list *
                                                 var_ptr, u_char type);
     netsnmp_variable_list *find_varbind_in_list(netsnmp_variable_list *vblist,
-                                                oid *name, size_t len);
+                                                const oid *name, size_t len);
 
     netsnmp_variable_list *snmp_add_null_var(netsnmp_pdu *, const oid *, size_t);
     netsnmp_pdu    *snmp_pdu_create(int);

=== modified file 'snmplib/snmp_client.c'
--- snmplib/snmp_client.c	2010-10-23 08:33:56 +0000
+++ snmplib/snmp_client.c	2010-10-23 13:28:58 +0000
@@ -735,7 +735,7 @@
 
 netsnmp_variable_list*
 find_varbind_in_list( netsnmp_variable_list *vblist,
-                      oid *name, size_t len)
+                      const oid *name, size_t len)
 {
     for (; vblist != NULL; vblist = vblist->next_variable)
         if (!snmp_oid_compare(vblist->name, vblist->name_length, name, len))

