aboutsummaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-extended
diff options
context:
space:
mode:
authorOtavio Salvador <otavio@ossystems.com.br>2012-02-08 15:27:28 +0000
committerKoen Kooi <koen@dominion.thruhere.net>2012-02-20 22:22:02 +0100
commit675da0c58afe0926f9e614acb49b9e6c5d30d413 (patch)
treee4ebd31422a44c335e664796783ecea35f61a393 /meta-oe/recipes-extended
parent6f371fa946d094c1b03d98692383aac803ae2fe0 (diff)
downloadmeta-openembedded-675da0c58afe0926f9e614acb49b9e6c5d30d413.tar.gz
net-snmp: sync with 5.7 maintainence branch
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
Diffstat (limited to 'meta-oe/recipes-extended')
-rw-r--r--meta-oe/recipes-extended/net-snmp/files/sync-with-5.7-branch.patch19998
-rw-r--r--meta-oe/recipes-extended/net-snmp/net-snmp_5.7.1.bb3
2 files changed, 20000 insertions, 1 deletions
diff --git a/meta-oe/recipes-extended/net-snmp/files/sync-with-5.7-branch.patch b/meta-oe/recipes-extended/net-snmp/files/sync-with-5.7-branch.patch
new file mode 100644
index 0000000000..442e8d0cd1
--- /dev/null
+++ b/meta-oe/recipes-extended/net-snmp/files/sync-with-5.7-branch.patch
@@ -0,0 +1,19998 @@
+Sync with 5.7 branch
+
+This syncs v5.7.1 to 2012-02-08 5.7 GIT branch status
+
+Upstream-Status: Backport
+
+diff --git a/.gitignore b/.gitignore
+index 9d6a15f..9cfb7a3 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -1,9 +1,9 @@
+ *.bak
+ *.bs
+-*.la
+-*.lo
+ *.ft
+ *.ft.1
++*.la
++*.lo
+ *.made
+ *.o
+ *.obj
+@@ -78,7 +78,10 @@ net-snmp-config
+ net-snmp-config-x
+ net-snmp-create-v3-user
+ NEWS.new*
++perl/*.yml
+ perl/*/*.def
++perl/*/*.yml
++perl/*/*/*.yml
+ perl/agent/agent.c
+ perl/agent/default_store/default_store.c
+ perl/agent/default_store/default_store.def
+@@ -96,6 +99,7 @@ perl/TrapReceiver/const-c.inc
+ perl/TrapReceiver/const-xs.inc
+ perl/TrapReceiver/TrapReceiver.c
+ pm_to_blib
++python/build
+ sedscript
+ snmplib/snmpsm_init.h
+ snmplib/snmpsm_shutdown.h
+diff --git a/COPYING b/COPYING
+index afe6e6d..d368331 100644
+--- a/COPYING
++++ b/COPYING
+@@ -135,7 +135,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ ---- Part 5: Sparta, Inc copyright notice (BSD) -----
+
+-Copyright (c) 2003-2011, Sparta, Inc
++Copyright (c) 2003-2012, Sparta, Inc
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+diff --git a/Makefile.in b/Makefile.in
+index f3dd7b7..9664676 100644
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -85,22 +85,23 @@ libtool: $(LIBTOOL_DEPS)
+ $(SHELL) ./config.status --recheck
+
+
+-snmplib:
++snmplib: @FEATURETARGS@
+ @(cd snmplib; $(MAKE) )
+
+-agent:
++agent: @FEATURETARGS@
+ @(cd snmplib; $(MAKE) )
+ @(cd agent; $(MAKE) )
+
+-apps:
++apps: @FEATURETARGS@
+ @(cd snmplib; $(MAKE) )
++ @(cd agent; $(MAKE) libs)
+ @(cd apps; $(MAKE) )
+
+-snmpget snmpbulkget snmpwalk snmpbulkwalk snmptranslate snmpstatus snmpdelta snmptable snmptest snmpset snmpusm snmpvacm snmpgetnext encode_keychange snmpdf snmptrap snmptls:
++snmpget snmpbulkget snmpwalk snmpbulkwalk snmptranslate snmpstatus snmpdelta snmptable snmptest snmpset snmpusm snmpvacm snmpgetnext encode_keychange snmpdf snmptrap snmptls: @FEATURETARGS@
+ @(cd snmplib; $(MAKE) )
+ @(cd apps; $(MAKE) $@ )
+
+-snmptrapd:
++agentxtrap snmptrapd: @FEATURETARGS@
+ @(cd snmplib; $(MAKE) )
+ @(cd agent; $(MAKE) libs)
+ @(cd apps; $(MAKE) $@ )
+diff --git a/agent/Makefile.in b/agent/Makefile.in
+index 84a5e4c..59cf4ef 100644
+--- a/agent/Makefile.in
++++ b/agent/Makefile.in
+@@ -114,7 +114,6 @@ USELIBS = ../snmplib/libnetsnmp.$(LIB_EXTENSION)$(LIB_VERSION)
+ AGENTLIB = libnetsnmpagent.$(LIB_EXTENSION)$(LIB_VERSION)
+ MIBLIB = libnetsnmpmibs.$(LIB_EXTENSION)$(LIB_VERSION)
+
+-LOCAL_LIBS = -L../snmplib/.libs -L../snmplib -L./.libs
+ LAGENTLIBS = @LAGENTLIBS@
+ LMIBLIBS = @LMIBLIBS@
+ VAL_LIBS = @VAL_LIBS@
+@@ -282,34 +281,33 @@ all: agentlib subdirs miblib $(INSTALLBINPROGS) $(INSTALLSBINPROGS)
+ # build stuff targets
+ #
+ getkstat: getkstat.o
+- $(CC) $(CFLAGS) -o $@ $? $(LOCAL_LIBS) $(LIBS)
++ $(CC) $(CFLAGS) -o $@ $? $(LIBS)
+
+ getkstat.o: mibgroup/kernel_sunos5.c
+ $(CC) $(CFLAGS) -o $@ -D_GETKSTAT_TEST -DDODEBUG -c $?
+
+ getmibstat: getmibstat.o
+- $(CC) $(CFLAGS) -o $@ $? $(LOCAL_LIBS) $(LIBS)
++ $(CC) $(CFLAGS) -o $@ $? $(LIBS)
+
+ getmibstat.o: mibgroup/kernel_sunos5.c
+ $(CC) $(CFLAGS) -o $@ -D_GETMIBSTAT_TEST -DDODEBUG -c $?
+
+-snmpd$(EXEEXT): ${LAGENTOBJS} $(USELIBS) $(AGENTLIB) $(MIBLIB) $(LIBTARG)
+- $(LINK) $(CFLAGS) -o $@ ${LAGENTOBJS} $(LOCAL_LIBS) ${LDFLAGS} ${OUR_AGENT_LIBS}
+-
++snmpd$(EXEEXT): ${LAGENTOBJS} $(USELIBS) $(AGENTLIB) $(HELPERLIB) $(MIBLIB) $(LIBTARG)
++ $(LINK) $(CFLAGS) -o $@ ${LAGENTOBJS} ${LDFLAGS} ${OUR_AGENT_LIBS}
+
+ libnetsnmpagent.$(LIB_EXTENSION)$(LIB_VERSION): ${LLIBAGENTOBJS} $(USELIBS)
+ $(LIB_LD_CMD) $(AGENTLIB) ${LLIBAGENTOBJS} $(USELIBS) ${LAGENTLIBS} @LD_NO_UNDEFINED@ $(LDFLAGS) $(PERLLDOPTS_FOR_LIBS) $(LIB_LD_LIBS) @AGENTLIBS@
+ $(RANLIB) $(AGENTLIB)
+
+ libnetsnmpmibs.$(LIB_EXTENSION)$(LIB_VERSION): ${LMIBOBJS} $(AGENTLIB) $(USELIBS)
+- $(LIB_LD_CMD) $(MIBLIB) ${LMIBOBJS} $(AGENTLIB) $(USELIBS) @LD_NO_UNDEFINED@ $(LDFLAGS) ${LMIBLIBS} $(LIB_LD_LIBS) @AGENTLIBS@
++ $(LIB_LD_CMD) $(MIBLIB) ${LMIBOBJS} $(AGENTLIB) $(USELIBS) @LD_NO_UNDEFINED@ $(LDFLAGS) ${LMIBLIBS} $(PERLLDOPTS_FOR_LIBS) $(LIB_LD_LIBS) @AGENTLIBS@
+ $(RANLIB) $(MIBLIB)
+
+ agentlib: $(AGENTLIB)
+
+ miblib: $(MIBLIB)
+
+-libs: $(INSTALLLIBS)
++libs: $(AGENTLIB) $(MIBLIB)
+
+ embedperlinstall:
+ @$(SHELL) $(srcdir)/../mkinstalldirs $(INSTALL_PREFIX)$(snmplibdir)
+diff --git a/agent/agent_handler.c b/agent/agent_handler.c
+index da64761..59e9613 100644
+--- a/agent/agent_handler.c
++++ b/agent/agent_handler.c
+@@ -774,7 +774,7 @@ netsnmp_handler_registration_free(netsnmp_handler_registration *reginfo)
+ /** Duplicates handler registration object and all subsequent handlers.
+ * Creates a copy of the handler registration object and all its data.
+ *
+- * @param handler is the handler registration object to be duplicated
++ * @param reginfo is the handler registration object to be duplicated
+ *
+ * @return Returns a pointer to the complete copy,
+ * or NULL if any problem occured.
+@@ -922,7 +922,8 @@ netsnmp_free_delegated_cache(netsnmp_delegated_cache *dcache)
+ * Sweeps through given chain of requests and sets 'delegated'
+ * flag accordingly to the isdelegaded parameter.
+ *
+- * @param isdelegaded New value of the 'delegated' flag.
++ * @param requests Request list.
++ * @param isdelegated New value of the 'delegated' flag.
+ */
+ void
+ netsnmp_handler_mark_requests_as_delegated(netsnmp_request_info *requests,
+diff --git a/agent/agent_read_config.c b/agent/agent_read_config.c
+index 3514f0f..f9ef1af 100644
+--- a/agent/agent_read_config.c
++++ b/agent/agent_read_config.c
+@@ -115,13 +115,10 @@ netsnmp_feature_child_of(snmpd_unregister_config_handler, agent_read_config_all)
+ void
+ snmpd_set_agent_user(const char *token, char *cptr)
+ {
+-#if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H)
+- struct passwd *info;
+-#endif
+-
+ if (cptr[0] == '#') {
+ char *ecp;
+ int uid;
++
+ uid = strtoul(cptr + 1, &ecp, 10);
+ if (*ecp != 0) {
+ config_perror("Bad number");
+@@ -129,44 +126,47 @@ snmpd_set_agent_user(const char *token, char *cptr)
+ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_USERID, uid);
+ }
+- }
+ #if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H)
+- else if ((info = getpwnam(cptr)) != NULL) {
+- netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+- NETSNMP_DS_AGENT_USERID, info->pw_uid);
+ } else {
+- config_perror("User not found in passwd database");
+- }
+- endpwent();
++ struct passwd *info;
++
++ info = getpwnam(cptr);
++ if (info)
++ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
++ NETSNMP_DS_AGENT_USERID, info->pw_uid);
++ else
++ config_perror("User not found in passwd database");
++ endpwent();
+ #endif
++ }
+ }
+
+ void
+ snmpd_set_agent_group(const char *token, char *cptr)
+ {
+-#if defined(HAVE_GETGRNAM) && defined(HAVE_GRP_H)
+- struct group *info;
+-#endif
+-
+ if (cptr[0] == '#') {
+ char *ecp;
+ int gid = strtoul(cptr + 1, &ecp, 10);
++
+ if (*ecp != 0) {
+ config_perror("Bad number");
+ } else {
+ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_GROUPID, gid);
+ }
+- }
+ #if defined(HAVE_GETGRNAM) && defined(HAVE_GRP_H)
+- else if ((info = getgrnam(cptr)) != NULL) {
+- netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+- NETSNMP_DS_AGENT_GROUPID, info->gr_gid);
+ } else {
+- config_perror("Group not found in group database");
+- }
+- endpwent();
++ struct group *info;
++
++ info = getgrnam(cptr);
++ if (info)
++ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
++ NETSNMP_DS_AGENT_GROUPID, info->gr_gid);
++ else
++ config_perror("Group not found in group database");
++ endgrent();
+ #endif
++ }
+ }
+ #endif
+
+@@ -187,9 +187,10 @@ snmpd_set_agent_address(const char *token, char *cptr)
+ /*
+ * append to the older specification string
+ */
+- snprintf(buf, SPRINT_MAX_LEN, "%s,%s", ptr, cptr);
++ snprintf(buf, sizeof(buf), "%s,%s", ptr, cptr);
++ buf[sizeof(buf) - 1] = '\0';
+ } else {
+- strncpy(buf, cptr, SPRINT_MAX_LEN);
++ strlcpy(buf, cptr, sizeof(buf));
+ }
+
+ DEBUGMSGTL(("snmpd_ports", "port spec: %s\n", buf));
+diff --git a/agent/agent_registry.c b/agent/agent_registry.c
+index 5efaeb5..1e2482a 100644
+--- a/agent/agent_registry.c
++++ b/agent/agent_registry.c
+@@ -555,6 +555,8 @@ netsnmp_subtree_change_prev(netsnmp_subtree *ptr, netsnmp_subtree *theprev)
+ &ptr->oid_off);
+ }
+
++netsnmp_feature_child_of(netsnmp_subtree_compare,netsnmp_unused)
++#ifndef NETSNMP_FEATURE_REMOVE_NETSNMP_SUBTREE_COMPARE
+ /** Compares OIDs of given subtrees.
+ *
+ * @param ap,bp Pointers to the subtrees to be compared.
+@@ -563,8 +565,6 @@ netsnmp_subtree_change_prev(netsnmp_subtree *ptr, netsnmp_subtree *theprev)
+ *
+ * @see snmp_oid_compare()
+ */
+-netsnmp_feature_child_of(netsnmp_subtree_compare,netsnmp_unused)
+-#ifndef NETSNMP_FEATURE_REMOVE_NETSNMP_SUBTREE_COMPARE
+ int
+ netsnmp_subtree_compare(const netsnmp_subtree *ap, const netsnmp_subtree *bp)
+ {
+@@ -742,7 +742,7 @@ netsnmp_subtree_split(netsnmp_subtree *current, oid name[], int name_len)
+
+ /** Loads the subtree under given context name.
+ *
+- * @param root The subtree to be loaded into current subtree.
++ * @param new_sub The subtree to be loaded into current subtree.
+ *
+ * @param context_name Text name of the context we're searching for.
+ *
+@@ -1085,8 +1085,22 @@ netsnmp_subtree_find(const oid *name, size_t len, netsnmp_subtree *subtree,
+
+ /** Registers a MIB handler.
+ *
++ * @param moduleName
++ * @param var
++ * @param varsize
++ * @param numvars
++ * @param mibloc
++ * @param mibloclen
++ * @param priority
++ * @param range_subid
++ * @param range_ubound
++ * @param ss
++ * @param context
++ * @param timeout
++ * @param flags
+ * @param reginfo Registration handler structure.
+ * In a case of failure, it will be freed.
++ * @param perform_callback
+ *
+ * @return gives MIB_REGISTERED_OK or MIB_* error code.
+ *
+@@ -1389,6 +1403,7 @@ register_mib_detach(void)
+ * If range_subid is zero, then this parameter is ignored.
+ *
+ * @param ss
++ * @param context
+ * @param timeout
+ * @param flags
+ *
+@@ -1584,6 +1599,7 @@ netsnmp_subtree_unload(netsnmp_subtree *sub, netsnmp_subtree *prev, const char *
+ DEBUGMSGOID(("register_mib", sub->start_a, sub->start_len));
+ } else {
+ DEBUGMSG(("register_mib", "[NIL]"));
++ return;
+ }
+ DEBUGMSG(("register_mib", ", "));
+ if (prev != NULL) {
+@@ -1664,7 +1680,7 @@ unregister_mib_context(oid * name, size_t len, int priority,
+ int range_subid, oid range_ubound,
+ const char *context)
+ {
+- netsnmp_subtree *list, *myptr;
++ netsnmp_subtree *list, *myptr = NULL;
+ netsnmp_subtree *prev, *child, *next; /* loop through children */
+ struct register_parameters reg_parms;
+ int old_lookup_cache_val = netsnmp_get_lookup_cache_size();
+diff --git a/agent/agent_trap.c b/agent/agent_trap.c
+index cc90620..dfa9dcf 100644
+--- a/agent/agent_trap.c
++++ b/agent/agent_trap.c
+@@ -801,6 +801,7 @@ netsnmp_send_traps(int trap, int specific,
+
+ }
+
++ if (template_v2pdu) {
+ /* A context name was provided, so copy it and its length to the v2 pdu
+ * template. */
+ if (context != NULL)
+@@ -808,6 +809,7 @@ netsnmp_send_traps(int trap, int specific,
+ template_v2pdu->contextName = strdup(context);
+ template_v2pdu->contextNameLen = strlen(context);
+ }
++ }
+
+ /*
+ * Now loop through the list of trap sinks
+diff --git a/agent/auto_nlist.c b/agent/auto_nlist.c
+index cb92a5b..bcbdb05 100644
+--- a/agent/auto_nlist.c
++++ b/agent/auto_nlist.c
+@@ -52,6 +52,9 @@ auto_nlist_value(const char *string)
+ }
+ }
+ if (*ptr == 0) {
++#if !(defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7))
++ static char *n_name = NULL;
++#endif
+ *ptr = (struct autonlist *) malloc(sizeof(struct autonlist));
+ it = *ptr;
+ it->left = 0;
+@@ -66,15 +69,35 @@ auto_nlist_value(const char *string)
+ strcpy(it->nl[0].n_name, string);
+ it->nl[0].n_name[strlen(string)+1] = '\0';
+ #else
+- sprintf(it->nl[0].n_name, "_%s", string);
++
++ if (n_name != NULL)
++ free(n_name);
++
++ n_name = malloc(strlen(string) + 2);
++ if (n_name == NULL) {
++ snmp_log(LOG_ERR, "nlist err: failed to allocate memory");
++ return (-1);
++ }
++ snprintf(n_name, strlen(string) + 2, "_%s", string);
++ it->nl[0].n_name = (const char*)n_name;
+ #endif
+ it->nl[1].n_name = 0;
+ init_nlist(it->nl);
+ #if !(defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7) || \
+- defined(netbsd1) || defined(dragonfly))
++ defined(netbsd1) || defined(dragonfly))
+ if (it->nl[0].n_type == 0) {
+- strcpy(it->nl[0].n_name, string);
+- it->nl[0].n_name[strlen(string)+1] = '\0';
++ static char *n_name2 = NULL;
++
++ if (n_name2 != NULL)
++ free(n_name2);
++
++ n_name2 = malloc(strlen(string) + 1);
++ if (n_name2 == NULL) {
++ snmp_log(LOG_ERR, "nlist err: failed to allocate memory");
++ return (-1);
++ }
++ strcpy(n_name2, string);
++ it->nl[0].n_name = (const char*)n_name2;
+ init_nlist(it->nl);
+ }
+ #endif
+@@ -86,7 +109,8 @@ auto_nlist_value(const char *string)
+ }
+ return (-1);
+ } else {
+- DEBUGMSGTL(("auto_nlist:auto_nlist_value", "found symbol %s at %x.\n",
++ DEBUGMSGTL(("auto_nlist:auto_nlist_value",
++ "found symbol %s at %lx.\n",
+ it->symbol, it->nl[0].n_value));
+ return (it->nl[0].n_value);
+ }
+@@ -95,7 +119,7 @@ auto_nlist_value(const char *string)
+ }
+
+ int
+-auto_nlist(const char *string, char *var, int size)
++auto_nlist(const char *string, char *var, size_t size)
+ {
+ long result;
+ int ret;
+@@ -192,7 +216,7 @@ init_nlist(struct nlist nl[])
+ }
+
+ int
+-KNLookup(struct nlist nl[], int nl_which, char *buf, int s)
++KNLookup(struct nlist nl[], int nl_which, char *buf, size_t s)
+ {
+ struct nlist *nlp = &nl[nl_which];
+
+diff --git a/agent/helpers/all_helpers.c b/agent/helpers/all_helpers.c
+index 0f2b6a1..e1e1b78 100644
+--- a/agent/helpers/all_helpers.c
++++ b/agent/helpers/all_helpers.c
+@@ -26,7 +26,7 @@ netsnmp_init_helpers(void)
+ netsnmp_init_bulk_to_next_helper();
+ #ifndef NETSNMP_FEATURE_REMOVE_TABLE_DATASET
+ netsnmp_init_table_dataset();
+-#endif
++#endif /* NETSNMP_FEATURE_REMOVE_TABLE_DATASET */
+
+ #ifndef NETSNMP_FEATURE_REMOVE_ROW_MERGE
+ netsnmp_init_row_merge();
+diff --git a/agent/helpers/instance.c b/agent/helpers/instance.c
+index 2142909..a187d58 100644
+--- a/agent/helpers/instance.c
++++ b/agent/helpers/instance.c
+@@ -536,6 +536,8 @@ netsnmp_register_num_file_instance(const char *name,
+ }
+ #endif /* NETSNMP_FEATURE_REMOVE_REGISTER_NUM_FILE_INSTANCE */
+
++netsnmp_feature_child_of(register_int_instance,instance)
++#ifndef NETSNMP_FEATURE_REMOVE_REGISTER_INT_INSTANCE
+ /**
+ * This function registers an int helper handler to a specified OID.
+ *
+@@ -554,8 +556,6 @@ netsnmp_register_num_file_instance(const char *name,
+ * MIB_REGISTERED_OK is returned if the registration was a success.
+ * Failures are MIB_REGISTRATION_FAILED and MIB_DUPLICATE_REGISTRATION.
+ */
+-netsnmp_feature_child_of(register_int_instance,instance)
+-#ifndef NETSNMP_FEATURE_REMOVE_REGISTER_INT_INSTANCE
+ int
+ netsnmp_register_int_instance(const char *name,
+ const oid * reg_oid, size_t reg_oid_len,
+diff --git a/agent/helpers/old_api.c b/agent/helpers/old_api.c
+index b1630e6..4888cbc 100644
+--- a/agent/helpers/old_api.c
++++ b/agent/helpers/old_api.c
+@@ -103,8 +103,12 @@ netsnmp_register_old_api(const char *moduleName,
+ reginfo->rootoid_len = (mibloclen + vp->namelen);
+ reginfo->rootoid =
+ (oid *) malloc(reginfo->rootoid_len * sizeof(oid));
+- if (reginfo->rootoid == NULL)
++ if (reginfo->rootoid == NULL) {
++ SNMP_FREE(vp);
++ SNMP_FREE(reginfo->handlerName);
++ SNMP_FREE(reginfo);
+ return SNMP_ERR_GENERR;
++ }
+
+ memcpy(reginfo->rootoid, mibloc, mibloclen * sizeof(oid));
+ memcpy(reginfo->rootoid + mibloclen, vp->name, vp->namelen
+@@ -127,7 +131,7 @@ netsnmp_register_old_api(const char *moduleName,
+ */
+ if (netsnmp_register_handler(reginfo) != MIB_REGISTERED_OK) {
+ /** netsnmp_handler_registration_free(reginfo); already freed */
+- SNMP_FREE(vp);
++ /* SNMP_FREE(vp); already freed */
+ }
+ }
+ return SNMPERR_SUCCESS;
+diff --git a/agent/helpers/snmp_get_statistic.c b/agent/helpers/snmp_get_statistic.c
+index 2e4fed8..efac2ac 100644
+--- a/agent/helpers/snmp_get_statistic.c
++++ b/agent/helpers/snmp_get_statistic.c
+@@ -58,4 +58,4 @@ netsnmp_register_statistic_handler(netsnmp_handler_registration *reginfo,
+ }
+ #else /* !NETSNMP_FEATURE_REMOVE_HELPER_GET_STATISTICS */
+ netsnmp_feature_unused(helper_statistics);
+-#endif
++#endif /* !NETSNMP_FEATURE_REMOVE_HELPER_GET_STATISTICS */
+diff --git a/agent/helpers/table_array.c b/agent/helpers/table_array.c
+index 49e0b24..7c98aae 100644
+--- a/agent/helpers/table_array.c
++++ b/agent/helpers/table_array.c
+@@ -576,8 +576,11 @@ group_requests(netsnmp_agent_request_info *agtreq_info,
+ DEBUGMSG(("table_array:group", "\n"));
+ g = SNMP_MALLOC_TYPEDEF(netsnmp_request_group);
+ i = SNMP_MALLOC_TYPEDEF(netsnmp_request_group_item);
+- if (i == NULL || g == NULL)
++ if (i == NULL || g == NULL) {
++ SNMP_FREE(i);
++ SNMP_FREE(g);
+ return;
++ }
+ g->list = i;
+ g->table = tad->table;
+ i->ri = current;
+diff --git a/agent/helpers/table_dataset.c b/agent/helpers/table_dataset.c
+index 5160748..0949a8a 100644
+--- a/agent/helpers/table_dataset.c
++++ b/agent/helpers/table_dataset.c
+@@ -467,7 +467,7 @@ netsnmp_register_table_data_set(netsnmp_handler_registration *reginfo,
+ netsnmp_get_table_data_set_handler(data_set));
+ ret = netsnmp_register_table_data(reginfo, data_set->table,
+ table_info);
+- if (reginfo->handler)
++ if (ret == SNMPERR_SUCCESS && reginfo->handler)
+ netsnmp_handler_owns_table_info(reginfo->handler->next);
+ return ret;
+ }
+@@ -1105,9 +1105,11 @@ netsnmp_config_parse_table_set(const char *token, char *line)
+ switch (tp->access) {
+ case MIB_ACCESS_CREATE:
+ table_set->allow_creation = 1;
++ /* fallthrough */
+ case MIB_ACCESS_READWRITE:
+ case MIB_ACCESS_WRITEONLY:
+ canwrite = 1;
++ /* fallthrough */
+ case MIB_ACCESS_READONLY:
+ DEBUGMSGTL(("table_set_add_table",
+ "adding column %ld of type %d\n", tp->subid, type));
+diff --git a/agent/helpers/table_iterator.c b/agent/helpers/table_iterator.c
+index 64ef2cb..8ed5cd0 100644
+--- a/agent/helpers/table_iterator.c
++++ b/agent/helpers/table_iterator.c
+@@ -648,6 +648,8 @@ netsnmp_table_iterator_helper_handler(netsnmp_mib_handler *handler,
+ */
+ if (free_this_index_search)
+ snmp_free_varbind(free_this_index_search);
++ netsnmp_free_request_data_sets(reqtmp);
++ SNMP_FREE(reqtmp);
+ return SNMP_ERR_GENERR;
+ }
+ coloid[reginfo->rootoid_len + 1] = table_info->colnum;
+@@ -681,6 +683,8 @@ netsnmp_table_iterator_helper_handler(netsnmp_mib_handler *handler,
+ if (free_this_index_search)
+ snmp_free_varbind
+ (free_this_index_search);
++ netsnmp_free_request_data_sets(reqtmp);
++ SNMP_FREE(reqtmp);
+ return SNMP_ERR_GENERR;
+ }
+ request_count--; /* One less to look for */
+diff --git a/agent/helpers/watcher.c b/agent/helpers/watcher.c
+index ee80736..9b3933b 100644
+--- a/agent/helpers/watcher.c
++++ b/agent/helpers/watcher.c
+@@ -245,14 +245,11 @@ netsnmp_watcher_helper_handler(netsnmp_mib_handler *handler,
+ netsnmp_watcher_cache *old_data;
+
+ DEBUGMSGTL(("helper:watcher", "Got request: %d\n", reqinfo->mode));
+-
+ DEBUGMSGTL(( "helper:watcher", " oid:"));
+ DEBUGMSGOID(("helper:watcher", requests->requestvb->name,
+ requests->requestvb->name_length));
+ DEBUGMSG(( "helper:watcher", "\n"));
+
+-
+-
+ switch (reqinfo->mode) {
+ /*
+ * data requests
+@@ -392,14 +389,11 @@ netsnmp_watched_timestamp_handler(netsnmp_mib_handler *handler,
+
+ DEBUGMSGTL(("helper:watcher:timestamp",
+ "Got request: %d\n", reqinfo->mode));
+-
+ DEBUGMSGTL(( "helper:watcher:timestamp", " oid:"));
+ DEBUGMSGOID(("helper:watcher:timestamp", requests->requestvb->name,
+ requests->requestvb->name_length));
+ DEBUGMSG(( "helper:watcher:timestamp", "\n"));
+
+-
+-
+ switch (reqinfo->mode) {
+ /*
+ * data requests
+@@ -481,14 +475,11 @@ netsnmp_watched_spinlock_handler(netsnmp_mib_handler *handler,
+
+ DEBUGMSGTL(("helper:watcher:spinlock",
+ "Got request: %d\n", reqinfo->mode));
+-
+ DEBUGMSGTL(( "helper:watcher:spinlock", " oid:"));
+ DEBUGMSGOID(("helper:watcher:spinlock", requests->requestvb->name,
+ requests->requestvb->name_length));
+ DEBUGMSG(( "helper:watcher:spinlock", "\n"));
+
+-
+-
+ switch (reqinfo->mode) {
+ /*
+ * Ensure the assigned value matches the current one
+diff --git a/agent/mibgroup/Rmon/agutil.c b/agent/mibgroup/Rmon/agutil.c
+index d28bb67..12c6342 100644
+--- a/agent/mibgroup/Rmon/agutil.c
++++ b/agent/mibgroup/Rmon/agutil.c
+@@ -200,12 +200,7 @@ AGUTIL_get_oid_value(u_char * var_val, u_char var_val_type,
+ u_long
+ AGUTIL_sys_up_time(void)
+ {
+- struct timeval current, delta;
+- const struct timeval* const starttime_ptr = netsnmp_get_agent_starttime();
+-
+- gettimeofday(&current, NULL);
+- NETSNMP_TIMERSUB(&current, starttime_ptr, &delta);
+- return delta.tv_sec * 100 + delta.tv_usec / 10000;
++ return netsnmp_get_agent_runtime();
+ }
+
+ /*
+diff --git a/agent/mibgroup/Rmon/event.c b/agent/mibgroup/Rmon/event.c
+index 008ebaa..04a8555 100644
+--- a/agent/mibgroup/Rmon/event.c
++++ b/agent/mibgroup/Rmon/event.c
+@@ -128,6 +128,7 @@ typedef struct {
+
+ static TABLE_DEFINTION_T EventCtrlTable;
+ static TABLE_DEFINTION_T *table_ptr = &EventCtrlTable;
++static unsigned char zero_octet_string[1];
+
+ /*
+ * Control Table RowApi Callbacks
+@@ -262,7 +263,6 @@ write_eventControl(int action, u_char * var_val, u_char var_val_type,
+ static int prev_action = COMMIT;
+ RMON_ENTRY_T *hdr;
+ CRTL_ENTRY_T *cloned_body;
+- CRTL_ENTRY_T *body;
+
+ switch (action) {
+ case RESERVE1:
+@@ -283,7 +283,6 @@ write_eventControl(int action, u_char * var_val, u_char var_val_type,
+ leaf_id = (int) name[eventEntryFirstIndexBegin - 1];
+ hdr = ROWAPI_find(table_ptr, long_temp); /* it MUST be OK */
+ cloned_body = (CRTL_ENTRY_T *) hdr->tmp;
+- body = (CRTL_ENTRY_T *) hdr->body;
+ switch (leaf_id) {
+ case Leaf_event_description:
+ char_temp = AGMALLOC(1 + MAX_event_description);
+@@ -406,7 +405,7 @@ var_eventTable(struct variable *vp,
+ return (unsigned char *) theEntry.event_description;
+ } else {
+ *var_len = 0;
+- return NETSNMP_REMOVE_CONST(unsigned char *, "");
++ return zero_octet_string;
+ }
+ case EVENTTYPE:
+ long_ret = theEntry.event_type;
+@@ -417,7 +416,7 @@ var_eventTable(struct variable *vp,
+ return (unsigned char *) theEntry.event_community;
+ } else {
+ *var_len = 0;
+- return NETSNMP_REMOVE_CONST(unsigned char *, "");
++ return zero_octet_string;
+ }
+ case EVENTLASTTIMESENT:
+ long_ret = theEntry.event_last_time_sent;
+@@ -428,7 +427,7 @@ var_eventTable(struct variable *vp,
+ return (unsigned char *) hdr->owner;
+ } else {
+ *var_len = 0;
+- return NETSNMP_REMOVE_CONST(unsigned char *, "");
++ return zero_octet_string;
+ }
+ case EVENTSTATUS:
+ long_ret = hdr->status;
+@@ -457,7 +456,6 @@ var_logTable(struct variable *vp,
+ static long long_ret;
+ static DATA_ENTRY_T theEntry;
+ RMON_ENTRY_T *hdr;
+- CRTL_ENTRY_T *ctrl;
+
+ *write_method = NULL;
+ hdr = ROWDATAAPI_header_DataEntry(vp, name, length, exact, var_len,
+@@ -467,8 +465,6 @@ var_logTable(struct variable *vp,
+ if (!hdr)
+ return NULL;
+
+- ctrl = (CRTL_ENTRY_T *) hdr->body;
+-
+ *var_len = sizeof(long); /* default */
+
+ switch (vp->magic) {
+@@ -487,7 +483,7 @@ var_logTable(struct variable *vp,
+ return (unsigned char *) theEntry.log_description;
+ } else {
+ *var_len = 0;
+- return NETSNMP_REMOVE_CONST(unsigned char *, "");
++ return zero_octet_string;
+ }
+ default:
+ ERROR_MSG("");
+diff --git a/agent/mibgroup/Rmon/history.c b/agent/mibgroup/Rmon/history.c
+index b962567..c8e9c25 100644
+--- a/agent/mibgroup/Rmon/history.c
++++ b/agent/mibgroup/Rmon/history.c
+@@ -181,7 +181,7 @@ write_historyControl(int action, u_char * var_val, u_char var_val_type,
+ var_val_len,
+ MIN_historyControlBucketsRequested,
+ MAX_historyControlBucketsRequested,
+- &cloned_body->scrlr.
++ (long *) &cloned_body->scrlr.
+ data_requested);
+ if (SNMP_ERR_NOERROR != snmp_status) {
+ return snmp_status;
+@@ -198,7 +198,7 @@ write_historyControl(int action, u_char * var_val, u_char var_val_type,
+ var_val_len,
+ MIN_historyControlInterval,
+ MAX_historyControlInterval,
+- &cloned_body->interval);
++ (long *) &cloned_body->interval);
+ if (SNMP_ERR_NOERROR != snmp_status) {
+ return snmp_status;
+ }
+@@ -257,6 +257,7 @@ var_historyControlTable(struct variable *vp,
+ int exact,
+ size_t * var_len, WriteMethod ** write_method)
+ {
++ static unsigned char zero_octet_string[1];
+ static long long_ret;
+ static CRTL_ENTRY_T theEntry;
+ RMON_ENTRY_T *hdr;
+@@ -298,7 +299,7 @@ var_historyControlTable(struct variable *vp,
+ return (unsigned char *) hdr->owner;
+ } else {
+ *var_len = 0;
+- return NETSNMP_REMOVE_CONST(unsigned char *, "");
++ return zero_octet_string;
+ }
+
+ case CTRL_STATUS:
+@@ -530,7 +531,6 @@ var_etherHistoryTable(struct variable *vp,
+ static long long_ret;
+ static DATA_ENTRY_T theBucket;
+ RMON_ENTRY_T *hdr;
+- CRTL_ENTRY_T *ctrl;
+
+ *write_method = NULL;
+ hdr = ROWDATAAPI_header_DataEntry(vp, name, length, exact, var_len,
+@@ -542,8 +542,6 @@ var_etherHistoryTable(struct variable *vp,
+
+ *var_len = sizeof(long); /* default */
+
+- ctrl = (CRTL_ENTRY_T *) hdr->body;
+-
+ switch (vp->magic) {
+ case DATA_INDEX:
+ long_ret = hdr->ctrl_index;
+diff --git a/agent/mibgroup/Rmon/row_api.h b/agent/mibgroup/Rmon/row_api.h
+index 2fb5a88..9f576be 100644
+--- a/agent/mibgroup/Rmon/row_api.h
++++ b/agent/mibgroup/Rmon/row_api.h
+@@ -62,7 +62,7 @@ typedef struct tagEntry {
+ typedef int (ENTRY_CALLBACK_T) (RMON_ENTRY_T *);
+
+ typedef struct {
+- char *name;
++ const char *name;
+ RMON_ENTRY_T *first;
+ u_long max_number_of_entries; /* '<0' means without limit */
+ u_long current_number_of_entries;
+diff --git a/agent/mibgroup/Rmon/statistics.c b/agent/mibgroup/Rmon/statistics.c
+index 51f25ee..3ed4acb 100644
+--- a/agent/mibgroup/Rmon/statistics.c
++++ b/agent/mibgroup/Rmon/statistics.c
+@@ -317,6 +317,7 @@ var_etherStatsEntry(struct variable * vp, oid * name, size_t * length,
+ int exact, size_t * var_len,
+ WriteMethod ** write_method)
+ {
++ static unsigned char zero_octet_string[1];
+ static long long_return;
+ static CRTL_ENTRY_T theEntry;
+ RMON_ENTRY_T *hdr;
+@@ -397,7 +398,7 @@ var_etherStatsEntry(struct variable * vp, oid * name, size_t * length,
+ return (unsigned char *) hdr->owner;
+ } else {
+ *var_len = 0;
+- return NETSNMP_REMOVE_CONST(unsigned char *, "");
++ return zero_octet_string;
+ }
+ case IDetherStatsStatus:
+ long_return = hdr->status;
+diff --git a/agent/mibgroup/agent/extend.c b/agent/mibgroup/agent/extend.c
+index ddef4fb..8268559 100644
+--- a/agent/mibgroup/agent/extend.c
++++ b/agent/mibgroup/agent/extend.c
+@@ -120,7 +120,8 @@ _register_extend( oid *base, size_t len )
+ netsnmp_table_data *dinfo;
+ netsnmp_table_registration_info *tinfo;
+ netsnmp_watcher_info *winfo;
+- netsnmp_handler_registration *reg;
++ netsnmp_handler_registration *reg = NULL;
++ int rc;
+
+ for ( eptr=ereg_head; eptr; eptr=eptr->next ) {
+ if (!snmp_oid_compare( base, len, eptr->root_oid, eptr->oid_len))
+@@ -128,6 +129,8 @@ _register_extend( oid *base, size_t len )
+ }
+ if (!eptr) {
+ eptr = SNMP_MALLOC_TYPEDEF( extend_registration_block );
++ if (!eptr)
++ return NULL;
+ eptr->root_oid = snmp_duplicate_objid( base, len );
+ eptr->oid_len = len;
+ eptr->num_entries = 0;
+@@ -157,7 +160,10 @@ _register_extend( oid *base, size_t len )
+ "nsExtendConfigTable", handle_nsExtendConfigTable,
+ oid_buf, len+1, HANDLER_CAN_RONLY);
+ #endif /* !NETSNMP_NO_WRITE_SUPPORT */
+- netsnmp_register_table_data( reg, dinfo, tinfo );
++ rc = netsnmp_register_table_data( reg, dinfo, tinfo );
++ if (rc != SNMPERR_SUCCESS) {
++ goto bail;
++ }
+ netsnmp_handler_owns_table_info(reg->handler->next);
+ eptr->reg[0] = reg;
+
+@@ -175,7 +181,9 @@ _register_extend( oid *base, size_t len )
+ reg = netsnmp_create_handler_registration(
+ "nsExtendOut1Table", handle_nsExtendOutput1Table,
+ oid_buf, len+1, HANDLER_CAN_RONLY);
+- netsnmp_register_table_data( reg, dinfo, tinfo );
++ rc = netsnmp_register_table_data( reg, dinfo, tinfo );
++ if (rc != SNMPERR_SUCCESS)
++ goto bail;
+ netsnmp_handler_owns_table_info(reg->handler->next);
+ eptr->reg[1] = reg;
+
+@@ -195,7 +203,9 @@ _register_extend( oid *base, size_t len )
+ reg = netsnmp_create_handler_registration(
+ "nsExtendOut2Table", handle_nsExtendOutput2Table,
+ oid_buf, len+1, HANDLER_CAN_RONLY);
+- netsnmp_register_table( reg, tinfo );
++ rc = netsnmp_register_table( reg, tinfo );
++ if (rc != SNMPERR_SUCCESS)
++ goto bail;
+ netsnmp_handler_owns_table_info(reg->handler->next);
+ eptr->reg[2] = reg;
+
+@@ -209,9 +219,20 @@ _register_extend( oid *base, size_t len )
+ winfo = netsnmp_create_watcher_info(
+ &(eptr->num_entries), sizeof(eptr->num_entries),
+ ASN_INTEGER, WATCHER_FIXED_SIZE);
+- netsnmp_register_watched_scalar2( reg, winfo );
++ rc = netsnmp_register_watched_scalar2( reg, winfo );
++ if (rc != SNMPERR_SUCCESS)
++ goto bail;
+
+ return eptr;
++
++bail:
++ if (eptr->reg[2])
++ netsnmp_unregister_handler(eptr->reg[2]);
++ if (eptr->reg[1])
++ netsnmp_unregister_handler(eptr->reg[1]);
++ if (eptr->reg[0])
++ netsnmp_unregister_handler(eptr->reg[0]);
++ return NULL;
+ }
+
+ static void
+@@ -406,9 +427,9 @@ _free_extension( netsnmp_extend *extension, extend_registration_block *ereg )
+ eprev->next = eptr->next;
+ else
+ ereg->ehead = eptr->next;
++ netsnmp_table_data_remove_and_delete_row( ereg->dinfo, extension->row);
+ }
+
+- netsnmp_table_data_remove_and_delete_row( ereg->dinfo, extension->row);
+ SNMP_FREE( extension->token );
+ SNMP_FREE( extension->cache );
+ SNMP_FREE( extension->command );
+diff --git a/agent/mibgroup/agent/nsDebug.c b/agent/mibgroup/agent/nsDebug.c
+index 0a629cc..89a90b0 100644
+--- a/agent/mibgroup/agent/nsDebug.c
++++ b/agent/mibgroup/agent/nsDebug.c
+@@ -423,8 +423,9 @@ handle_nsDebugTable(netsnmp_mib_handler *handler,
+ */
+ debug_entry = (netsnmp_token_descr*)
+ netsnmp_extract_iterator_context(request);
+- debug_entry->enabled =
+- (*request->requestvb->val.integer == RS_ACTIVE);
++ if (debug_entry)
++ debug_entry->enabled =
++ (*request->requestvb->val.integer == RS_ACTIVE);
+ break;
+
+ case RS_CREATEANDWAIT:
+diff --git a/agent/mibgroup/agent/nsLogging.c b/agent/mibgroup/agent/nsLogging.c
+index c06a18a..7f20bdb 100644
+--- a/agent/mibgroup/agent/nsLogging.c
++++ b/agent/mibgroup/agent/nsLogging.c
+@@ -363,7 +363,7 @@ handle_nsLoggingTable(netsnmp_mib_handler *handler,
+ switch ( *request->requestvb->val.integer ) {
+ case RS_ACTIVE:
+ case RS_CREATEANDGO:
+- if ( !logh->type ) {
++ if ( !logh || !logh->type ) {
+ netsnmp_set_request_error(reqinfo, request,
+ SNMP_ERR_INCONSISTENTVALUE);
+ return SNMP_ERR_INCONSISTENTVALUE;
+diff --git a/agent/mibgroup/agent/nsVacmAccessTable.c b/agent/mibgroup/agent/nsVacmAccessTable.c
+index 22d2154..79fa97d 100644
+--- a/agent/mibgroup/agent/nsVacmAccessTable.c
++++ b/agent/mibgroup/agent/nsVacmAccessTable.c
+@@ -174,11 +174,11 @@ nsVacmAccessTable_handler(netsnmp_mib_handler *handler,
+ /* Extract the authType token from the list of indexes */
+ idx = table_info->indexes->next_variable->next_variable->next_variable->next_variable;
+ memset(atype, 0, sizeof(atype));
+- strncpy(atype, (char *)idx->val.string, idx->val_len);
++ memcpy(atype, (char *)idx->val.string, idx->val_len);
+ viewIdx = se_find_value_in_slist(VACM_VIEW_ENUM_NAME, atype);
+ DEBUGMSGTL(("nsVacm", "GET %s (%d)\n", idx->val.string, viewIdx));
+
+- if (!entry)
++ if (!entry || viewIdx < 0)
+ continue;
+
+ switch (table_info->colnum) {
+@@ -248,7 +248,7 @@ nsVacmAccessTable_handler(netsnmp_mib_handler *handler,
+ */
+ idx = table_info->indexes->next_variable->next_variable->next_variable->next_variable;
+ memset(atype, 0, sizeof(atype));
+- strncpy(atype, (char *)idx->val.string, idx->val_len);
++ memcpy(atype, (char *)idx->val.string, idx->val_len);
+ viewIdx = se_find_value_in_slist(VACM_VIEW_ENUM_NAME, atype);
+ if ( viewIdx < 0 ) {
+ ret = SNMP_ERR_NOCREATION;
+@@ -322,8 +322,10 @@ nsVacmAccessTable_handler(netsnmp_mib_handler *handler,
+ /* Extract the authType token from the list of indexes */
+ idx = table_info->indexes->next_variable->next_variable->next_variable->next_variable;
+ memset(atype, 0, sizeof(atype));
+- strncpy(atype, (char *)idx->val.string, idx->val_len);
++ memcpy(atype, (char *)idx->val.string, idx->val_len);
+ viewIdx = se_find_value_in_slist(VACM_VIEW_ENUM_NAME, atype);
++ if (viewIdx < 0)
++ continue;
+
+ switch (table_info->colnum) {
+ case COLUMN_NSVACMCONTEXTMATCH:
+diff --git a/agent/mibgroup/agentx/agentx_config.c b/agent/mibgroup/agentx/agentx_config.c
+index b590c7a..ea453c2 100644
+--- a/agent/mibgroup/agentx/agentx_config.c
++++ b/agent/mibgroup/agentx/agentx_config.c
+@@ -180,10 +180,8 @@ agentx_config_init(void)
+ */
+ netsnmp_register_default_domain("agentx", "unix tcp");
+ netsnmp_register_default_target("agentx", "unix", NETSNMP_AGENTX_SOCKET);
+-#define val(x) __STRING(x)
+ netsnmp_register_default_target("agentx", "tcp",
+- "localhost:" val(AGENTX_PORT));
+-#undef val
++ "localhost:" __STRING(AGENTX_PORT));
+ agentx_register_config_handler("agentxsocket",
+ agentx_parse_agentx_socket, NULL,
+ "AgentX bind address");
+diff --git a/agent/mibgroup/agentx/master_admin.c b/agent/mibgroup/agentx/master_admin.c
+index 3f4b33d..f16f392 100644
+--- a/agent/mibgroup/agentx/master_admin.c
++++ b/agent/mibgroup/agentx/master_admin.c
+@@ -64,7 +64,6 @@ int
+ open_agentx_session(netsnmp_session * session, netsnmp_pdu *pdu)
+ {
+ netsnmp_session *sp;
+- struct timeval now;
+
+ DEBUGMSGTL(("agentx/master", "open %8p\n", session));
+ sp = (netsnmp_session *) malloc(sizeof(netsnmp_session));
+@@ -104,8 +103,7 @@ open_agentx_session(netsnmp_session * session, netsnmp_pdu *pdu)
+ name_length);
+ sp->securityAuthProtoLen = pdu->variables->name_length;
+ sp->securityName = strdup((char *) pdu->variables->val.string);
+- gettimeofday(&now, NULL);
+- sp->engineTime = calculate_sectime_diff(&now, netsnmp_get_agent_starttime());
++ sp->engineTime = (netsnmp_get_agent_runtime() + 50) / 100;
+
+ sp->subsession = session; /* link back to head */
+ sp->flags |= SNMP_FLAGS_SUBSESSION;
+diff --git a/agent/mibgroup/agentx/protocol.c b/agent/mibgroup/agentx/protocol.c
+index 09c149f..6e3daf3 100644
+--- a/agent/mibgroup/agentx/protocol.c
++++ b/agent/mibgroup/agentx/protocol.c
+@@ -453,6 +453,7 @@ agentx_realloc_build_varbind(u_char ** buf, size_t * buf_len,
+ case ASN_COUNTER:
+ case ASN_GAUGE:
+ case ASN_TIMETICKS:
++ case ASN_UINTEGER:
+ if (!agentx_realloc_build_int(buf, buf_len, out_len, allow_realloc,
+ *(vp->val.integer), network_order)) {
+ DEBUGINDENTLESS();
+@@ -1372,6 +1373,7 @@ agentx_parse_varbind(u_char * data, size_t * length, int *type,
+ case ASN_COUNTER:
+ case ASN_GAUGE:
+ case ASN_TIMETICKS:
++ case ASN_UINTEGER:
+ int_val = agentx_parse_int(bufp, network_byte_order);
+ memmove(data_buf, &int_val, 4);
+ *data_len = 4;
+@@ -1429,6 +1431,7 @@ agentx_parse_varbind(u_char * data, size_t * length, int *type,
+ break;
+
+ default:
++ DEBUGMSG(("recv", "Can not parse type %x", *type));
+ DEBUGINDENTLESS();
+ return NULL;
+ }
+diff --git a/agent/mibgroup/agentx/subagent.c b/agent/mibgroup/agentx/subagent.c
+index 5d51834..76b1acf 100644
+--- a/agent/mibgroup/agentx/subagent.c
++++ b/agent/mibgroup/agentx/subagent.c
+@@ -243,6 +243,24 @@ free_set_vars(netsnmp_session * ss, netsnmp_pdu *pdu)
+ }
+ #endif /* !NETSNMP_NO_WRITE_SUPPORT */
+
++static void
++send_agentx_error(netsnmp_session *session, netsnmp_pdu *pdu, int errstat, int errindex)
++{
++ pdu = snmp_clone_pdu(pdu);
++ pdu->command = AGENTX_MSG_RESPONSE;
++ pdu->version = session->version;
++ pdu->errstat = errstat;
++ pdu->errindex = errindex;
++ snmp_free_varbind(pdu->variables);
++ pdu->variables = NULL;
++
++ DEBUGMSGTL(("agentx/subagent", "Sending AgentX response error stat %d idx %d\n",
++ errstat, errindex));
++ if (!snmp_send(session, pdu)) {
++ snmp_free_pdu(pdu);
++ }
++}
++
+ int
+ handle_agentx_packet(int operation, netsnmp_session * session, int reqid,
+ netsnmp_pdu *pdu, void *magic)
+@@ -298,8 +316,10 @@ handle_agentx_packet(int operation, netsnmp_session * session, int reqid,
+ * agentx_reopen_session unregisters itself if it succeeds in talking
+ * to the master agent.
+ */
+- snmp_alarm_register(period, SA_REPEAT, agentx_reopen_session,
+- NULL);
++ snmp_alarm_register(period, SA_REPEAT, agentx_reopen_session, NULL);
++ snmp_log(LOG_INFO, "AgentX master disconnected us, reconnecting in %d\n", period);
++ } else {
++ snmp_log(LOG_INFO, "AgentX master disconnected us, not reconnecting\n");
+ }
+ return 0;
+ } else if (operation != NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE) {
+@@ -325,6 +345,7 @@ handle_agentx_packet(int operation, netsnmp_session * session, int reqid,
+ (ns_subagent_magic *) calloc(1, sizeof(ns_subagent_magic));
+ if (smagic == NULL) {
+ DEBUGMSGTL(("agentx/subagent", "couldn't malloc() smagic\n"));
++ /* would like to send_agentx_error(), but it needs memory too */
+ return 1;
+ }
+ smagic->original_command = pdu->command;
+@@ -389,6 +410,7 @@ handle_agentx_packet(int operation, netsnmp_session * session, int reqid,
+ if (asi == NULL) {
+ SNMP_FREE(smagic);
+ snmp_log(LOG_WARNING, "save_set_vars() failed\n");
++ send_agentx_error(session, pdu, AGENTX_ERR_PARSE_FAILED, 0);
+ return 1;
+ }
+ asi->mode = pdu->command = SNMP_MSG_INTERNAL_SET_RESERVE1;
+@@ -402,6 +424,7 @@ handle_agentx_packet(int operation, netsnmp_session * session, int reqid,
+ if (asi == NULL) {
+ SNMP_FREE(smagic);
+ snmp_log(LOG_WARNING, "restore_set_vars() failed\n");
++ send_agentx_error(session, pdu, AGENTX_ERR_PROCESSING_ERROR, 0);
+ return 1;
+ }
+ if (asi->mode != SNMP_MSG_INTERNAL_SET_RESERVE2) {
+@@ -409,6 +432,7 @@ handle_agentx_packet(int operation, netsnmp_session * session, int reqid,
+ snmp_log(LOG_WARNING,
+ "dropping bad AgentX request (wrong mode %d)\n",
+ asi->mode);
++ send_agentx_error(session, pdu, AGENTX_ERR_PROCESSING_ERROR, 0);
+ return 1;
+ }
+ asi->mode = pdu->command = SNMP_MSG_INTERNAL_SET_ACTION;
+@@ -422,6 +446,7 @@ handle_agentx_packet(int operation, netsnmp_session * session, int reqid,
+ if (asi == NULL) {
+ SNMP_FREE(smagic);
+ snmp_log(LOG_WARNING, "restore_set_vars() failed\n");
++ send_agentx_error(session, pdu, AGENTX_ERR_PROCESSING_ERROR, 0);
+ return 1;
+ }
+ if (asi->mode == SNMP_MSG_INTERNAL_SET_RESERVE1 ||
+@@ -446,6 +471,7 @@ handle_agentx_packet(int operation, netsnmp_session * session, int reqid,
+ if (asi == NULL) {
+ SNMP_FREE(smagic);
+ snmp_log(LOG_WARNING, "restore_set_vars() failed\n");
++ send_agentx_error(session, pdu, AGENTX_ERR_PROCESSING_ERROR, 0);
+ return 1;
+ }
+ asi->mode = pdu->command = SNMP_MSG_INTERNAL_SET_UNDO;
+@@ -484,6 +510,26 @@ handle_agentx_packet(int operation, netsnmp_session * session, int reqid,
+ return 1;
+ }
+
++static int
++_invalid_op_and_magic(int op, ns_subagent_magic *smagic)
++{
++ int invalid = 0;
++
++ if (smagic && (snmp_sess_pointer(smagic->session) == NULL ||
++ op == NETSNMP_CALLBACK_OP_TIMED_OUT)) {
++ if (smagic->ovars != NULL) {
++ snmp_free_varbind(smagic->ovars);
++ }
++ free(smagic);
++ invalid = 1;
++ }
++
++ if (op != NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE || smagic == NULL)
++ invalid = 1;
++
++ return invalid;
++}
++
+ int
+ handle_subagent_response(int op, netsnmp_session * session, int reqid,
+ netsnmp_pdu *pdu, void *magic)
+@@ -492,13 +538,7 @@ handle_subagent_response(int op, netsnmp_session * session, int reqid,
+ netsnmp_variable_list *u = NULL, *v = NULL;
+ int rc = 0;
+
+- if (op != NETSNMP_CALLBACK_OP_RECEIVED_MESSAGE || magic == NULL) {
+- if (op == NETSNMP_CALLBACK_OP_TIMED_OUT && magic != NULL) {
+- if (smagic->ovars != NULL) {
+- snmp_free_varbind(smagic->ovars);
+- }
+- free(smagic);
+- }
++ if (_invalid_op_and_magic(op, magic)) {
+ return 1;
+ }
+
+@@ -778,6 +818,7 @@ subagent_open_master_session(void)
+ {
+ netsnmp_transport *t;
+ netsnmp_session sess;
++ const char *agentx_socket;
+
+ DEBUGMSGTL(("agentx/subagent", "opening session...\n"));
+
+@@ -795,9 +836,9 @@ subagent_open_master_session(void)
+ sess.callback = handle_agentx_packet;
+ sess.authenticator = NULL;
+
+- t = netsnmp_transport_open_client(
+- "agentx", netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
+- NETSNMP_DS_AGENT_X_SOCKET));
++ agentx_socket = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
++ NETSNMP_DS_AGENT_X_SOCKET);
++ t = netsnmp_transport_open_client("agentx", agentx_socket);
+ if (t == NULL) {
+ /*
+ * Diagnose snmp_open errors with the input
+@@ -806,12 +847,9 @@ subagent_open_master_session(void)
+ if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_NO_CONNECTION_WARNINGS)) {
+ char buf[1024];
+- const char *socket =
+- netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
+- NETSNMP_DS_AGENT_X_SOCKET);
+ snprintf(buf, sizeof(buf), "Warning: "
+ "Failed to connect to the agentx master agent (%s)",
+- socket ? socket : "[NIL]");
++ agentx_socket ? agentx_socket : "[NIL]");
+ if (!netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_NO_ROOT_ACCESS)) {
+ netsnmp_sess_log_error(LOG_WARNING, buf, &sess);
+@@ -832,8 +870,7 @@ subagent_open_master_session(void)
+ char buf[1024];
+ snprintf(buf, sizeof(buf), "Error: "
+ "Failed to create the agentx master agent session (%s)",
+- netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
+- NETSNMP_DS_AGENT_X_SOCKET));
++ agentx_socket);
+ snmp_sess_perror(buf, &sess);
+ }
+ netsnmp_transport_free(t);
+diff --git a/agent/mibgroup/disman/event/mteEventConf.c b/agent/mibgroup/disman/event/mteEventConf.c
+index 949d6e5..24192a6 100644
+--- a/agent/mibgroup/disman/event/mteEventConf.c
++++ b/agent/mibgroup/disman/event/mteEventConf.c
+@@ -296,6 +296,11 @@ parse_setEvent( const char *token, char *line )
+ if (cp && *cp == '=') {
+ cp = skip_token( cp ); /* skip the '=' assignment character */
+ }
++ if (!cp) {
++ config_perror("syntax error: missing set value");
++ return;
++ }
++
+ value = strtol( cp, NULL, 0);
+
+ /*
+diff --git a/agent/mibgroup/disman/event/mteEventNotificationTable.c b/agent/mibgroup/disman/event/mteEventNotificationTable.c
+index 9095f0e..7d2c94a 100644
+--- a/agent/mibgroup/disman/event/mteEventNotificationTable.c
++++ b/agent/mibgroup/disman/event/mteEventNotificationTable.c
+@@ -98,6 +98,9 @@ mteEventNotificationTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_GET:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+@@ -136,6 +139,9 @@ mteEventNotificationTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_SET_RESERVE1:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+
+ /*
+@@ -204,6 +210,9 @@ mteEventNotificationTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_ACTION:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request);
+ if (!entry) {
+ /*
+@@ -225,6 +234,9 @@ mteEventNotificationTable_handler(netsnmp_mib_handler *handler,
+ * (reasonably) safe to apply them in the Commit phase
+ */
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+diff --git a/agent/mibgroup/disman/event/mteEventSetTable.c b/agent/mibgroup/disman/event/mteEventSetTable.c
+index 67a8170..ee696f1 100644
+--- a/agent/mibgroup/disman/event/mteEventSetTable.c
++++ b/agent/mibgroup/disman/event/mteEventSetTable.c
+@@ -100,6 +100,9 @@ mteEventSetTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_GET:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+@@ -151,6 +154,9 @@ mteEventSetTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_SET_RESERVE1:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+
+ /*
+@@ -233,6 +239,9 @@ mteEventSetTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_ACTION:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request);
+ if (!entry) {
+ /*
+@@ -254,6 +263,9 @@ mteEventSetTable_handler(netsnmp_mib_handler *handler,
+ * (reasonably) safe to apply them in the Commit phase
+ */
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+diff --git a/agent/mibgroup/disman/event/mteEventTable.c b/agent/mibgroup/disman/event/mteEventTable.c
+index 5603715..c5b534e 100644
+--- a/agent/mibgroup/disman/event/mteEventTable.c
++++ b/agent/mibgroup/disman/event/mteEventTable.c
+@@ -106,6 +106,9 @@ mteEventTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_GET:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+ if (!entry || !(entry->flags & MTE_EVENT_FLAG_VALID))
+@@ -142,6 +145,9 @@ mteEventTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_SET_RESERVE1:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+@@ -223,6 +229,9 @@ mteEventTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_RESERVE2:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+
+ switch (tinfo->colnum) {
+@@ -255,6 +264,9 @@ mteEventTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_FREE:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+
+ switch (tinfo->colnum) {
+@@ -280,6 +292,9 @@ mteEventTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_ACTION:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+ entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request);
+ if (!entry) {
+@@ -304,6 +319,9 @@ mteEventTable_handler(netsnmp_mib_handler *handler,
+ * (reasonably) safe to apply them in the Commit phase
+ */
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteEvent *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+diff --git a/agent/mibgroup/disman/event/mteObjectsTable.c b/agent/mibgroup/disman/event/mteObjectsTable.c
+index 443c5cc..f7f6e02 100644
+--- a/agent/mibgroup/disman/event/mteObjectsTable.c
++++ b/agent/mibgroup/disman/event/mteObjectsTable.c
+@@ -101,6 +101,9 @@ mteObjectsTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_GET:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteObject *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+@@ -135,6 +138,9 @@ mteObjectsTable_handler(netsnmp_mib_handler *handler,
+ case MODE_SET_RESERVE1:
+
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteObject *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+@@ -198,8 +204,10 @@ mteObjectsTable_handler(netsnmp_mib_handler *handler,
+ break;
+
+ case MODE_SET_RESERVE2:
+-
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+
+ switch (tinfo->colnum) {
+@@ -232,8 +240,10 @@ mteObjectsTable_handler(netsnmp_mib_handler *handler,
+ break;
+
+ case MODE_SET_FREE:
+-
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+
+ switch (tinfo->colnum) {
+@@ -259,6 +269,9 @@ mteObjectsTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_ACTION:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteObject *) netsnmp_tdata_extract_entry(request);
+ if (!entry) {
+ /*
+@@ -282,6 +295,9 @@ mteObjectsTable_handler(netsnmp_mib_handler *handler,
+ * (reasonably) safe to apply them in the Commit phase
+ */
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteObject *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+diff --git a/agent/mibgroup/disman/event/mteTrigger.c b/agent/mibgroup/disman/event/mteTrigger.c
+index 002b543..7fca1b0 100644
+--- a/agent/mibgroup/disman/event/mteTrigger.c
++++ b/agent/mibgroup/disman/event/mteTrigger.c
+@@ -255,6 +255,7 @@ mteTrigger_run( unsigned int reg, void *clientarg)
+ DEBUGMSGTL(( "disman:event:trigger:monitor", "Trigger query (%s) failed: %d\n",
+ (( entry->flags & MTE_TRIGGER_FLAG_VWILD ) ? "walk" : "get"), n));
+ _mteTrigger_failure( "failed to run mteTrigger query" );
++ snmp_free_varbind(var);
+ return;
+ }
+
+@@ -299,6 +300,7 @@ mteTrigger_run( unsigned int reg, void *clientarg)
+ if (!vtmp) {
+ _mteTrigger_failure(
+ "failed to create mteTrigger temp varbind");
++ snmp_free_varbind(var);
+ return;
+ }
+ vtmp->type = ASN_NULL;
+@@ -336,6 +338,7 @@ mteTrigger_run( unsigned int reg, void *clientarg)
+ if (!vtmp) {
+ _mteTrigger_failure(
+ "failed to create mteTrigger temp varbind");
++ snmp_free_varbind(var);
+ return;
+ }
+ vtmp->type = ASN_NULL;
+@@ -377,6 +380,7 @@ mteTrigger_run( unsigned int reg, void *clientarg)
+ if (!vtmp) {
+ _mteTrigger_failure(
+ "failed to create mteTrigger temp varbind");
++ snmp_free_varbind(var);
+ return;
+ }
+ vtmp->type = ASN_NULL;
+@@ -712,6 +716,7 @@ mteTrigger_run( unsigned int reg, void *clientarg)
+ if (!vtmp) {
+ _mteTrigger_failure(
+ "failed to create mteTrigger discontinuity varbind");
++ snmp_free_varbind(dvar);
+ return;
+ }
+ snmp_set_var_objid(vtmp, entry->mteDeltaDiscontID,
+diff --git a/agent/mibgroup/disman/event/mteTriggerBooleanTable.c b/agent/mibgroup/disman/event/mteTriggerBooleanTable.c
+index a34ad30..ed1ec30 100644
+--- a/agent/mibgroup/disman/event/mteTriggerBooleanTable.c
++++ b/agent/mibgroup/disman/event/mteTriggerBooleanTable.c
+@@ -97,6 +97,9 @@ mteTriggerBooleanTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_GET:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+@@ -105,8 +108,10 @@ mteTriggerBooleanTable_handler(netsnmp_mib_handler *handler,
+ * rows where the mteTriggerTest 'boolean(1)' bit is set.
+ * So skip entries where this isn't the case.
+ */
+- if (!entry || !(entry->mteTriggerTest & MTE_TRIGGER_BOOLEAN ))
++ if (!entry || !(entry->mteTriggerTest & MTE_TRIGGER_BOOLEAN )) {
++ netsnmp_request_set_error(request, SNMP_NOSUCHINSTANCE);
+ continue;
++ }
+
+ switch (tinfo->colnum) {
+ case COLUMN_MTETRIGGERBOOLEANCOMPARISON:
+@@ -152,6 +157,9 @@ mteTriggerBooleanTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_SET_RESERVE1:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+@@ -236,6 +244,9 @@ mteTriggerBooleanTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_ACTION:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ if (!entry) {
+ /*
+@@ -256,6 +267,9 @@ mteTriggerBooleanTable_handler(netsnmp_mib_handler *handler,
+ * (reasonably) safe to apply them in the Commit phase
+ */
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+diff --git a/agent/mibgroup/disman/event/mteTriggerDeltaTable.c b/agent/mibgroup/disman/event/mteTriggerDeltaTable.c
+index 47f112c..c2c2e8e 100644
+--- a/agent/mibgroup/disman/event/mteTriggerDeltaTable.c
++++ b/agent/mibgroup/disman/event/mteTriggerDeltaTable.c
+@@ -27,6 +27,7 @@ init_mteTriggerDeltaTable(void)
+ size_t mteTDeltaTable_oid_len = OID_LENGTH(mteTDeltaTable_oid);
+ netsnmp_handler_registration *reg;
+ netsnmp_table_registration_info *table_info;
++ int rc;
+
+ /*
+ * Ensure the (combined) table container is available...
+@@ -61,7 +62,9 @@ init_mteTriggerDeltaTable(void)
+ table_info->max_column = COLUMN_MTETRIGGERDELTADISCONTINUITYIDTYPE;
+
+ /* Register this using the (common) trigger_table_data container */
+- netsnmp_tdata_register(reg, trigger_table_data, table_info);
++ rc = netsnmp_tdata_register(reg, trigger_table_data, table_info);
++ if (rc != SNMPERR_SUCCESS)
++ return;
+ netsnmp_handler_owns_table_info(reg->handler->next);
+ DEBUGMSGTL(("disman:event:init", "Trigger Delta Table\n"));
+ }
+@@ -89,6 +92,9 @@ mteTriggerDeltaTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_GET:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+@@ -97,8 +103,10 @@ mteTriggerDeltaTable_handler(netsnmp_mib_handler *handler,
+ * rows where the mteTriggerSampleType is 'deltaValue(2)'
+ * So skip entries where this isn't the case.
+ */
+- if (!entry || !(entry->flags & MTE_TRIGGER_FLAG_DELTA ))
++ if (!entry || !(entry->flags & MTE_TRIGGER_FLAG_DELTA )) {
++ netsnmp_request_set_error(request, SNMP_NOSUCHINSTANCE);
+ continue;
++ }
+
+ switch (tinfo->colnum) {
+ case COLUMN_MTETRIGGERDELTADISCONTINUITYID:
+@@ -125,6 +133,9 @@ mteTriggerDeltaTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_SET_RESERVE1:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+@@ -199,6 +210,9 @@ mteTriggerDeltaTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_ACTION:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ if (!entry) {
+ /*
+@@ -219,6 +233,9 @@ mteTriggerDeltaTable_handler(netsnmp_mib_handler *handler,
+ * (reasonably) safe to apply them in the Commit phase
+ */
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+diff --git a/agent/mibgroup/disman/event/mteTriggerExistenceTable.c b/agent/mibgroup/disman/event/mteTriggerExistenceTable.c
+index ce1299f..22b683e 100644
+--- a/agent/mibgroup/disman/event/mteTriggerExistenceTable.c
++++ b/agent/mibgroup/disman/event/mteTriggerExistenceTable.c
+@@ -27,6 +27,7 @@ init_mteTriggerExistenceTable(void)
+ static oid mteTExistTable_oid[] = { 1, 3, 6, 1, 2, 1, 88, 1, 2, 4 };
+ size_t mteTExistTable_oid_len = OID_LENGTH(mteTExistTable_oid);
+ netsnmp_handler_registration *reg;
++ int rc;
+
+ /*
+ * Ensure the (combined) table container is available...
+@@ -61,7 +62,10 @@ init_mteTriggerExistenceTable(void)
+ table_info->max_column = COLUMN_MTETRIGGEREXISTENCEEVENT;
+
+ /* Register this using the (common) trigger_table_data container */
+- netsnmp_tdata_register(reg, trigger_table_data, table_info);
++ rc = netsnmp_tdata_register(reg, trigger_table_data, table_info);
++ if (rc != SNMPERR_SUCCESS)
++ return;
++
+ netsnmp_handler_owns_table_info(reg->handler->next);
+ DEBUGMSGTL(("disman:event:init", "Trigger Exist Table\n"));
+ }
+@@ -89,6 +93,9 @@ mteTriggerExistenceTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_GET:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+@@ -97,8 +104,10 @@ mteTriggerExistenceTable_handler(netsnmp_mib_handler *handler,
+ * rows where the mteTriggerTest 'existence(0)' bit is set.
+ * So skip entries where this isn't the case.
+ */
+- if (!entry || !(entry->mteTriggerTest & MTE_TRIGGER_EXISTENCE ))
++ if (!entry || !(entry->mteTriggerTest & MTE_TRIGGER_EXISTENCE )) {
++ netsnmp_request_set_error(request, SNMP_NOSUCHINSTANCE);
+ continue;
++ }
+
+ switch (tinfo->colnum) {
+ case COLUMN_MTETRIGGEREXISTENCETEST:
+@@ -139,6 +148,9 @@ mteTriggerExistenceTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_SET_RESERVE1:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+@@ -212,6 +224,9 @@ mteTriggerExistenceTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_ACTION:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ if (!entry) {
+ /*
+@@ -233,6 +248,9 @@ mteTriggerExistenceTable_handler(netsnmp_mib_handler *handler,
+ * (reasonably) safe to apply them in the Commit phase
+ */
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+diff --git a/agent/mibgroup/disman/event/mteTriggerTable.c b/agent/mibgroup/disman/event/mteTriggerTable.c
+index d738ab5..88c2f8b 100644
+--- a/agent/mibgroup/disman/event/mteTriggerTable.c
++++ b/agent/mibgroup/disman/event/mteTriggerTable.c
+@@ -109,6 +109,9 @@ mteTriggerTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_GET:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+@@ -186,6 +189,9 @@ mteTriggerTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_SET_RESERVE1:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+@@ -292,6 +298,9 @@ mteTriggerTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_RESERVE2:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+
+ switch (tinfo->colnum) {
+@@ -324,6 +333,9 @@ mteTriggerTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_FREE:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+
+ switch (tinfo->colnum) {
+@@ -349,6 +361,9 @@ mteTriggerTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_ACTION:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ if (!entry) {
+@@ -373,6 +388,9 @@ mteTriggerTable_handler(netsnmp_mib_handler *handler,
+ * (reasonably) safe to apply them in the Commit phase
+ */
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+diff --git a/agent/mibgroup/disman/event/mteTriggerThresholdTable.c b/agent/mibgroup/disman/event/mteTriggerThresholdTable.c
+index 37d35e0..5aed0c8 100644
+--- a/agent/mibgroup/disman/event/mteTriggerThresholdTable.c
++++ b/agent/mibgroup/disman/event/mteTriggerThresholdTable.c
+@@ -97,6 +97,9 @@ mteTriggerThresholdTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_GET:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+@@ -105,8 +108,10 @@ mteTriggerThresholdTable_handler(netsnmp_mib_handler *handler,
+ * rows where the mteTriggerTest 'threshold(2)' bit is set.
+ * So skip entries where this isn't the case.
+ */
+- if (!entry || !(entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD ))
++ if (!entry || !(entry->mteTriggerTest & MTE_TRIGGER_THRESHOLD )) {
++ netsnmp_request_set_error(request, SNMP_NOSUCHINSTANCE);
+ continue;
++ }
+
+ switch (tinfo->colnum) {
+ case COLUMN_MTETRIGGERTHRESHOLDSTARTUP:
+@@ -189,6 +194,9 @@ mteTriggerThresholdTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_SET_RESERVE1:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+@@ -276,6 +284,9 @@ mteTriggerThresholdTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_ACTION:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ if (!entry) {
+ /*
+@@ -296,6 +307,9 @@ mteTriggerThresholdTable_handler(netsnmp_mib_handler *handler,
+ * (reasonably) safe to apply them in the Commit phase
+ */
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct mteTrigger *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+diff --git a/agent/mibgroup/disman/expr/expErrorTable.c b/agent/mibgroup/disman/expr/expErrorTable.c
+index 6640a41..a759e2d 100644
+--- a/agent/mibgroup/disman/expr/expErrorTable.c
++++ b/agent/mibgroup/disman/expr/expErrorTable.c
+@@ -77,6 +77,9 @@ expErrorTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_GET:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct expExpression *)
+ netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+diff --git a/agent/mibgroup/disman/expr/expExpressionTable.c b/agent/mibgroup/disman/expr/expExpressionTable.c
+index ced9e0c..79aa715 100644
+--- a/agent/mibgroup/disman/expr/expExpressionTable.c
++++ b/agent/mibgroup/disman/expr/expExpressionTable.c
+@@ -88,6 +88,9 @@ expExpressionTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_GET:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct expExpression *)
+ netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+@@ -150,6 +153,9 @@ expExpressionTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_SET_RESERVE1:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct expExpression *)
+ netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+@@ -204,6 +210,9 @@ expExpressionTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_RESERVE2:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+
+ switch (tinfo->colnum) {
+@@ -236,6 +245,9 @@ expExpressionTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_FREE:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+
+ switch (tinfo->colnum) {
+@@ -261,6 +273,9 @@ expExpressionTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_ACTION:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+ entry = (struct expExpression *)
+ netsnmp_tdata_extract_entry(request);
+@@ -286,6 +301,9 @@ expExpressionTable_handler(netsnmp_mib_handler *handler,
+ * (reasonably) safe to apply them in the Commit phase
+ */
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct expExpression *)
+ netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+diff --git a/agent/mibgroup/disman/expr/expObject.c b/agent/mibgroup/disman/expr/expObject.c
+index 28fbac6..c27437b 100644
+--- a/agent/mibgroup/disman/expr/expObject.c
++++ b/agent/mibgroup/disman/expr/expObject.c
+@@ -240,7 +240,6 @@ void
+ expObject_getData( struct expExpression *expr, struct expObject *obj )
+ {
+ netsnmp_variable_list *var;
+- int res;
+
+ /*
+ * Retrieve and store the basic object value(s)
+@@ -279,7 +278,7 @@ expObject_getData( struct expExpression *expr, struct expObject *obj )
+ expr->expPrefix_len,
+ expr->pvars );
+ }
+- res = netsnmp_query_get( var, expr->session );
++ netsnmp_query_get( var, expr->session );
+ }
+
+ if ( obj->expObjectSampleType != EXPSAMPLETYPE_ABSOLUTE ) {
+@@ -312,7 +311,7 @@ expObject_getData( struct expExpression *expr, struct expObject *obj )
+ else
+ var = _expObject_buildList( obj->expObjDeltaD,
+ obj->expObjDeltaD_len, 0, NULL );
+- res = netsnmp_query_get( var, expr->session );
++ netsnmp_query_get( var, expr->session );
+ if ( obj->old_dvars )
+ snmp_free_varbind( obj->old_dvars );
+ obj->old_dvars = obj->dvars;
+@@ -338,7 +337,7 @@ expObject_getData( struct expExpression *expr, struct expObject *obj )
+ *
+ * (The MIB description seems bogus?)
+ */
+- res = netsnmp_query_get( var, expr->session );
++ netsnmp_query_get( var, expr->session );
+ if ( obj->cvars )
+ snmp_free_varbind( obj->cvars );
+ obj->cvars = var;
+diff --git a/agent/mibgroup/disman/expr/expObjectTable.c b/agent/mibgroup/disman/expr/expObjectTable.c
+index 4182b3e..adda438 100644
+--- a/agent/mibgroup/disman/expr/expObjectTable.c
++++ b/agent/mibgroup/disman/expr/expObjectTable.c
+@@ -90,6 +90,9 @@ expObjectTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_GET:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct expObject *)netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+ if (!entry || !(entry->flags & EXP_OBJ_FLAG_VALID))
+@@ -159,6 +162,9 @@ expObjectTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_SET_RESERVE1:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct expObject *)
+ netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+@@ -211,6 +217,9 @@ expObjectTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_RESERVE2:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+
+ switch (tinfo->colnum) {
+@@ -245,6 +254,9 @@ expObjectTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_FREE:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+
+ switch (tinfo->colnum) {
+@@ -270,6 +282,9 @@ expObjectTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_ACTION:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+ entry = (struct expObject *)
+ netsnmp_tdata_extract_entry(request);
+@@ -296,6 +311,9 @@ expObjectTable_handler(netsnmp_mib_handler *handler,
+ */
+ ret = 0; /* Flag to re-check expExpressionPrefix settings */
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct expObject *) netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info(request);
+
+diff --git a/agent/mibgroup/disman/expr/expValueTable.c b/agent/mibgroup/disman/expr/expValueTable.c
+index eac5faa..d74dbd1 100644
+--- a/agent/mibgroup/disman/expr/expValueTable.c
++++ b/agent/mibgroup/disman/expr/expValueTable.c
+@@ -124,7 +124,7 @@ NEXT_EXP:
+ }
+ if ( vp->val.objid[0] != 0 ) {
+ DEBUGMSGTL(( "disman:expr:val",
+- "non-zero instance (%d)\n", vp->val.objid[0]));
++ "non-zero instance (%" NETSNMP_PRIo "d)\n", vp->val.objid[0]));
+ return NULL; /* Invalid instance */
+ }
+
+@@ -158,7 +158,7 @@ NEXT_EXP:
+ */
+ if ( vp->val_len > 0 && vp->val.objid[0] != 0 ) {
+ DEBUGMSGTL(( "disman:expr:val",
+- "non-zero next instance (%d)\n", vp->val.objid[0]));
++ "non-zero next instance (%" NETSNMP_PRIo "d)\n", vp->val.objid[0]));
+ return NULL; /* All valid instances start with .0 */
+ }
+ plen = exp->expPrefix_len;
+@@ -231,6 +231,8 @@ NEXT_EXP:
+ len = vp2->name_length - exp->expPrefix_len;
+ snmp_set_var_typed_value( vp, ASN_PRIV_IMPLIED_OBJECT_ID,
+ (u_char*)(vp2->name+exp->expPrefix_len), len);
++ } else {
++ len = 1;
+ }
+ res = expValue_evaluateExpression( exp, vp->val.objid+1, len-1);
+ DEBUGMSGTL(( "disman:expr:val", "w/card next returned (%p)\n", res));
+diff --git a/agent/mibgroup/disman/expression/expValueTable.c b/agent/mibgroup/disman/expression/expValueTable.c
+index feace8c..6b315c6 100644
+--- a/agent/mibgroup/disman/expression/expValueTable.c
++++ b/agent/mibgroup/disman/expression/expValueTable.c
+@@ -133,7 +133,7 @@ init_expValueTable(void)
+ * Initialize a "session" that defines who we're going to talk to
+ */
+ snmp_sess_init(&session); /* set up defaults */
+- session.peername = "localhost";
++ session.peername = strdup("localhost");
+
+ DEBUGMSGTL(("expValueTable", "done.\n"));
+ }
+@@ -272,8 +272,7 @@ Evaluate_Expression(struct expValueTable_data *vtable_data)
+ break;
+ }
+ }
+- strncpy(temp, expression + 1, j - 1);
+- *(temp + j - 1) = '\0';
++ sprintf(temp, "%.*s", j - 1, expression + 1);
+ l = atoi(temp);
+ expression = expression + j;
+ /*
+@@ -434,24 +433,12 @@ expValueTable_clean(void *data)
+ void
+ build_valuetable(void)
+ {
+- struct expExpressionTable_data *expstorage, *expfound;
++ struct expExpressionTable_data *expstorage;
+ struct expObjectTable_data *objstorage, *objfound = NULL;
+ struct header_complex_index *hcindex, *object_hcindex;
+ char *expression;
+- size_t expression_len;
+ oid *index;
+-
+-
+- char *result, *resultbak;
+- char *temp, *tempbak;
+ int i = 0, j, l;
+- temp = malloc(100);
+- result = malloc(100);
+- tempbak = temp;
+- memset(result, 0, 100);
+- *result = '\0';
+- resultbak = result;
+-
+
+ DEBUGMSGTL(("expValueTable", "building valuetable... \n"));
+
+@@ -460,7 +447,6 @@ build_valuetable(void)
+ expstorage = (struct expExpressionTable_data *) hcindex->data;
+ if (expstorage->expExpressionEntryStatus == RS_ACTIVE) {
+ expression = expstorage->expExpression;
+- expression_len = expstorage->expExpressionLen;
+ while (*expression != '\0') {
+ if (*expression == '$') {
+ i++;
+@@ -475,9 +461,12 @@ build_valuetable(void)
+ break;
+ }
+ }
+- strncpy(temp, expression + 1, j - 1);
+- *(temp + j - 1) = '\0';
+- l = atoi(temp);
++ {
++ char temp[100];
++
++ sprintf(temp, "%.*s", j - 1, expression + 1);
++ l = atoi(temp);
++ }
+ for (object_hcindex = expObjectTableStorage;
+ object_hcindex != NULL;
+ object_hcindex = object_hcindex->next) {
+@@ -495,7 +484,6 @@ build_valuetable(void)
+ expstorage->expExpressionNameLen)
+ && (l == objstorage->expObjectIndex)) {
+ if (objfound == NULL) {
+- expfound = expstorage;
+ objfound = objstorage;
+ }
+ if (objstorage->expObjectIDWildcard ==
+diff --git a/agent/mibgroup/disman/ping/pingCtlTable.c b/agent/mibgroup/disman/ping/pingCtlTable.c
+index a4fd3a8..a5036e2 100644
+--- a/agent/mibgroup/disman/ping/pingCtlTable.c
++++ b/agent/mibgroup/disman/ping/pingCtlTable.c
+@@ -340,12 +340,11 @@ pingProbeHistoryTable_addall(struct pingCtlTable_data *thedata)
+ void
+ pingCtlTable_cleaner(struct header_complex_index *thestuff)
+ {
+- struct header_complex_index *hciptr = NULL;
+- struct pingCtlTable_data *StorageDel = NULL;
++ struct header_complex_index *hciptr;
++
+ DEBUGMSGTL(("pingProbeHistoryTable", "cleanerout "));
+ for (hciptr = thestuff; hciptr != NULL; hciptr = hciptr->next) {
+- StorageDel =
+- header_complex_extract_entry(&pingCtlTableStorage, hciptr);
++ header_complex_extract_entry(&pingCtlTableStorage, hciptr);
+ DEBUGMSGTL(("pingProbeHistoryTable", "cleaner "));
+ }
+ }
+@@ -864,7 +863,6 @@ pingProbeHistoryTable_delLast(struct pingCtlTable_data *thedata)
+ {
+ struct header_complex_index *hciptr2 = NULL;
+ struct header_complex_index *hcilast = NULL;
+- struct pingProbeHistoryTable_data *StorageDel = NULL;
+ struct pingProbeHistoryTable_data *StorageTmp = NULL;
+ netsnmp_variable_list *vars = NULL;
+ oid newoid[MAX_OID_LEN];
+@@ -895,9 +893,7 @@ pingProbeHistoryTable_delLast(struct pingCtlTable_data *thedata)
+
+ }
+ }
+- StorageDel =
+- header_complex_extract_entry(&pingProbeHistoryTableStorage,
+- hcilast);
++ header_complex_extract_entry(&pingProbeHistoryTableStorage, hcilast);
+ DEBUGMSGTL(("pingProbeHistoryTable",
+ "delete the last one success!\n"));
+ }
+@@ -1231,7 +1227,6 @@ readloop(struct pingCtlTable_data *item, struct addrinfo *ai, int datalen,
+ unsigned long *minrtt, unsigned long *maxrtt,
+ unsigned long *averagertt, pid_t pid)
+ {
+- int size;
+ char recvbuf[BUFSIZE];
+ char sendbuf[BUFSIZE];
+ int nsent = 1;
+@@ -1257,8 +1252,6 @@ readloop(struct pingCtlTable_data *item, struct addrinfo *ai, int datalen,
+ }
+ setuid(getuid()); /* don't need special permissions any more */
+
+- size = 60 * 1024; /* OK if setsockopt fails */
+-
+ tv.tv_sec = 5;
+ tv.tv_usec = 0;
+ setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+@@ -1266,11 +1259,13 @@ readloop(struct pingCtlTable_data *item, struct addrinfo *ai, int datalen,
+ for (current_probe_temp = 1;
+ current_probe_temp <= item->pingCtlProbeCount;
+ current_probe_temp++) {
++ time_t timep;
+ (*pr->fsend) (datalen, pid, nsent, sockfd, sendbuf);
+ nsent++;
+ len = pr->salen;
+ if (readable_timeo(sockfd, item->pingCtlTimeOut) == 0) {
+ /* printf("socket timeout!\n"); */
++ n = -1;
+ fail_probe = fail_probe + 1;
+ flag = 1;
+ } else {
+@@ -1282,18 +1277,17 @@ readloop(struct pingCtlTable_data *item, struct addrinfo *ai, int datalen,
+
+ gettimeofday(&tval, NULL);
+
+- time_t timep;
+ time(&timep);
+
+ (*pr->fproc) (recvbuf, n, &tval, timep, item, ai, datalen, minrtt,
+ maxrtt, sumrtt, averagertt, current_probe_temp,
+ success_probe, fail_probe, flag, &current_var, pid);
+- printf("receiver success!\n");
+ if (current_probe_temp >= item->pingCtlProbeCount) {
+ SNMP_FREE(sumrtt);
+ return;
+ }
+ }
++ close(sockfd);
+ }
+
+ unsigned long
+@@ -1599,7 +1593,6 @@ send_v4(int datalen, pid_t pid, int nsent, int sockfd, char *sendbuf)
+ {
+ int len;
+ struct icmp *icmp = NULL;
+- struct timeval *temp = NULL;
+
+ icmp = (struct icmp *) sendbuf;
+ icmp->icmp_type = ICMP_ECHO;
+@@ -1607,7 +1600,6 @@ send_v4(int datalen, pid_t pid, int nsent, int sockfd, char *sendbuf)
+ icmp->icmp_id = pid;
+ icmp->icmp_seq = nsent;
+ gettimeofday((struct timeval *) icmp->icmp_data, NULL);
+- temp = (struct timeval *) icmp->icmp_data;
+
+ len = 8 + datalen; /* checksum ICMP header and data */
+ icmp->icmp_cksum = 0;
+@@ -1773,7 +1765,7 @@ run_ping(unsigned int clientreg, void *clientarg)
+ if (device) {
+ struct ifreq ifr;
+ memset(&ifr, 0, sizeof(ifr));
+- strncpy(ifr.ifr_name, device, IFNAMSIZ - 1);
++ strlcpy(ifr.ifr_name, device, IFNAMSIZ);
+ if (setsockopt
+ (probe_fd, SOL_SOCKET, SO_BINDTODEVICE, device,
+ strlen(device) + 1) == -1) {
+@@ -1936,6 +1928,7 @@ run_ping(unsigned int clientreg, void *clientarg)
+ (char *) outpack, &ident, &start_time, &screen_width,
+ &deadline);
+
++ close(icmp_sock);
+ }
+ return;
+ }
+@@ -2705,8 +2698,7 @@ write_pingCtlAdminStatus(int action,
+ snmp_alarm_register(StorageTmp->pingCtlFrequency,
+ SA_REPEAT, run_ping, StorageTmp);
+ else
+- StorageTmp->timer_id = snmp_alarm_register(1, (int) NULL,
+- run_ping,
++ StorageTmp->timer_id = snmp_alarm_register(1, 0, run_ping,
+ StorageTmp);
+
+ } else if (StorageTmp->pingCtlAdminStatus == 2
+@@ -4367,8 +4359,7 @@ write_pingCtlRowStatus(int action,
+ StorageTmp);
+ else
+ StorageTmp->timer_id =
+- snmp_alarm_register(1, (int) NULL, run_ping,
+- StorageTmp);
++ snmp_alarm_register(1, 0, run_ping, StorageTmp);
+
+ }
+
+@@ -4451,7 +4442,9 @@ int
+ __schedule_exit(int next, long *nreceived, long *tmax)
+ {
+ unsigned long waittime;
++#if 0
+ struct itimerval it;
++#endif
+
+ if (*nreceived) {
+ waittime = 2 * (*tmax);
+@@ -4463,11 +4456,13 @@ __schedule_exit(int next, long *nreceived, long *tmax)
+ if (next < 0 || next < waittime / 1000)
+ next = waittime / 1000;
+
++#if 0
+ it.it_interval.tv_sec = 0;
+ it.it_interval.tv_usec = 0;
+ it.it_value.tv_sec = waittime / 1000000;
+ it.it_value.tv_usec = waittime % 1000000;
+- /* setitimer(ITIMER_REAL, &it, NULL); */
++ setitimer(ITIMER_REAL, &it, NULL);
++#endif
+ return next;
+ }
+
+@@ -4741,6 +4736,7 @@ setup(int icmp_sock, int options, int uid, int timeout, int preload,
+
+ gettimeofday(start_time, NULL);
+
++#if 0
+ if (*deadline) {
+ struct itimerval it;
+
+@@ -4749,6 +4745,7 @@ setup(int icmp_sock, int options, int uid, int timeout, int preload,
+ it.it_value.tv_sec = (*deadline);
+ it.it_value.tv_usec = 0;
+ }
++#endif
+
+ if (isatty(STDOUT_FILENO)) {
+ struct winsize w;
+diff --git a/agent/mibgroup/disman/ping/pingProbeHistoryTable.c b/agent/mibgroup/disman/ping/pingProbeHistoryTable.c
+index de398a8..78c75be 100644
+--- a/agent/mibgroup/disman/ping/pingProbeHistoryTable.c
++++ b/agent/mibgroup/disman/ping/pingProbeHistoryTable.c
+@@ -74,12 +74,10 @@ void
+ pingProbeHistoryTable_cleaner(struct header_complex_index *thestuff)
+ {
+ struct header_complex_index *hciptr = NULL;
+- struct pingProbeHistoryTable_data *StorageDel = NULL;
++
+ DEBUGMSGTL(("pingProbeHistoryTable", "cleanerout "));
+ for (hciptr = thestuff; hciptr != NULL; hciptr = hciptr->next) {
+- StorageDel =
+- header_complex_extract_entry(&pingProbeHistoryTableStorage,
+- hciptr);
++ header_complex_extract_entry(&pingProbeHistoryTableStorage, hciptr);
+ DEBUGMSGTL(("pingProbeHistoryTable", "cleaner "));
+ }
+
+diff --git a/agent/mibgroup/disman/ping/pingResultsTable.c b/agent/mibgroup/disman/ping/pingResultsTable.c
+index bc4a9f4..1445d86 100644
+--- a/agent/mibgroup/disman/ping/pingResultsTable.c
++++ b/agent/mibgroup/disman/ping/pingResultsTable.c
+@@ -86,12 +86,11 @@ pingResultsTable_inadd(struct pingResultsTable_data *thedata);
+ void
+ pingResultsTable_cleaner(struct header_complex_index *thestuff)
+ {
+- struct header_complex_index *hciptr = NULL;
+- struct pingResultsTable_data *StorageDel = NULL;
++ struct header_complex_index *hciptr;
++
+ DEBUGMSGTL(("pingResultsTable", "cleanerout "));
+ for (hciptr = thestuff; hciptr != NULL; hciptr = hciptr->next) {
+- StorageDel =
+- header_complex_extract_entry(&pingResultsTableStorage, hciptr);
++ header_complex_extract_entry(&pingResultsTableStorage, hciptr);
+ DEBUGMSGTL(("pingResultsTable", "cleaner "));
+ }
+
+diff --git a/agent/mibgroup/disman/schedule/schedCore.h b/agent/mibgroup/disman/schedule/schedCore.h
+index 4436711..35866d7 100644
+--- a/agent/mibgroup/disman/schedule/schedCore.h
++++ b/agent/mibgroup/disman/schedule/schedCore.h
+@@ -44,7 +44,7 @@ struct schedTable_entry {
+ char schedDay[4+4];
+ char schedHour[3];
+ char schedMinute[8];
+- char schedContextName[SCHED_STR1_LEN];
++ char schedContextName[SCHED_STR1_LEN+1];
+ oid schedVariable[ MAX_OID_LEN ];
+ size_t schedVariable_len;
+ long schedValue;
+diff --git a/agent/mibgroup/disman/schedule/schedTable.c b/agent/mibgroup/disman/schedule/schedTable.c
+index 943e545..bba48fd 100644
+--- a/agent/mibgroup/disman/schedule/schedTable.c
++++ b/agent/mibgroup/disman/schedule/schedTable.c
+@@ -98,6 +98,9 @@ schedTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_GET:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct schedTable_entry *)
+ netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info( request);
+@@ -210,6 +213,9 @@ schedTable_handler(netsnmp_mib_handler *handler,
+ */
+ case MODE_SET_RESERVE1:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct schedTable_entry *)
+ netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info( request);
+@@ -340,6 +346,9 @@ schedTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_RESERVE2:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+
+ switch (tinfo->colnum) {
+@@ -370,6 +379,9 @@ schedTable_handler(netsnmp_mib_handler *handler,
+
+ case MODE_SET_FREE:
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ tinfo = netsnmp_extract_table_info(request);
+
+ switch (tinfo->colnum) {
+@@ -417,7 +429,11 @@ schedTable_handler(netsnmp_mib_handler *handler,
+ * All these assignments are "unfailable", so it's
+ * (reasonably) safe to apply them in the Commit phase
+ */
++ entry = NULL;
+ for (request = requests; request; request = request->next) {
++ if (request->processed)
++ continue;
++
+ entry = (struct schedTable_entry *)
+ netsnmp_tdata_extract_entry(request);
+ tinfo = netsnmp_extract_table_info( request);
+@@ -460,7 +476,7 @@ schedTable_handler(netsnmp_mib_handler *handler,
+ recalculate = 1;
+ break;
+ case COLUMN_SCHEDCONTEXTNAME:
+- memset(entry->schedContextName, 0, SCHED_STR1_LEN+1);
++ memset(entry->schedContextName, 0, sizeof(entry->schedContextName));
+ memcpy(entry->schedContextName,
+ request->requestvb->val.string,
+ request->requestvb->val_len);
+@@ -514,8 +530,10 @@ schedTable_handler(netsnmp_mib_handler *handler,
+ break;
+ }
+ }
+- if (recalculate)
++ if (recalculate) {
++ netsnmp_assert(entry);
+ sched_nextTime(entry);
++ }
+ break;
+ }
+ return SNMP_ERR_NOERROR;
+diff --git a/agent/mibgroup/disman/traceroute/traceRouteCtlTable.c b/agent/mibgroup/disman/traceroute/traceRouteCtlTable.c
+index 23ac029..04143eb 100644
+--- a/agent/mibgroup/disman/traceroute/traceRouteCtlTable.c
++++ b/agent/mibgroup/disman/traceroute/traceRouteCtlTable.c
+@@ -713,7 +713,6 @@ traceRouteProbeHistoryTable_delLast(struct traceRouteCtlTable_data
+ {
+ struct header_complex_index *hciptr2 = NULL;
+ struct header_complex_index *hcilast = NULL;
+- struct traceRouteProbeHistoryTable_data *StorageDel = NULL;
+ struct traceRouteProbeHistoryTable_data *StorageTmp = NULL;
+ netsnmp_variable_list *vars = NULL;
+ oid newoid[MAX_OID_LEN];
+@@ -745,9 +744,7 @@ traceRouteProbeHistoryTable_delLast(struct traceRouteCtlTable_data
+
+ }
+ }
+- StorageDel =
+- header_complex_extract_entry(&traceRouteProbeHistoryTableStorage,
+- hcilast);
++ header_complex_extract_entry(&traceRouteProbeHistoryTableStorage, hcilast);
+ DEBUGMSGTL(("traceRouteProbeHistoryTable",
+ "delete the last one success!\n"));
+ vars = NULL;
+@@ -1353,7 +1350,6 @@ int
+ traceRouteResultsTable_del(struct traceRouteCtlTable_data *thedata)
+ {
+ struct header_complex_index *hciptr2 = NULL;
+- struct traceRouteResultsTable_data *StorageDel = NULL;
+ netsnmp_variable_list *vars = NULL;
+ oid newoid[MAX_OID_LEN];
+ size_t newoid_len = 0;
+@@ -1368,9 +1364,8 @@ traceRouteResultsTable_del(struct traceRouteCtlTable_data *thedata)
+ hciptr2 = hciptr2->next) {
+ if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len)
+ == 0) {
+- StorageDel =
+- header_complex_extract_entry
+- (&traceRouteResultsTableStorage, hciptr2);
++ header_complex_extract_entry(&traceRouteResultsTableStorage,
++ hciptr2);
+ DEBUGMSGTL(("traceRouteResultsTable", "delete success!\n"));
+
+ }
+@@ -1386,7 +1381,6 @@ int
+ traceRouteProbeHistoryTable_del(struct traceRouteCtlTable_data *thedata)
+ {
+ struct header_complex_index *hciptr2 = NULL;
+- struct traceRouteProbeHistoryTable_data *StorageDel = NULL;
+ netsnmp_variable_list *vars = NULL;
+ oid newoid[MAX_OID_LEN];
+ size_t newoid_len = 0;
+@@ -1402,9 +1396,8 @@ traceRouteProbeHistoryTable_del(struct traceRouteCtlTable_data *thedata)
+ hciptr2 = hciptr2->next) {
+ if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len)
+ == 0) {
+- StorageDel =
+- header_complex_extract_entry
+- (&traceRouteProbeHistoryTableStorage, hciptr2);
++ header_complex_extract_entry(&traceRouteProbeHistoryTableStorage,
++ hciptr2);
+ DEBUGMSGTL(("traceRouteProbeHistoryTable",
+ "delete success!\n"));
+
+@@ -1419,7 +1412,6 @@ int
+ traceRouteHopsTable_del(struct traceRouteCtlTable_data *thedata)
+ {
+ struct header_complex_index *hciptr2 = NULL;
+- struct traceRouteHopsTable_data *StorageDel = NULL;
+ netsnmp_variable_list *vars = NULL;
+ oid newoid[MAX_OID_LEN];
+ size_t newoid_len = 0;
+@@ -1435,9 +1427,7 @@ traceRouteHopsTable_del(struct traceRouteCtlTable_data *thedata)
+ hciptr2 = hciptr2->next) {
+ if (snmp_oid_compare(newoid, newoid_len, hciptr2->name, newoid_len)
+ == 0) {
+- StorageDel =
+- header_complex_extract_entry(&traceRouteHopsTableStorage,
+- hciptr2);
++ header_complex_extract_entry(&traceRouteHopsTableStorage, hciptr2);
+ DEBUGMSGTL(("traceRouteHopsTable", "delete success!\n"));
+
+ }
+@@ -3210,8 +3200,7 @@ write_traceRouteCtlAdminStatus(int action,
+ SA_REPEAT, run_traceRoute,
+ StorageTmp);
+ else
+- StorageTmp->timer_id = snmp_alarm_register(1, (int) NULL,
+- run_traceRoute,
++ StorageTmp->timer_id = snmp_alarm_register(1, 0, run_traceRoute,
+ StorageTmp);
+
+ } else if (StorageTmp->traceRouteCtlAdminStatus == 2
+@@ -4041,8 +4030,7 @@ write_traceRouteCtlRowStatus(int action,
+ StorageTmp);
+ else
+ StorageTmp->timer_id =
+- snmp_alarm_register(1, (int) NULL, run_traceRoute,
+- StorageTmp);
++ snmp_alarm_register(1, 0, run_traceRoute, StorageTmp);
+
+ }
+
+@@ -4924,6 +4912,8 @@ run_traceRoute(unsigned int clientreg, void *clientarg)
+
+ }
+
++ close(sndsock);
++
+ if (flag == 1) {
+ DEBUGMSGTL(("traceRouteProbeHistoryTable", "path changed!\n"));
+ send_traceRoute_trap(item, traceRoutePathChange,
+@@ -5556,6 +5546,8 @@ run_traceRoute(unsigned int clientreg, void *clientarg)
+
+ }
+
++ close(sndsock);
++
+ if (flag == 1) {
+ printf("path changed!\n");
+ send_traceRoute_trap(item, traceRoutePathChange,
+@@ -6105,7 +6097,7 @@ ifaddrlist(register struct ifaddrlist **ipaddrp, register char *errbuf)
+ #ifdef HAVE_SOCKADDR_SA_LEN
+ register int n;
+ #endif
+- register struct ifreq *ifrp, *ifend, *ifnext, *mp;
++ register struct ifreq *ifrp, *ifend, *ifnext;
+ register struct sockaddr_in *sin;
+ register struct ifaddrlist *al;
+ struct ifconf ifc;
+@@ -6137,7 +6129,6 @@ ifaddrlist(register struct ifaddrlist **ipaddrp, register char *errbuf)
+ ifend = (struct ifreq *) ((char *) ibuf + ifc.ifc_len);
+
+ al = ifaddrlist;
+- mp = NULL;
+ nipaddr = 0;
+ for (; ifrp < ifend; ifrp = ifnext) {
+ #ifdef HAVE_SOCKADDR_SA_LEN
+@@ -6157,7 +6148,7 @@ ifaddrlist(register struct ifaddrlist **ipaddrp, register char *errbuf)
+ * SIOCGIFFLAGS stomps over it because the requests
+ * are returned in a union.)
+ */
+- strncpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));
++ strlcpy(ifr.ifr_name, ifrp->ifr_name, sizeof(ifr.ifr_name));
+ if (ioctl(fd, SIOCGIFFLAGS, (char *) &ifr) < 0) {
+ if (errno == ENXIO)
+ continue;
+@@ -6174,9 +6165,7 @@ ifaddrlist(register struct ifaddrlist **ipaddrp, register char *errbuf)
+ if ((ifr.ifr_flags & IFF_UP) == 0)
+ continue;
+
+-
+- (void) strncpy(device, ifr.ifr_name, sizeof(ifr.ifr_name));
+- device[sizeof(device) - 1] = '\0';
++ sprintf(device, "%.*s", (int) sizeof(ifr.ifr_name), ifr.ifr_name);
+ #ifdef sun
+ /*
+ * Ignore sun virtual interfaces
+diff --git a/agent/mibgroup/etherlike-mib/data_access/dot3stats_linux.c b/agent/mibgroup/etherlike-mib/data_access/dot3stats_linux.c
+index efb1b54..00f4bc3 100644
+--- a/agent/mibgroup/etherlike-mib/data_access/dot3stats_linux.c
++++ b/agent/mibgroup/etherlike-mib/data_access/dot3stats_linux.c
+@@ -47,8 +47,8 @@ dot3stats_interface_name_list_get (struct ifname *list_head, int *retval)
+ *retval = -2;
+ return NULL;
+ }
+- memset (list_head, 0, sizeof (struct ifname));
+- strncpy (list_head->name, p->ifa_name, IF_NAMESIZE);
++ memset(list_head, 0, sizeof (struct ifname));
++ strlcpy(list_head->name, p->ifa_name, IF_NAMESIZE);
+ continue;
+ }
+
+@@ -69,8 +69,8 @@ dot3stats_interface_name_list_get (struct ifname *list_head, int *retval)
+ return NULL;
+ }
+ nameptr2 = nameptr2->ifn_next;
+- memset (nameptr2, 0, sizeof (struct ifname));
+- strncpy (nameptr2->name, p->ifa_name, IF_NAMESIZE);
++ memset(nameptr2, 0, sizeof (struct ifname));
++ strlcpy(nameptr2->name, p->ifa_name, IF_NAMESIZE);
+ continue;
+
+ }
+@@ -655,7 +655,7 @@ interface_ioctl_dot3stats_get (dot3StatsTable_rowreq_ctx *rowreq_ctx, int fd, co
+ "called\n"));
+
+ memset(&ifr, 0, sizeof(ifr));
+- strcpy(ifr.ifr_name, name);
++ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+
+ memset(&driver_info, 0, sizeof (driver_info));
+ driver_info.cmd = ETHTOOL_GDRVINFO;
+@@ -730,8 +730,8 @@ interface_ioctl_dot3stats_get (dot3StatsTable_rowreq_ctx *rowreq_ctx, int fd, co
+ for (i = 0; i < nstats; i++) {
+ char s[ETH_GSTRING_LEN];
+
+- strncpy(s, (const char *) &eth_strings->data[i * ETH_GSTRING_LEN],
+- ETH_GSTRING_LEN);
++ strlcpy(s, (const char *) &eth_strings->data[i * ETH_GSTRING_LEN],
++ sizeof(s));
+
+ if (DOT3STATSALIGNMENTERRORS(s)) {
+ data->dot3StatsAlignmentErrors = (u_long)eth_stats->data[i];
+@@ -911,8 +911,7 @@ _dot3Stats_ioctl_get(int fd, int which, struct ifreq *ifrq, const char* name)
+ }
+ }
+
+- strncpy(ifrq->ifr_name, name, sizeof(ifrq->ifr_name));
+- ifrq->ifr_name[ sizeof(ifrq->ifr_name)-1 ] = 0;
++ strlcpy(ifrq->ifr_name, name, sizeof(ifrq->ifr_name));
+ rc = ioctl(fd, which, ifrq);
+ if (rc < 0) {
+ DEBUGMSGTL(("access:dot3StatsTable:ioctl",
+diff --git a/agent/mibgroup/examples/example.c b/agent/mibgroup/examples/example.c
+index 8f27ead..50b7e7d 100644
+--- a/agent/mibgroup/examples/example.c
++++ b/agent/mibgroup/examples/example.c
+@@ -163,7 +163,7 @@ init_example(void)
+ * Also set a default value for the string object. Note that the
+ * example integer variable was initialised above.
+ */
+- strncpy(example_str, EXAMPLE_STR_DEFAULT, EXAMPLE_STR_LEN);
++ strlcpy(example_str, EXAMPLE_STR_DEFAULT, sizeof(example_str));
+
+ snmpd_register_config_handler("exampleint",
+ example_parse_config_exampleint,
+@@ -209,7 +209,7 @@ example_parse_config_examplestr(const char *token, char *cptr)
+ /*
+ * Make sure the string fits in the space allocated for it.
+ */
+- if (strlen(cptr) < EXAMPLE_STR_LEN)
++ if (strlen(cptr) < sizeof(example_str))
+ strcpy(example_str, cptr);
+ else {
+ /*
+@@ -217,10 +217,8 @@ example_parse_config_examplestr(const char *token, char *cptr)
+ * An alternative approach would be to log an error,
+ * and discard this value altogether.
+ */
+- strncpy(example_str, cptr, EXAMPLE_STR_LEN - 4);
+- example_str[EXAMPLE_STR_LEN - 4] = 0;
+- strcat(example_str, "...");
+- example_str[EXAMPLE_STR_LEN - 1] = 0;
++ sprintf(example_str, "%.*s...", (int) (sizeof(example_str) - 4), cptr);
++ netsnmp_assert(strlen(example_str) < sizeof(example_str));
+ }
+ }
+
+diff --git a/agent/mibgroup/examples/netSnmpHostsTable_access.c b/agent/mibgroup/examples/netSnmpHostsTable_access.c
+index f6f933a..3d2e5fb 100644
+--- a/agent/mibgroup/examples/netSnmpHostsTable_access.c
++++ b/agent/mibgroup/examples/netSnmpHostsTable_access.c
+@@ -177,10 +177,11 @@ void *
+ netSnmpHostsTable_create_data_context(netsnmp_variable_list * index_data)
+ {
+ my_data_info *datactx = SNMP_MALLOC_TYPEDEF(my_data_info);
++
+ if (!datactx)
+ return NULL;
+- strncpy(datactx->hostname, index_data->val.string,
+- strlen(index_data->val.string));
++ strlcpy(datactx->hostname, (const char *) index_data->val.string,
++ sizeof(datactx->hostname));
+ return datactx;
+ }
+
+diff --git a/agent/mibgroup/examples/netSnmpHostsTable_checkfns.c b/agent/mibgroup/examples/netSnmpHostsTable_checkfns.c
+index df47ca4..25a7330 100644
+--- a/agent/mibgroup/examples/netSnmpHostsTable_checkfns.c
++++ b/agent/mibgroup/examples/netSnmpHostsTable_checkfns.c
+@@ -34,9 +34,6 @@ int
+ check_netSnmpHostAddressType(int type, long *val, size_t val_len,
+ long *old_val, size_t old_val_len)
+ {
+-
+- int ret;
+-
+ /** Check to see that we were called legally */
+ if (!val)
+ return SNMP_ERR_GENERR;
+@@ -59,8 +56,6 @@ check_netSnmpHostAddressType(int type, long *val, size_t val_len,
+ default:
+ return SNMP_ERR_INCONSISTENTVALUE;
+ }
+- ret = SNMP_ERR_NOERROR;
+-
+
+ /** looks ok, call the local version of the same function. */
+ return check_netSnmpHostAddressType_local(type, val, val_len, old_val,
+@@ -79,9 +74,6 @@ int
+ check_netSnmpHostAddress(int type, char *val, size_t val_len,
+ char *old_val, size_t old_val_len)
+ {
+-
+- int ret;
+-
+ /** Check to see that we were called legally */
+ if (!val)
+ return SNMP_ERR_GENERR;
+@@ -91,11 +83,8 @@ check_netSnmpHostAddress(int type, char *val, size_t val_len,
+ return SNMP_ERR_WRONGTYPE;
+
+ /** Check the ranges of the passed value for legality */
+- if (!(val_len >= 0 && val_len <= 255)
+- ) {
++ if (!(val_len >= 0 && val_len <= 255))
+ return SNMP_ERR_WRONGVALUE;
+- }
+-
+
+ /** looks ok, call the local version of the same function. */
+ return check_netSnmpHostAddress_local(type, val, val_len, old_val,
+@@ -138,11 +127,10 @@ check_netSnmpHostStorage(int type, long *val, size_t val_len,
+ default:
+ return SNMP_ERR_INCONSISTENTVALUE;
+ }
+- ret = SNMP_ERR_NOERROR;
+
+- if (ret =
+- check_storage_transition((old_val) ? *old_val : SNMP_STORAGE_NONE,
+- *val))
++ ret = check_storage_transition((old_val) ? *old_val : SNMP_STORAGE_NONE,
++ *val);
++ if (ret)
+ return ret;
+
+ /** looks ok, call the local version of the same function. */
+@@ -187,11 +175,10 @@ check_netSnmpHostRowStatus(int type, long *val, size_t val_len,
+ default:
+ return SNMP_ERR_INCONSISTENTVALUE;
+ }
+- ret = SNMP_ERR_NOERROR;
+
+- if (ret =
+- check_rowstatus_transition((old_val) ? *old_val : RS_NONEXISTENT,
+- *val))
++ ret = check_rowstatus_transition((old_val) ? *old_val : RS_NONEXISTENT,
++ *val);
++ if (ret)
+ return ret;
+
+ /** looks ok, call the local version of the same function. */
+diff --git a/agent/mibgroup/examples/netSnmpHostsTable_checkfns_local.h b/agent/mibgroup/examples/netSnmpHostsTable_checkfns_local.h
+index 335a0ae..6cd44c9 100644
+--- a/agent/mibgroup/examples/netSnmpHostsTable_checkfns_local.h
++++ b/agent/mibgroup/examples/netSnmpHostsTable_checkfns_local.h
+@@ -3,8 +3,8 @@
+ * : : mib2c.check_values_local.conf,v 5.1 2003/05/30 23:53:15 hardaker Exp $
+ *
+ */
+-#ifndef NETSNMPHOSTSTABLE_CHECKFNS_H
+-#define NETSNMPHOSTSTABLE_CHECKFNS_H
++#ifndef NETSNMPHOSTSTABLE_CHECKFNS_LOCAL_H
++#define NETSNMPHOSTSTABLE_CHECKFNS_LOCAL_H
+
+ /*
+ * these functions are designed to check incoming values for
+@@ -18,19 +18,32 @@
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
++#if 0
++}
++#endif
+
+-int check_(int type, long *val, size_t val_len, long *old_val,
+- size_t old_val_len);
+-int check_(int type, char *val, size_t val_len, char *old_val,
+- size_t old_val_len);
+-int check_(int type, long *val, size_t val_len, long *old_val,
+- size_t old_val_len);
+-int check_(int type, long *val, size_t val_len, long *old_val,
+- size_t old_val_len);
+-
++int check_netSnmpHostAddressType_local(int type, long *val,
++ size_t val_len,
++ long *old_val,
++ size_t old_val_len);
++int check_netSnmpHostAddress_local(int type, char *val,
++ size_t val_len,
++ char *old_val,
++ size_t old_val_len);
++int check_netSnmpHostStorage_local(int type, long *val,
++ size_t val_len,
++ long *old_val,
++ size_t old_val_len);
++int check_netSnmpHostRowStatus_local(int type, long *val,
++ size_t val_len,
++ long *old_val,
++ size_t old_val_len);
+
++#if 0
++{
++#endif
+ #ifdef __cplusplus
+ }
+ #endif
+
+-#endif /* NETSNMPHOSTSTABLE_CHECKFNS_H */
++#endif /* NETSNMPHOSTSTABLE_CHECKFNS_LOCAL_H */
+diff --git a/agent/mibgroup/examples/ucdDemoPublic.c b/agent/mibgroup/examples/ucdDemoPublic.c
+index e935216..8e9e66a 100644
+--- a/agent/mibgroup/examples/ucdDemoPublic.c
++++ b/agent/mibgroup/examples/ucdDemoPublic.c
+@@ -25,6 +25,7 @@
+
+ #include <net-snmp/net-snmp-includes.h>
+ #include <net-snmp/agent/net-snmp-agent-includes.h>
++#include <net-snmp/library/tools.h>
+
+ #include "util_funcs/header_generic.h"
+ #include "ucdDemoPublic.h"
+@@ -213,16 +214,9 @@ write_ucdDemoPublicString(int action,
+ return SNMP_ERR_WRONGLENGTH;
+ }
+ if (action == COMMIT) {
+- if (var_val_len != 0) {
+- strncpy((char*)publicString, (const char*)var_val, sizeof(publicString)-1);
+- /* some sanity checks */
+- if (strlen((const char*)var_val) > sizeof(publicString)-1 ||
+- strlen((const char*)var_val) != var_val_len)
+- publicString[sizeof(publicString)-1] = '\0';
+- else
+- publicString[var_val_len] = '\0';
+- } else
+- publicString[0] = '\0';
++ sprintf((char*) publicString, "%.*s",
++ (int) SNMP_MIN(sizeof(publicString) - 1, var_val_len),
++ (const char*) var_val);
+ }
+ return SNMP_ERR_NOERROR;
+ }
+diff --git a/agent/mibgroup/hardware/cpu/cpu.c b/agent/mibgroup/hardware/cpu/cpu.c
+index 3a0a5d4..2772001 100644
+--- a/agent/mibgroup/hardware/cpu/cpu.c
++++ b/agent/mibgroup/hardware/cpu/cpu.c
+@@ -142,6 +142,12 @@ netsnmp_cpu_info *netsnmp_cpu_get_byName( char *name, int create ) {
+ cpu = SNMP_MALLOC_TYPEDEF( netsnmp_cpu_info );
+ if (!cpu)
+ return NULL;
++ if (strlen(name) >= sizeof(cpu->name)) {
++ free(cpu);
++ snmp_log(LOG_ERR, "Name of CPU is too large: %s\n", name);
++ return NULL;
++ }
++
+ strcpy(cpu->name, name);
+ if ( _cpu_tail ) {
+ cpu->idx = _cpu_tail->idx+1;
+diff --git a/agent/mibgroup/hardware/cpu/cpu_kerndata.c b/agent/mibgroup/hardware/cpu/cpu_kerndata.c
+index 9a9c4a4..8a7f2b2 100644
+--- a/agent/mibgroup/hardware/cpu/cpu_kerndata.c
++++ b/agent/mibgroup/hardware/cpu/cpu_kerndata.c
+@@ -64,32 +64,32 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
+ for ( i=0; i < cpu_num; i++ ) {
+ cpu2 = netsnmp_cpu_get_byIdx( i, 0 );
+
+- cpu2->user_ticks = (unsigned long)vminfo[i].v_time[V_CPU_USER];
+- cpu2->idle_ticks = (unsigned long)vminfo[i].v_time[V_CPU_IDLE];
+- cpu2->kern_ticks = (unsigned long)vminfo[i].v_time[V_CPU_KERNEL];
+- cpu2->wait_ticks = (unsigned long)vminfo[i].v_time[V_CPU_STREAM];
+- cpu2->sys2_ticks = (unsigned long)vminfo[i].v_time[V_CPU_KERNEL]+
++ cpu2->user_ticks = (unsigned long long)vminfo[i].v_time[V_CPU_USER];
++ cpu2->idle_ticks = (unsigned long long)vminfo[i].v_time[V_CPU_IDLE];
++ cpu2->kern_ticks = (unsigned long long)vminfo[i].v_time[V_CPU_KERNEL];
++ cpu2->wait_ticks = (unsigned long long)vminfo[i].v_time[V_CPU_STREAM];
++ cpu2->sys2_ticks = (unsigned long long)vminfo[i].v_time[V_CPU_KERNEL]+
+ vminfo[i].v_time[V_CPU_STREAM];
+ /* nice_ticks, intrpt_ticks, sirq_ticks unused */
+
+ /* sum these for the overall stats */
+- cpu->user_ticks += (unsigned long)vminfo[i].v_time[V_CPU_USER];
+- cpu->idle_ticks += (unsigned long)vminfo[i].v_time[V_CPU_IDLE];
+- cpu->kern_ticks += (unsigned long)vminfo[i].v_time[V_CPU_KERNEL];
+- cpu->wait_ticks += (unsigned long)vminfo[i].v_time[V_CPU_STREAM];
+- cpu->sys2_ticks += (unsigned long)vminfo[i].v_time[V_CPU_KERNEL]+
++ cpu->user_ticks += (unsigned long long)vminfo[i].v_time[V_CPU_USER];
++ cpu->idle_ticks += (unsigned long long)vminfo[i].v_time[V_CPU_IDLE];
++ cpu->kern_ticks += (unsigned long long)vminfo[i].v_time[V_CPU_KERNEL];
++ cpu->wait_ticks += (unsigned long long)vminfo[i].v_time[V_CPU_STREAM];
++ cpu->sys2_ticks += (unsigned long long)vminfo[i].v_time[V_CPU_KERNEL]+
+ vminfo[i].v_time[V_CPU_STREAM];
+
+ /*
+ * Interrupt/Context Switch statistics
+ * XXX - Do these really belong here ?
+ */
+- cpu->swapIn += (unsigned long)vminfo[i].v_swpin;
+- cpu->swapOut += (unsigned long)vminfo[i].v_swpout;
+- cpu->pageIn += (unsigned long)vminfo[i].v_phread;
+- cpu->pageOut += (unsigned long)vminfo[i].v_phwrite;
+- cpu->nInterrupts += (unsigned long)vminfo[i].v_intr;
+- cpu->nCtxSwitches += (unsigned long)vminfo[i].v_swtch;
++ cpu->swapIn += (unsigned long long)vminfo[i].v_swpin;
++ cpu->swapOut += (unsigned long long)vminfo[i].v_swpout;
++ cpu->pageIn += (unsigned long long)vminfo[i].v_phread;
++ cpu->pageOut += (unsigned long long)vminfo[i].v_phwrite;
++ cpu->nInterrupts += (unsigned long long)vminfo[i].v_intr;
++ cpu->nCtxSwitches += (unsigned long long)vminfo[i].v_swtch;
+ }
+ return 0;
+ }
+diff --git a/agent/mibgroup/hardware/cpu/cpu_kstat.c b/agent/mibgroup/hardware/cpu/cpu_kstat.c
+index 32ccb00..049864c 100644
+--- a/agent/mibgroup/hardware/cpu/cpu_kstat.c
++++ b/agent/mibgroup/hardware/cpu/cpu_kstat.c
+@@ -48,16 +48,13 @@ void init_cpu_kstat( void ) {
+ memset(state, 0, sizeof(state));
+ for (i=0, ks_data = ksp->ks_data; i < ksp->ks_ndata; i++, ks_data++) {
+ if ( strcmp( ks_data->name, "state" ) == 0 ) {
+- strncpy( state, ks_data->value.c, sizeof(state));
+- state[sizeof(state)-1] = '\0';
++ strlcpy(state, ks_data->value.c, sizeof(state));
+ } else if ( strcmp( ks_data->name, "state_begin" ) == 0 ) {
+ state_begin = ks_data->value.i32;
+ } else if ( strcmp( ks_data->name, "cpu_type" ) == 0 ) {
+- strncpy( ctype, ks_data->value.c, sizeof(ctype));
+- ctype[sizeof(ctype)-1] = '\0';
++ strlcpy(ctype, ks_data->value.c, sizeof(ctype));
+ } else if ( strcmp( ks_data->name, "fpu_type" ) == 0 ) {
+- strncpy( ftype, ks_data->value.c, sizeof(ftype));
+- ftype[sizeof(ftype)-1] = '\0';
++ strlcpy(ftype, ks_data->value.c, sizeof(ftype));
+ } else if ( strcmp( ks_data->name, "clock_MHz" ) == 0 ) {
+ clock = ks_data->value.i32;
+ }
+@@ -112,30 +109,30 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
+ break; /* or continue ? */
+ }
+
+- cpu2->user_ticks = (unsigned long)cs.cpu_sysinfo.cpu[CPU_USER];
+- cpu2->idle_ticks = (unsigned long)cs.cpu_sysinfo.cpu[CPU_IDLE];
+- cpu2->kern_ticks = (unsigned long)cs.cpu_sysinfo.cpu[CPU_KERNEL];
+- cpu2->wait_ticks = (unsigned long)cs.cpu_sysinfo.cpu[CPU_WAIT];
++ cpu2->user_ticks = (unsigned long long)cs.cpu_sysinfo.cpu[CPU_USER];
++ cpu2->idle_ticks = (unsigned long long)cs.cpu_sysinfo.cpu[CPU_IDLE];
++ cpu2->kern_ticks = (unsigned long long)cs.cpu_sysinfo.cpu[CPU_KERNEL];
++ cpu2->wait_ticks = (unsigned long long)cs.cpu_sysinfo.cpu[CPU_WAIT];
+ /* or cs.cpu_sysinfo.wait[W_IO]+cs.cpu_sysinfo.wait[W_PIO] */
+- cpu2->sys2_ticks = (unsigned long)cpu2->kern_ticks+cpu2->wait_ticks;
++ cpu2->sys2_ticks = (unsigned long long)cpu2->kern_ticks+cpu2->wait_ticks;
+ /* nice_ticks, intrpt_ticks, sirq_ticks unused */
+
+ /* sum these for the overall stats */
+- cpu->user_ticks += (unsigned long)cs.cpu_sysinfo.cpu[CPU_USER];
+- cpu->idle_ticks += (unsigned long)cs.cpu_sysinfo.cpu[CPU_IDLE];
+- cpu->kern_ticks += (unsigned long)cs.cpu_sysinfo.cpu[CPU_KERNEL];
+- cpu->wait_ticks += (unsigned long)cs.cpu_sysinfo.cpu[CPU_WAIT];
++ cpu->user_ticks += (unsigned long long)cs.cpu_sysinfo.cpu[CPU_USER];
++ cpu->idle_ticks += (unsigned long long)cs.cpu_sysinfo.cpu[CPU_IDLE];
++ cpu->kern_ticks += (unsigned long long)cs.cpu_sysinfo.cpu[CPU_KERNEL];
++ cpu->wait_ticks += (unsigned long long)cs.cpu_sysinfo.cpu[CPU_WAIT];
+ /* or cs.cpu_sysinfo.wait[W_IO]+cs.cpu_sysinfo.wait[W_PIO] */
+- cpu->sys2_ticks += (unsigned long)cpu2->kern_ticks+cpu2->wait_ticks;
++ cpu->sys2_ticks += (unsigned long long)cpu2->kern_ticks+cpu2->wait_ticks;
+
+ /*
+ * Interrupt/Context Switch statistics
+ * XXX - Do these really belong here ?
+ */
+- cpu->swapIn += (unsigned long)cs.cpu_vminfo.swapin;
+- cpu->swapOut += (unsigned long)cs.cpu_vminfo.swapout;
+- cpu->nInterrupts += (unsigned long)cs.cpu_sysinfo.intr;
+- cpu->nCtxSwitches += (unsigned long)cs.cpu_sysinfo.pswitch;
++ cpu->swapIn += (unsigned long long)cs.cpu_vminfo.swapin;
++ cpu->swapOut += (unsigned long long)cs.cpu_vminfo.swapout;
++ cpu->nInterrupts += (unsigned long long)cs.cpu_sysinfo.intr;
++ cpu->nCtxSwitches += (unsigned long long)cs.cpu_sysinfo.pswitch;
+ }
+ }
+ return 0;
+diff --git a/agent/mibgroup/hardware/cpu/cpu_linux.c b/agent/mibgroup/hardware/cpu/cpu_linux.c
+index 2edeccd..640407b 100644
+--- a/agent/mibgroup/hardware/cpu/cpu_linux.c
++++ b/agent/mibgroup/hardware/cpu/cpu_linux.c
+@@ -121,6 +121,10 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
+ DEBUGMSGTL(("cpu", "/proc/stat buffer increased to %d\n", bsize));
+ close(statfd);
+ statfd = open(STAT_FILE, O_RDONLY, 0);
++ if (statfd == -1) {
++ snmp_log_perror(STAT_FILE);
++ return -1;
++ }
+ }
+ close(statfd);
+
+@@ -159,27 +163,27 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
+
+ /* kernel 2.6.33 and above */
+ if (num_cpuline_elem == 10) {
+- cpu->guestnice_ticks = (unsigned long)cguest_nicell;
++ cpu->guestnice_ticks = (unsigned long long)cguest_nicell;
+ }
+ /* kernel 2.6.24 and above */
+ if (num_cpuline_elem >= 9) {
+- cpu->guest_ticks = (unsigned long)cguestll;
++ cpu->guest_ticks = (unsigned long long)cguestll;
+ }
+ /* kernel 2.6.11 and above */
+ if (num_cpuline_elem >= 8) {
+- cpu->steal_ticks = (unsigned long)cstealll;
++ cpu->steal_ticks = (unsigned long long)cstealll;
+ }
+ /* kernel 2.6 */
+ if (num_cpuline_elem >= 5) {
+- cpu->wait_ticks = (unsigned long)ciowll;
+- cpu->intrpt_ticks = (unsigned long)cirqll;
+- cpu->sirq_ticks = (unsigned long)csoftll;
++ cpu->wait_ticks = (unsigned long long)ciowll;
++ cpu->intrpt_ticks = (unsigned long long)cirqll;
++ cpu->sirq_ticks = (unsigned long long)csoftll;
+ }
+ /* rest */
+- cpu->user_ticks = (unsigned long)cusell;
+- cpu->nice_ticks = (unsigned long)cicell;
+- cpu->sys_ticks = (unsigned long)csysll;
+- cpu->idle_ticks = (unsigned long)cidell;
++ cpu->user_ticks = (unsigned long long)cusell;
++ cpu->nice_ticks = (unsigned long long)cicell;
++ cpu->sys_ticks = (unsigned long long)csysll;
++ cpu->idle_ticks = (unsigned long long)cidell;
+ }
+ if ( b1 == buff ) {
+ if (first)
+@@ -232,6 +236,10 @@ void _cpu_load_swap_etc( char *buff, netsnmp_cpu_info *cpu ) {
+ vmbuff = (char*)realloc(vmbuff, vmbsize+1);
+ close(vmstatfd);
+ vmstatfd = open(VMSTAT_FILE, O_RDONLY, 0);
++ if (vmstatfd == -1) {
++ snmp_log_perror("cannot open " VMSTAT_FILE);
++ return;
++ }
+ }
+ close(vmstatfd);
+ if ( bytes_read < 0 ) {
+@@ -246,7 +254,7 @@ void _cpu_load_swap_etc( char *buff, netsnmp_cpu_info *cpu ) {
+ b = strstr(vmbuff, "pgpgin ");
+ if (b) {
+ sscanf(b, "pgpgin %llu", &pin);
+- cpu->pageIn = (unsigned long)pin*2; /* ??? */
++ cpu->pageIn = (unsigned long long)pin*2; /* ??? */
+ } else {
+ if (first)
+ snmp_log(LOG_ERR, "No pgpgin line in %s\n", VMSTAT_FILE);
+@@ -255,7 +263,7 @@ void _cpu_load_swap_etc( char *buff, netsnmp_cpu_info *cpu ) {
+ b = strstr(vmbuff, "pgpgout ");
+ if (b) {
+ sscanf(b, "pgpgout %llu", &pout);
+- cpu->pageOut = (unsigned long)pout*2; /* ??? */
++ cpu->pageOut = (unsigned long long)pout*2; /* ??? */
+ } else {
+ if (first)
+ snmp_log(LOG_ERR, "No pgpgout line in %s\n", VMSTAT_FILE);
+@@ -264,7 +272,7 @@ void _cpu_load_swap_etc( char *buff, netsnmp_cpu_info *cpu ) {
+ b = strstr(vmbuff, "pswpin ");
+ if (b) {
+ sscanf(b, "pswpin %llu", &swpin);
+- cpu->swapIn = (unsigned long)swpin;
++ cpu->swapIn = (unsigned long long)swpin;
+ } else {
+ if (first)
+ snmp_log(LOG_ERR, "No pswpin line in %s\n", VMSTAT_FILE);
+@@ -273,7 +281,7 @@ void _cpu_load_swap_etc( char *buff, netsnmp_cpu_info *cpu ) {
+ b = strstr(vmbuff, "pswpout ");
+ if (b) {
+ sscanf(b, "pswpout %llu", &swpout);
+- cpu->swapOut = (unsigned long)swpout;
++ cpu->swapOut = (unsigned long long)swpout;
+ } else {
+ if (first)
+ snmp_log(LOG_ERR, "No pswpout line in %s\n", VMSTAT_FILE);
+@@ -284,8 +292,8 @@ void _cpu_load_swap_etc( char *buff, netsnmp_cpu_info *cpu ) {
+ b = strstr(buff, "page ");
+ if (b) {
+ sscanf(b, "page %llu %llu", &pin, &pout);
+- cpu->pageIn = (unsigned long)pin;
+- cpu->pageOut = (unsigned long)pout;
++ cpu->pageIn = (unsigned long long)pin;
++ cpu->pageOut = (unsigned long long)pout;
+ } else {
+ if (first)
+ snmp_log(LOG_ERR, "No page line in %s\n", STAT_FILE);
+@@ -294,8 +302,8 @@ void _cpu_load_swap_etc( char *buff, netsnmp_cpu_info *cpu ) {
+ b = strstr(buff, "swap ");
+ if (b) {
+ sscanf(b, "swap %llu %llu", &swpin, &swpout);
+- cpu->swapIn = (unsigned long)swpin;
+- cpu->swapOut = (unsigned long)swpout;
++ cpu->swapIn = (unsigned long long)swpin;
++ cpu->swapOut = (unsigned long long)swpout;
+ } else {
+ if (first)
+ snmp_log(LOG_ERR, "No swap line in %s\n", STAT_FILE);
+@@ -306,7 +314,7 @@ void _cpu_load_swap_etc( char *buff, netsnmp_cpu_info *cpu ) {
+ b = strstr(buff, "intr ");
+ if (b) {
+ sscanf(b, "intr %llu %llu", &itot, &iticks);
+- cpu->nInterrupts = (unsigned long)itot;
++ cpu->nInterrupts = (unsigned long long)itot;
+ /* iticks not used? */
+ } else {
+ if (first)
+@@ -315,7 +323,7 @@ void _cpu_load_swap_etc( char *buff, netsnmp_cpu_info *cpu ) {
+ b = strstr(buff, "ctxt ");
+ if (b) {
+ sscanf(b, "ctxt %llu", &ctx);
+- cpu->nCtxSwitches = (unsigned long)ctx;
++ cpu->nCtxSwitches = (unsigned long long)ctx;
+ } else {
+ if (first)
+ snmp_log(LOG_ERR, "No ctxt line in %s\n", STAT_FILE);
+diff --git a/agent/mibgroup/hardware/cpu/cpu_nlist.c b/agent/mibgroup/hardware/cpu/cpu_nlist.c
+index b9554d7..974028a 100644
+--- a/agent/mibgroup/hardware/cpu/cpu_nlist.c
++++ b/agent/mibgroup/hardware/cpu/cpu_nlist.c
+@@ -76,12 +76,12 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
+ auto_nlist( CPU_SYMBOL, (char *) cpu_stats, sizeof(cpu_stats));
+ auto_nlist( MEM_SYMBOL, (char *)&mem_stats, sizeof(mem_stats));
+
+- cpu->user_ticks = (unsigned long)cpu_stats[CP_USER];
+- cpu->nice_ticks = (unsigned long)cpu_stats[CP_NICE];
+- cpu->sys2_ticks = (unsigned long)cpu_stats[CP_SYS]+cpu_stats[CP_INTR];
+- cpu->idle_ticks = (unsigned long)cpu_stats[CP_IDLE];
+- cpu->kern_ticks = (unsigned long)cpu_stats[CP_SYS];
+- cpu->intrpt_ticks = (unsigned long)cpu_stats[CP_INTR];
++ cpu->user_ticks = (unsigned long long)cpu_stats[CP_USER];
++ cpu->nice_ticks = (unsigned long long)cpu_stats[CP_NICE];
++ cpu->sys2_ticks = (unsigned long long)cpu_stats[CP_SYS]+cpu_stats[CP_INTR];
++ cpu->idle_ticks = (unsigned long long)cpu_stats[CP_IDLE];
++ cpu->kern_ticks = (unsigned long long)cpu_stats[CP_SYS];
++ cpu->intrpt_ticks = (unsigned long long)cpu_stats[CP_INTR];
+ /* wait_ticks, sirq_ticks unused */
+
+ /*
+@@ -89,14 +89,14 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
+ * XXX - Do these really belong here ?
+ */
+ #if defined(openbsd2) || defined(darwin)
+- cpu->swapIn = (unsigned long)mem_stats.v_swpin;
+- cpu->swapOut = (unsigned long)mem_stats.v_swpout;
++ cpu->swapIn = (unsigned long long)mem_stats.v_swpin;
++ cpu->swapOut = (unsigned long long)mem_stats.v_swpout;
+ #else
+- cpu->swapIn = (unsigned long)mem_stats.v_swappgsin+mem_stats.v_vnodepgsin;
+- cpu->swapOut = (unsigned long)mem_stats.v_swappgsout+mem_stats.v_vnodepgsout;
++ cpu->swapIn = (unsigned long long)mem_stats.v_swappgsin+mem_stats.v_vnodepgsin;
++ cpu->swapOut = (unsigned long long)mem_stats.v_swappgsout+mem_stats.v_vnodepgsout;
+ #endif
+- cpu->nInterrupts = (unsigned long)mem_stats.v_intr;
+- cpu->nCtxSwitches = (unsigned long)mem_stats.v_swtch;
++ cpu->nInterrupts = (unsigned long long)mem_stats.v_intr;
++ cpu->nCtxSwitches = (unsigned long long)mem_stats.v_swtch;
+
+ #ifdef PER_CPU_INFO
+ for ( i = 0; i < n; i++ ) {
+diff --git a/agent/mibgroup/hardware/cpu/cpu_pcp.c b/agent/mibgroup/hardware/cpu/cpu_pcp.c
+index dcc2724..94c7b5c 100644
+--- a/agent/mibgroup/hardware/cpu/cpu_pcp.c
++++ b/agent/mibgroup/hardware/cpu/cpu_pcp.c
+@@ -153,13 +153,13 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
+ exit(1);
+ }
+
+- cpu->wait_ticks = (unsigned long)resp->vset[CPUWAIT]->vlist[0].value.lval / 10;
+- cpu->intrpt_ticks = (unsigned long)resp->vset[CPUINTR]->vlist[0].value.lval / 10;
++ cpu->wait_ticks = (unsigned long long)resp->vset[CPUWAIT]->vlist[0].value.lval / 10;
++ cpu->intrpt_ticks = (unsigned long long)resp->vset[CPUINTR]->vlist[0].value.lval / 10;
+ /*cpu->sirq_ticks = (unsigned long)csoftll / 10;*/
+- cpu->user_ticks = (unsigned long)resp->vset[CPUUSER]->vlist[0].value.lval / 10;
++ cpu->user_ticks = (unsigned long long)resp->vset[CPUUSER]->vlist[0].value.lval / 10;
+ /*cpu->nice_ticks = (unsigned long)cicell / 10;*/
+- cpu->sys_ticks = (unsigned long)resp->vset[CPUSYS]->vlist[0].value.lval / 10;
+- cpu->idle_ticks = (unsigned long)resp->vset[CPUIDLE]->vlist[0].value.lval / 10;
++ cpu->sys_ticks = (unsigned long long)resp->vset[CPUSYS]->vlist[0].value.lval / 10;
++ cpu->idle_ticks = (unsigned long long)resp->vset[CPUIDLE]->vlist[0].value.lval / 10;
+
+
+ /*
+@@ -168,12 +168,12 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
+ */
+ /*cpu = netsnmp_cpu_get_byIdx( -1, 0 );*/
+ /*_cpu_load_swap_etc( buff, cpu );*/
+- cpu->pageIn = (unsigned long)resp->vset[PAGESIN]->vlist[0].value.lval;
+- cpu->pageOut = (unsigned long)resp->vset[PAGESOUT]->vlist[0].value.lval;
+- cpu->swapIn = (unsigned long)resp->vset[SWAPIN]->vlist[0].value.lval;
+- cpu->swapOut = (unsigned long)resp->vset[SWAPOUT]->vlist[0].value.lval;
+- cpu->nInterrupts = (unsigned long)resp->vset[INTR]->vlist[0].value.lval;
+- cpu->nCtxSwitches = (unsigned long)resp->vset[CTXT]->vlist[0].value.lval;
++ cpu->pageIn = (unsigned long long)resp->vset[PAGESIN]->vlist[0].value.lval;
++ cpu->pageOut = (unsigned long long)resp->vset[PAGESOUT]->vlist[0].value.lval;
++ cpu->swapIn = (unsigned long long)resp->vset[SWAPIN]->vlist[0].value.lval;
++ cpu->swapOut = (unsigned long long)resp->vset[SWAPOUT]->vlist[0].value.lval;
++ cpu->nInterrupts = (unsigned long long)resp->vset[INTR]->vlist[0].value.lval;
++ cpu->nCtxSwitches = (unsigned long long)resp->vset[CTXT]->vlist[0].value.lval;
+
+ /*
+ * XXX - TODO: extract per-CPU statistics
+diff --git a/agent/mibgroup/hardware/cpu/cpu_perfstat.c b/agent/mibgroup/hardware/cpu/cpu_perfstat.c
+index 981656d..5f58190 100644
+--- a/agent/mibgroup/hardware/cpu/cpu_perfstat.c
++++ b/agent/mibgroup/hardware/cpu/cpu_perfstat.c
+@@ -58,27 +58,27 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
+ sizeof(perfstat_cpu_total_t), 1) > 0) {
+
+ /* Returns 'u_longlong_t' statistics */
+- cpu->user_ticks = (unsigned long)cs.user / cs.ncpus;
+- cpu->sys_ticks = ((unsigned long)cs.sys + (unsigned long)cs.wait) / cs.ncpus;
+- cpu->kern_ticks = (unsigned long)cs.sys / cs.ncpus;
+- cpu->wait_ticks = (unsigned long)cs.wait / cs.ncpus;
+- cpu->idle_ticks = (unsigned long)cs.idle / cs.ncpus;
++ cpu->user_ticks = (unsigned long long)cs.user / cs.ncpus;
++ cpu->sys_ticks = ((unsigned long long)cs.sys + (unsigned long long)cs.wait) / cs.ncpus;
++ cpu->kern_ticks = (unsigned long long)cs.sys / cs.ncpus;
++ cpu->wait_ticks = (unsigned long long)cs.wait / cs.ncpus;
++ cpu->idle_ticks = (unsigned long long)cs.idle / cs.ncpus;
+ /* intrpt_ticks, sirq_ticks, nice_ticks unused */
+
+ /*
+ * Interrupt/Context Switch statistics
+ * XXX - Do these really belong here ?
+ */
+- cpu->pageIn = (unsigned long)cs.sysread;
+- cpu->pageOut = (unsigned long)cs.syswrite;
+- cpu->nInterrupts = (unsigned long)cs.devintrs + cs.softintrs;
+- cpu->nCtxSwitches = (unsigned long)cs.pswitch;
++ cpu->pageIn = (unsigned long long)cs.sysread;
++ cpu->pageOut = (unsigned long long)cs.syswrite;
++ cpu->nInterrupts = (unsigned long long)cs.devintrs + cs.softintrs;
++ cpu->nCtxSwitches = (unsigned long long)cs.pswitch;
+ }
+
+ if (perfstat_memory_total((perfstat_id_t *)NULL, &ms,
+ sizeof(perfstat_memory_total_t), 1) > 0) {
+- cpu->swapIn = (unsigned long)ms.pgspins;
+- cpu->swapOut = (unsigned long)ms.pgspouts;
++ cpu->swapIn = (unsigned long long)ms.pgspins;
++ cpu->swapOut = (unsigned long long)ms.pgspouts;
+ }
+
+
+@@ -91,14 +91,14 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
+ if (perfstat_cpu(&name, cs2, sizeof(perfstat_cpu_t), n) > 0) {
+ for ( i = 0; i < n; i++ ) {
+ cpu = netsnmp_cpu_get_byIdx( i, 0 );
+- cpu->user_ticks = (unsigned long)cs2[i].user;
+- cpu->sys_ticks = (unsigned long)cs2[i].sys + (unsigned long)cs2[i].wait;
+- cpu->kern_ticks = (unsigned long)cs2[i].sys;
+- cpu->wait_ticks = (unsigned long)cs2[i].wait;
+- cpu->idle_ticks = (unsigned long)cs2[i].idle;
+- cpu->pageIn = (unsigned long)cs2[i].sysread;
+- cpu->pageOut = (unsigned long)cs2[i].syswrite;
+- cpu->nCtxSwitches = (unsigned long)cs2[i].pswitch;
++ cpu->user_ticks = (unsigned long long)cs2[i].user;
++ cpu->sys_ticks = (unsigned long long)cs2[i].sys + (unsigned long long)cs2[i].wait;
++ cpu->kern_ticks = (unsigned long long)cs2[i].sys;
++ cpu->wait_ticks = (unsigned long long)cs2[i].wait;
++ cpu->idle_ticks = (unsigned long long)cs2[i].idle;
++ cpu->pageIn = (unsigned long long)cs2[i].sysread;
++ cpu->pageOut = (unsigned long long)cs2[i].syswrite;
++ cpu->nCtxSwitches = (unsigned long long)cs2[i].pswitch;
+ /* Interrupt stats only apply overall, not per-CPU */
+ }
+ } else {
+diff --git a/agent/mibgroup/hardware/cpu/cpu_pstat.c b/agent/mibgroup/hardware/cpu/cpu_pstat.c
+index c68739b..35c1d63 100644
+--- a/agent/mibgroup/hardware/cpu/cpu_pstat.c
++++ b/agent/mibgroup/hardware/cpu/cpu_pstat.c
+@@ -72,13 +72,13 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
+
+ pstat_getdynamic(&psd, sizeof(psd), 1, 0);
+ /* XXX - Compare cpu_num against psd.psd_proc_cnt */
+- cpu->user_ticks = (unsigned long)psd.psd_cpu_time[CP_USER];
+- cpu->nice_ticks = (unsigned long)psd.psd_cpu_time[CP_NICE];
+- cpu->sys2_ticks = (unsigned long)psd.psd_cpu_time[CP_SYS]+
++ cpu->user_ticks = (unsigned long long)psd.psd_cpu_time[CP_USER];
++ cpu->nice_ticks = (unsigned long long)psd.psd_cpu_time[CP_NICE];
++ cpu->sys2_ticks = (unsigned long long)psd.psd_cpu_time[CP_SYS]+
+ psd.psd_cpu_time[CP_WAIT];
+- cpu->idle_ticks = (unsigned long)psd.psd_cpu_time[CP_IDLE];
+- cpu->wait_ticks = (unsigned long)psd.psd_cpu_time[CP_WAIT];
+- cpu->kern_ticks = (unsigned long)psd.psd_cpu_time[CP_SYS];
++ cpu->idle_ticks = (unsigned long long)psd.psd_cpu_time[CP_IDLE];
++ cpu->wait_ticks = (unsigned long long)psd.psd_cpu_time[CP_WAIT];
++ cpu->kern_ticks = (unsigned long long)psd.psd_cpu_time[CP_SYS];
+ /* XXX - record (sum of) "all other ticks" */
+ /* intrpt_ticks, sirq_ticks unused */
+
+@@ -87,21 +87,21 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
+ * XXX - Do these really belong here ?
+ */
+ pstat_getvminfo(&psv, sizeof(psv), 1, 0);
+- cpu->swapIn = (unsigned long)psv.psv_sswpin;
+- cpu->swapOut = (unsigned long)psv.psv_sswpout;
+- cpu->nInterrupts = (unsigned long)psv.psv_sintr;
+- cpu->nCtxSwitches = (unsigned long)psv.psv_sswtch;
++ cpu->swapIn = (unsigned long long)psv.psv_sswpin;
++ cpu->swapOut = (unsigned long long)psv.psv_sswpout;
++ cpu->nInterrupts = (unsigned long long)psv.psv_sintr;
++ cpu->nCtxSwitches = (unsigned long long)psv.psv_sswtch;
+
+
+ for ( i = 0; i < psd.psd_proc_cnt; i++ ) {
+ cpu = netsnmp_cpu_get_byIdx( i, 0 );
+- cpu->user_ticks = (unsigned long)psd.psd_mp_cpu_time[i][CP_USER];
+- cpu->nice_ticks = (unsigned long)psd.psd_mp_cpu_time[i][CP_NICE];
+- cpu->sys2_ticks = (unsigned long)psd.psd_mp_cpu_time[i][CP_SYS]+
++ cpu->user_ticks = (unsigned long long)psd.psd_mp_cpu_time[i][CP_USER];
++ cpu->nice_ticks = (unsigned long long)psd.psd_mp_cpu_time[i][CP_NICE];
++ cpu->sys2_ticks = (unsigned long long)psd.psd_mp_cpu_time[i][CP_SYS]+
+ psd.psd_mp_cpu_time[i][CP_WAIT];
+- cpu->idle_ticks = (unsigned long)psd.psd_mp_cpu_time[i][CP_IDLE];
+- cpu->wait_ticks = (unsigned long)psd.psd_mp_cpu_time[i][CP_WAIT];
+- cpu->kern_ticks = (unsigned long)psd.psd_mp_cpu_time[i][CP_SYS];
++ cpu->idle_ticks = (unsigned long long)psd.psd_mp_cpu_time[i][CP_IDLE];
++ cpu->wait_ticks = (unsigned long long)psd.psd_mp_cpu_time[i][CP_WAIT];
++ cpu->kern_ticks = (unsigned long long)psd.psd_mp_cpu_time[i][CP_SYS];
+ /* XXX - record (sum of) "all other ticks" */
+ }
+
+diff --git a/agent/mibgroup/hardware/cpu/cpu_sysctl.c b/agent/mibgroup/hardware/cpu/cpu_sysctl.c
+index e549671..5599a58 100644
+--- a/agent/mibgroup/hardware/cpu/cpu_sysctl.c
++++ b/agent/mibgroup/hardware/cpu/cpu_sysctl.c
+@@ -40,23 +40,25 @@ void _cpu_copy_stats( netsnmp_cpu_info *cpu );
+ * (including descriptions)
+ */
+ void init_cpu_sysctl( void ) {
+- int n;
+- size_t i;
++ int i, n;
++ size_t siz;
+ int ncpu_mib[] = { CTL_HW, HW_NCPU };
++#if !(defined(__NetBSD__) && ( defined(__i386__) || defined(__x86_64__) ) )
+ int model_mib[] = { CTL_HW, HW_MODEL };
++#endif
+ char descr[ SNMP_MAXBUF ];
+ netsnmp_cpu_info *cpu = netsnmp_cpu_get_byIdx( -1, 1 );
+ strcpy(cpu->name, "Overall CPU statistics");
+
+- i = sizeof(n);
+- sysctl(ncpu_mib, 2, &n, &i, NULL, 0);
++ siz = sizeof(n);
++ sysctl(ncpu_mib, 2, &n, &siz, NULL, 0);
+ if ( n <= 0 )
+ n = 1; /* Single CPU system */
+- i = sizeof(descr);
++ siz = sizeof(descr);
+ #if defined(__NetBSD__) && ( defined(__i386__) || defined(__x86_64__) )
+- sysctlbyname("machdep.cpu_brand", descr, (void *)&i, NULL, 0);
++ sysctlbyname("machdep.cpu_brand", descr, &siz, NULL, 0);
+ #else
+- sysctl(model_mib, 2, descr, &i, NULL, 0);
++ sysctl(model_mib, 2, descr, &siz, NULL, 0);
+ #endif
+ for ( i = 0; i < n; i++ ) {
+ cpu = netsnmp_cpu_get_byIdx( i, 1 );
+@@ -176,12 +178,12 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
+ #else
+ sysctl(cpu_mib, 2, cpu_stats, &cpu_size, NULL, 0);
+ #endif
+- cpu->user_ticks = (unsigned long)cpu_stats[CP_USER];
+- cpu->nice_ticks = (unsigned long)cpu_stats[CP_NICE];
+- cpu->sys2_ticks = (unsigned long)cpu_stats[CP_SYS]+cpu_stats[CP_INTR];
+- cpu->kern_ticks = (unsigned long)cpu_stats[CP_SYS];
+- cpu->idle_ticks = (unsigned long)cpu_stats[CP_IDLE];
+- cpu->intrpt_ticks = (unsigned long)cpu_stats[CP_INTR];
++ cpu->user_ticks = (unsigned long long)cpu_stats[CP_USER];
++ cpu->nice_ticks = (unsigned long long)cpu_stats[CP_NICE];
++ cpu->sys2_ticks = (unsigned long long)cpu_stats[CP_SYS]+cpu_stats[CP_INTR];
++ cpu->kern_ticks = (unsigned long long)cpu_stats[CP_SYS];
++ cpu->idle_ticks = (unsigned long long)cpu_stats[CP_IDLE];
++ cpu->intrpt_ticks = (unsigned long long)cpu_stats[CP_INTR];
+ /* wait_ticks, sirq_ticks unused */
+
+ /*
+@@ -189,15 +191,15 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic ) {
+ * XXX - Do these really belong here ?
+ */
+ sysctl(mem_mib, 2, &mem_stats, &mem_size, NULL, 0);
+- cpu->nInterrupts = (unsigned long)mem_stats.NS_VM_INTR;
+- cpu->nCtxSwitches = (unsigned long)mem_stats.NS_VM_SWTCH;
+- cpu->swapIn = (unsigned long)mem_stats.NS_VM_SWAPIN;
+- cpu->swapOut = (unsigned long)mem_stats.NS_VM_SWAPOUT;
++ cpu->nInterrupts = (unsigned long long)mem_stats.NS_VM_INTR;
++ cpu->nCtxSwitches = (unsigned long long)mem_stats.NS_VM_SWTCH;
++ cpu->swapIn = (unsigned long long)mem_stats.NS_VM_SWAPIN;
++ cpu->swapOut = (unsigned long long)mem_stats.NS_VM_SWAPOUT;
+ #ifdef NS_VM_PAGEIN
+- cpu->pageIn = (unsigned long)mem_stats.NS_VM_PAGEIN;
++ cpu->pageIn = (unsigned long long)mem_stats.NS_VM_PAGEIN;
+ #endif
+ #ifdef NS_VM_PAGEOUT
+- cpu->pageOut = (unsigned long)mem_stats.NS_VM_PAGEOUT;
++ cpu->pageOut = (unsigned long long)mem_stats.NS_VM_PAGEOUT;
+ #endif
+
+ #ifdef NETSNMP_KERN_MCPU
+diff --git a/agent/mibgroup/hardware/cpu/cpu_sysinfo.c b/agent/mibgroup/hardware/cpu/cpu_sysinfo.c
+index d510308..ed1f357 100644
+--- a/agent/mibgroup/hardware/cpu/cpu_sysinfo.c
++++ b/agent/mibgroup/hardware/cpu/cpu_sysinfo.c
+@@ -91,20 +91,20 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic )
+ }
+
+ DEBUGMSGTL(("cpu_sysinfo", "total cpu kernel: %lu\n", sinfo_gen->cpu[CPU_KERNEL]));
+- cpu->sys2_ticks = (unsigned long) sinfo_gen->cpu[CPU_KERNEL] + (unsigned long) sinfo_gen->cpu[CPU_SXBRK] + (unsigned long) sinfo_gen->cpu[CPU_INTR];
+- cpu->kern_ticks = (unsigned long) sinfo_gen->cpu[CPU_KERNEL];
+- cpu->intrpt_ticks = (unsigned long) sinfo_gen->cpu[CPU_INTR];
+- cpu->user_ticks = (unsigned long) sinfo_gen->cpu[CPU_USER];
+- cpu->wait_ticks = (unsigned long) sinfo_gen->cpu[CPU_WAIT];
+- cpu->idle_ticks = (unsigned long) sinfo_gen->cpu[CPU_IDLE];
++ cpu->sys2_ticks = (unsigned long long) sinfo_gen->cpu[CPU_KERNEL] + (unsigned long long) sinfo_gen->cpu[CPU_SXBRK] + (unsigned long long) sinfo_gen->cpu[CPU_INTR];
++ cpu->kern_ticks = (unsigned long long) sinfo_gen->cpu[CPU_KERNEL];
++ cpu->intrpt_ticks = (unsigned long long) sinfo_gen->cpu[CPU_INTR];
++ cpu->user_ticks = (unsigned long long) sinfo_gen->cpu[CPU_USER];
++ cpu->wait_ticks = (unsigned long long) sinfo_gen->cpu[CPU_WAIT];
++ cpu->idle_ticks = (unsigned long long) sinfo_gen->cpu[CPU_IDLE];
+
+ /* XXX - Do these really belong here ? */
+- cpu->pageIn = (unsigned long)0;
+- cpu->pageOut = (unsigned long)0;
+- cpu->swapIn = (unsigned long)sinfo_gen->swapin;
+- cpu->swapOut = (unsigned long)sinfo_gen->swapout;
+- cpu->nInterrupts = (unsigned long)sinfo_gen->intr_svcd;
+- cpu->nCtxSwitches = (unsigned long)sinfo_gen->pswitch;
++ cpu->pageIn = (unsigned long long)0;
++ cpu->pageOut = (unsigned long long)0;
++ cpu->swapIn = (unsigned long long)sinfo_gen->swapin;
++ cpu->swapOut = (unsigned long long)sinfo_gen->swapout;
++ cpu->nInterrupts = (unsigned long long)sinfo_gen->intr_svcd;
++ cpu->nCtxSwitches = (unsigned long long)sinfo_gen->pswitch;
+
+ /* fetch individual cpu stats */
+
+@@ -120,11 +120,11 @@ int netsnmp_cpu_arch_load( netsnmp_cache *cache, void *magic )
+ cpu = netsnmp_cpu_get_byIdx(i, 0);
+
+ DEBUGMSGTL(("cpu_sysinfo", "cpu %u kernel: %lu\n", i, sinfo_cpus[i].cpu[CPU_KERNEL]));
+- cpu->sys2_ticks = (unsigned long)sinfo_cpus[i].cpu[CPU_KERNEL] + (unsigned long) sinfo_cpus[i].cpu[CPU_SXBRK] + (unsigned long)sinfo_cpus[i].cpu[CPU_INTR];
+- cpu->intrpt_ticks = (unsigned long)sinfo_cpus[i].cpu[CPU_INTR];
+- cpu->user_ticks = (unsigned long)sinfo_cpus[i].cpu[CPU_USER];
+- cpu->wait_ticks = (unsigned long)sinfo_cpus[i].cpu[CPU_WAIT];
+- cpu->idle_ticks = (unsigned long)sinfo_cpus[i].cpu[CPU_IDLE];
++ cpu->sys2_ticks = (unsigned long long)sinfo_cpus[i].cpu[CPU_KERNEL] + (unsigned long long) sinfo_cpus[i].cpu[CPU_SXBRK] + (unsigned long long)sinfo_cpus[i].cpu[CPU_INTR];
++ cpu->intrpt_ticks = (unsigned long long)sinfo_cpus[i].cpu[CPU_INTR];
++ cpu->user_ticks = (unsigned long long)sinfo_cpus[i].cpu[CPU_USER];
++ cpu->wait_ticks = (unsigned long long)sinfo_cpus[i].cpu[CPU_WAIT];
++ cpu->idle_ticks = (unsigned long long)sinfo_cpus[i].cpu[CPU_IDLE];
+ }
+
+ return 0;
+diff --git a/agent/mibgroup/hardware/fsys/fsys_getfsstats.c b/agent/mibgroup/hardware/fsys/fsys_getfsstats.c
+index 55327b7..93f38ce 100644
+--- a/agent/mibgroup/hardware/fsys/fsys_getfsstats.c
++++ b/agent/mibgroup/hardware/fsys/fsys_getfsstats.c
+@@ -164,7 +164,7 @@ netsnmp_fsys_arch_load( void )
+ entry->type = _fs_type( stats[i].f_fstypename );
+ entry->flags |= NETSNMP_FS_FLAG_ACTIVE;
+
+- if (! stats[i].NSFS_FLAGS & MNT_LOCAL ) {
++ if (! (stats[i].NSFS_FLAGS & MNT_LOCAL )) {
+ entry->flags |= NETSNMP_FS_FLAG_REMOTE;
+ }
+ if ( stats[i].NSFS_FLAGS & MNT_RDONLY ) {
+@@ -175,4 +175,6 @@ netsnmp_fsys_arch_load( void )
+ }
+ netsnmp_fsys_calculate32(entry);
+ }
++
++ free(stats);
+ }
+diff --git a/agent/mibgroup/hardware/fsys/fsys_mntctl.c b/agent/mibgroup/hardware/fsys/fsys_mntctl.c
+index e65d6d5..3ad68d4 100644
+--- a/agent/mibgroup/hardware/fsys/fsys_mntctl.c
++++ b/agent/mibgroup/hardware/fsys/fsys_mntctl.c
+@@ -128,9 +128,9 @@ netsnmp_fsys_arch_load( void )
+ continue;
+ }
+
+- strncpy( entry->path, path, sizeof( entry->path ));
+- strncpy( entry->device, vmt2dataptr( aixcurr, VMT_STUB),
+- sizeof( entry->device ));
++ strlcpy(entry->path, path, sizeof(entry->path));
++ strlcpy(entry->device, vmt2dataptr(aixcurr, VMT_STUB),
++ sizeof(entry->device));
+ entry->type = _fsys_type( aixcurr->vmt_gfstype );
+
+ if (!(entry->type & _NETSNMP_FS_TYPE_SKIP_BIT))
+diff --git a/agent/mibgroup/hardware/fsys/fsys_mntent.c b/agent/mibgroup/hardware/fsys/fsys_mntent.c
+index 1a156f4..c380365 100644
+--- a/agent/mibgroup/hardware/fsys/fsys_mntent.c
++++ b/agent/mibgroup/hardware/fsys/fsys_mntent.c
+@@ -135,6 +135,9 @@ _fsys_type( char *typename )
+ !strcmp(typename, MNTTYPE_GFS2) ||
+ !strcmp(typename, MNTTYPE_XFS) ||
+ !strcmp(typename, MNTTYPE_JFS) ||
++ !strcmp(typename, MNTTYPE_VXFS) ||
++ !strcmp(typename, MNTTYPE_REISERFS) ||
++ !strcmp(typename, MNTTYPE_OCFS2) ||
+ !strcmp(typename, MNTTYPE_LOFS))
+ return NETSNMP_FS_TYPE_OTHER;
+
+@@ -190,11 +193,9 @@ netsnmp_fsys_arch_load( void )
+ continue;
+ }
+
+- strncpy( entry->path, m->NSFS_PATH, sizeof( entry->path ));
+- entry->path[sizeof(entry->path)-1] = '\0';
+- strncpy( entry->device, m->NSFS_DEV, sizeof( entry->device ));
+- entry->device[sizeof(entry->device)-1] = '\0';
+- entry->type = _fsys_type( m->NSFS_TYPE );
++ strlcpy(entry->path, m->NSFS_PATH, sizeof(entry->path));
++ strlcpy(entry->device, m->NSFS_DEV, sizeof(entry->device));
++ entry->type = _fsys_type(m->NSFS_TYPE);
+ if (!(entry->type & _NETSNMP_FS_TYPE_SKIP_BIT))
+ entry->flags |= NETSNMP_FS_FLAG_ACTIVE;
+
+diff --git a/agent/mibgroup/hardware/fsys/hw_fsys.c b/agent/mibgroup/hardware/fsys/hw_fsys.c
+index c96284e..a6cd94d 100644
+--- a/agent/mibgroup/hardware/fsys/hw_fsys.c
++++ b/agent/mibgroup/hardware/fsys/hw_fsys.c
+@@ -3,6 +3,9 @@
+ #include <net-snmp/net-snmp-includes.h>
+ #include <net-snmp/agent/net-snmp-agent-includes.h>
+ #include <net-snmp/agent/hardware/fsys.h>
++#ifdef HAVE_INTTYPES_H
++#include <inttypes.h>
++#endif
+
+ netsnmp_feature_child_of(hw_fsys_get_container, netsnmp_unused)
+
+@@ -174,9 +177,8 @@ netsnmp_fsys_by_path( char *path, int create_type )
+ * ... so let's create a new one
+ */
+ sp = _fsys_create_entry();
+- if ( sp ) {
+- strncpy( sp->path, path, sizeof(sp->path) );
+- }
++ if (sp)
++ strlcpy(sp->path, path, sizeof(sp->path));
+ return sp;
+ }
+
+@@ -217,9 +219,8 @@ netsnmp_fsys_by_device( char *device, int create_type )
+ * ... so let's create a new one
+ */
+ sp = _fsys_create_entry();
+- if ( sp ) {
+- strncpy( sp->device, device, sizeof(sp->device) );
+- }
++ if (sp)
++ strlcpy(sp->device, device, sizeof(sp->device));
+ return sp;
+ }
+
+@@ -242,7 +243,7 @@ _fsys_create_entry( void )
+ sp->idx.oids[0] = ++_fsys_idx;
+ }
+
+- DEBUGMSGTL(("fsys:new", "Create filesystem entry (index = %d\n", _fsys_idx));
++ DEBUGMSGTL(("fsys:new", "Create filesystem entry (index = %d)\n", _fsys_idx));
+ CONTAINER_INSERT( _fsys_container, sp );
+ return sp;
+ }
+@@ -319,21 +320,30 @@ netsnmp_fsys_avail( netsnmp_fsys_info *f) {
+ #define INT32_MAX 0x7fffffff
+ #endif
+
++#ifndef PRIu64
++#define PRIu64 "llu"
++#endif
++
+ /* recalculate f->size_32, used_32, avail_32 and units_32 from f->size & comp.*/
+ void
+-netsnmp_fsys_calculate32( netsnmp_fsys_info *f)
++netsnmp_fsys_calculate32(netsnmp_fsys_info *f)
+ {
+ unsigned long long s = f->size;
+- unsigned long long u = f->units;
+- int factor = 0;
++ unsigned shift = 0;
++
+ while (s > INT32_MAX) {
+ s = s >> 1;
+- u = u << 1;
+- factor++;
++ shift++;
+ }
+
+ f->size_32 = s;
+- f->units_32 = u;
+- f->avail_32 = f->avail << factor;
+- f->used_32 = f->used << factor;
++ f->units_32 = f->units << shift;
++ f->avail_32 = f->avail >> shift;
++ f->used_32 = f->used >> shift;
++
++ DEBUGMSGTL(("fsys", "Results of 32-bit conversion: size %" PRIu64 " -> %lu;"
++ " units %" PRIu64 " -> %lu; avail %" PRIu64 " -> %lu;"
++ " used %" PRIu64 " -> %lu\n",
++ (uint64_t)f->size, f->size_32, (uint64_t)f->units, f->units_32,
++ (uint64_t)f->avail, f->avail_32, (uint64_t)f->used, f->used_32));
+ }
+diff --git a/agent/mibgroup/hardware/fsys/mnttypes.h b/agent/mibgroup/hardware/fsys/mnttypes.h
+index f6d96fe..9183451 100644
+--- a/agent/mibgroup/hardware/fsys/mnttypes.h
++++ b/agent/mibgroup/hardware/fsys/mnttypes.h
+@@ -90,9 +90,6 @@
+ #ifndef MNTTYPE_PC
+ #define MNTTYPE_PC "pc"
+ #endif
+-#ifndef MNTTYPE_REISERFS
+-#define MNTTYPE_REISERFS "reiserfs"
+-#endif
+ #ifndef MNTTYPE_SMBFS
+ #define MNTTYPE_SMBFS "smbfs"
+ #endif
+@@ -108,30 +105,48 @@
+ #ifndef MNTTYPE_VFAT
+ #define MNTTYPE_VFAT "vfat"
+ #endif
++
++/*
++ * File systems to monitor, but not covered by HR-TYPES enumerations
++ */
++#ifndef MNTTYPE_MVFS
++#define MNTTYPE_MVFS "mvfs"
++#endif
++#ifndef MNTTYPE_TMPFS
++#define MNTTYPE_TMPFS "tmpfs"
++#endif
+ #ifndef MNTTYPE_GFS
+ #define MNTTYPE_GFS "gfs"
+ #endif
+ #ifndef MNTTYPE_GFS2
+ #define MNTTYPE_GFS2 "gfs2"
+ #endif
+-
+-/*
+- * File systems to monitor, but not covered by HR-TYPES enumerations
+- */
++#ifndef MNTTYPE_XFS
++#define MNTTYPE_XFS "xfs"
++#endif
++#ifndef MNTTYPE_JFS
++#define MNTTYPE_JFS "jfs"
++#endif
++#ifndef MNTTYPE_VXFS
++#define MNTTYPE_VXFS "vxfs"
++#endif
++#ifndef MNTTYPE_REISERFS
++#define MNTTYPE_REISERFS "reiserfs"
++#endif
+ #ifndef MNTTYPE_LOFS
+ #define MNTTYPE_LOFS "lofs"
+ #endif
+-#ifndef MNTTYPE_APP
+-#define MNTTYPE_APP "app"
+-#endif
+-#ifndef MNTTYPE_MVFS
+-#define MNTTYPE_MVFS "mvfs"
++#ifndef MNTTYPE_OCFS2
++#define MNTTYPE_OCFS2 "ocfs2"
+ #endif
+
+ /*
+ * File systems to skip
+ * (Probably not strictly needed)
+ */
++#ifndef MNTTYPE_APP
++#define MNTTYPE_APP "app"
++#endif
+ #ifndef MNTTYPE_DEVPTS
+ #define MNTTYPE_DEVPTS "devpts"
+ #endif
+@@ -144,9 +159,6 @@
+ #ifndef MNTTYPE_SYSFS
+ #define MNTTYPE_SYSFS "sysfs"
+ #endif
+-#ifndef MNTTYPE_TMPFS
+-#define MNTTYPE_TMPFS "tmpfs"
+-#endif
+ #ifndef MNTTYPE_USBFS
+ #define MNTTYPE_USBFS "usbfs"
+ #endif
+@@ -156,12 +168,5 @@
+ #ifndef MNTTYPE_RPCPIPE
+ #define MNTTYPE_RPCPIPE "rpc_pipefs"
+ #endif
+-#ifndef MNTTYPE_XFS
+-#define MNTTYPE_XFS "xfs"
+-#endif
+-#ifndef MNTTYPE_JFS
+-#define MNTTYPE_JFS "jfs"
+-#endif
+-
+
+ #endif /* _NETSNMP_FSYS_MNTTYPES_H */
+diff --git a/agent/mibgroup/hardware/memory/memory_linux.c b/agent/mibgroup/hardware/memory/memory_linux.c
+index 89abf57..8c189c5 100644
+--- a/agent/mibgroup/hardware/memory/memory_linux.c
++++ b/agent/mibgroup/hardware/memory/memory_linux.c
+@@ -46,6 +46,7 @@ int netsnmp_mem_arch_load( netsnmp_cache *cache, void *magic ) {
+ buff = (char*)malloc(bsize+1);
+ if (NULL == buff) {
+ snmp_log(LOG_ERR, "malloc failed\n");
++ close(statfd);
+ return -1;
+ }
+ }
+@@ -53,6 +54,7 @@ int netsnmp_mem_arch_load( netsnmp_cache *cache, void *magic ) {
+ b = (char*)realloc(buff, bsize + MEMINFO_STEP_SIZE + 1);
+ if (NULL == b) {
+ snmp_log(LOG_ERR, "malloc failed\n");
++ close(statfd);
+ return -1;
+ }
+ buff = b;
+@@ -89,13 +91,19 @@ int netsnmp_mem_arch_load( netsnmp_cache *cache, void *magic ) {
+ if (first)
+ snmp_log(LOG_ERR, "No MemFree line in /proc/meminfo\n");
+ }
+- b = strstr(buff, "MemShared: ");
+- if (b)
+- sscanf(b, "MemShared: %lu", &memshared);
++ if (0 == netsnmp_os_prematch("Linux","2.4")) {
++ b = strstr(buff, "MemShared: ");
++ if (b)
++ sscanf(b, "MemShared: %lu", &memshared);
++ else if (first)
++ snmp_log(LOG_ERR, "No MemShared line in /proc/meminfo\n");
++ }
+ else {
+- if (first)
+- if (0 == netsnmp_os_prematch("Linux","2.4"))
+- snmp_log(LOG_ERR, "No MemShared line in /proc/meminfo\n");
++ b = strstr(buff, "Shmem: ");
++ if (b)
++ sscanf(b, "Shmem: %lu", &memshared);
++ else if (first)
++ snmp_log(LOG_ERR, "No Shmem line in /proc/meminfo\n");
+ }
+ b = strstr(buff, "Buffers: ");
+ if (b)
+@@ -155,8 +163,6 @@ int netsnmp_mem_arch_load( netsnmp_cache *cache, void *magic ) {
+ mem->other = -1;
+ }
+
+- /* Shared memory is not reported by Linux 2.6 kernel */
+- if (0 != netsnmp_os_prematch("Linux","2.6")) {
+ mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_SHARED, 1 );
+ if (!mem) {
+ snmp_log_perror("No Shared Memory info entry");
+@@ -165,10 +171,9 @@ int netsnmp_mem_arch_load( netsnmp_cache *cache, void *magic ) {
+ mem->descr = strdup("Shared memory");
+ mem->units = 1024;
+ mem->size = memshared;
+- mem->free = -1;
++ mem->free = 0; /* All in use */
+ mem->other = -1;
+ }
+- }
+
+ mem = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_CACHED, 1 );
+ if (!mem) {
+diff --git a/agent/mibgroup/hardware/sensors/hw_sensors.c b/agent/mibgroup/hardware/sensors/hw_sensors.c
+index 508ad47..1a01645 100644
+--- a/agent/mibgroup/hardware/sensors/hw_sensors.c
++++ b/agent/mibgroup/hardware/sensors/hw_sensors.c
+@@ -163,6 +163,11 @@ sensor_by_name( const char *name, int create_type )
+ */
+ sp = SNMP_MALLOC_TYPEDEF( netsnmp_sensor_info );
+ if ( sp ) {
++ if (strlen(name) >= sizeof(sp->name)) {
++ snmp_log(LOG_ERR, "Sensor name is too large: %s\n", name);
++ free(sp);
++ return NULL;
++ }
+ strcpy( sp->name, name );
+ sp->type = create_type;
+ /*
+diff --git a/agent/mibgroup/hardware/sensors/lmsensors_v3.c b/agent/mibgroup/hardware/sensors/lmsensors_v3.c
+index d33a1c4..e34da19 100644
+--- a/agent/mibgroup/hardware/sensors/lmsensors_v3.c
++++ b/agent/mibgroup/hardware/sensors/lmsensors_v3.c
+@@ -32,7 +32,7 @@ netsnmp_sensor_arch_load(netsnmp_cache *cache, void *vp) {
+
+ while ((data2 = sensors_get_all_subfeatures( chip, data, &b))) {
+ char *label = NULL;
+- double val;
++ double val = 0;
+ int type = NETSNMP_SENSOR_TYPE_OTHER;
+
+ DEBUGMSGTL(("sensors:arch:detail", " get_subfeatures (%s, %d)\n", data2->name, data2->number));
+diff --git a/agent/mibgroup/host/data_access/swinst_apt.c b/agent/mibgroup/host/data_access/swinst_apt.c
+index d204857..26cdba5 100644
+--- a/agent/mibgroup/host/data_access/swinst_apt.c
++++ b/agent/mibgroup/host/data_access/swinst_apt.c
+@@ -37,11 +37,10 @@ static char apt_fmt[SNMP_MAXBUF];
+ void
+ netsnmp_swinst_arch_init(void)
+ {
+- strncpy( pkg_directory, "/var/lib/dpkg/info", SNMP_MAXBUF );
++ strlcpy(pkg_directory, "/var/lib/dpkg/info", sizeof(pkg_directory));
+ snprintf(apt_fmt, SNMP_MAXBUF, "%%%d[^#]#%%%d[^#]#%%%d[^#]#%%%d[^#]#%%%d[^#]#%%%ds",
+ SNMP_MAXBUF, SNMP_MAXBUF, SNMP_MAXBUF,
+ SNMP_MAXBUF, SNMP_MAXBUF, SNMP_MAXBUF);
+- return;
+ }
+
+ void
+@@ -95,7 +94,7 @@ netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags)
+ entry->swDate_len = 8;
+ memcpy(entry->swDate, "\0\0\1\1\0\0\0\0", 8);
+ }
+- fclose(p);
++ pclose(p);
+ DEBUGMSGTL(("swinst:load:arch"," loaded %d entries\n",
+ CONTAINER_SIZE(container)));
+
+diff --git a/agent/mibgroup/host/data_access/swinst_pkginfo.c b/agent/mibgroup/host/data_access/swinst_pkginfo.c
+index 1ca40a2..327ca70 100644
+--- a/agent/mibgroup/host/data_access/swinst_pkginfo.c
++++ b/agent/mibgroup/host/data_access/swinst_pkginfo.c
+@@ -103,7 +103,9 @@ netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags)
+ if there isn't a list of them! */
+ }
+ d = opendir( pkg_directory );
+- while (d != NULL && (dp = readdir(d)) != NULL) {
++ if (!d)
++ return 1;
++ while ((dp = readdir(d)) != NULL) {
+ if ( '.' == dp->d_name[0] )
+ continue;
+ entry = netsnmp_swinst_entry_create( i++ );
+diff --git a/agent/mibgroup/host/data_access/swinst_rpm.c b/agent/mibgroup/host/data_access/swinst_rpm.c
+index a2862e0..71595be 100644
+--- a/agent/mibgroup/host/data_access/swinst_rpm.c
++++ b/agent/mibgroup/host/data_access/swinst_rpm.c
+@@ -100,7 +100,7 @@ netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags)
+ int32_t *t;
+ time_t install_time;
+ size_t date_len;
+- int rc, i = 1;
++ int i = 1;
+ netsnmp_swinst_entry *entry;
+
+ ts = rpmtsCreate();
+@@ -112,11 +112,11 @@ netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags)
+
+ while (NULL != (h = rpmdbNextIterator( mi )))
+ {
+-
++ const u_char *dt;
+ entry = netsnmp_swinst_entry_create( i++ );
+ if (NULL == entry)
+ continue; /* error already logged by function */
+- rc = CONTAINER_INSERT(container, entry);
++ CONTAINER_INSERT(container, entry);
+
+ h = headerLink( h );
+ headerGetEntry( h, RPMTAG_NAME, NULL, (void**)&n, NULL);
+@@ -134,8 +134,15 @@ netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags)
+ : 4; /* application */
+
+ install_time = *t;
+- entry->swDate_len = snprintf( entry->swDate, sizeof(entry->swDate),
+- "%s", date_n_time( &install_time, &date_len ));
++ dt = date_n_time( &install_time, &date_len );
++ if (date_len != 8 && date_len != 11) {
++ snmp_log(LOG_ERR, "Bogus length from date_n_time for %s", entry->swName);
++ entry->swDate_len = 0;
++ }
++ else {
++ entry->swDate_len = date_len;
++ memcpy(entry->swDate, dt, entry->swDate_len);
++ }
+
+ headerFree( h );
+ }
+diff --git a/agent/mibgroup/host/data_access/swrun_darwin.c b/agent/mibgroup/host/data_access/swrun_darwin.c
+index 7d07cd5..6c6b82a 100644
+--- a/agent/mibgroup/host/data_access/swrun_darwin.c
++++ b/agent/mibgroup/host/data_access/swrun_darwin.c
+@@ -289,8 +289,7 @@ _set_command_name_jaguar(netsnmp_swrun_entry *entry)
+ exec_path = (char *)ip;
+ DEBUGMSGTL(("swrun:load:arch:_cn"," exec_path %s\n", exec_path));
+ len = strlen(exec_path);
+- strncpy(entry->hrSWRunPath, exec_path, sizeof(entry->hrSWRunPath)-1);
+- entry->hrSWRunPath[sizeof(entry->hrSWRunPath)-1] = 0;
++ strlcpy(entry->hrSWRunPath, exec_path, sizeof(entry->hrSWRunPath));
+ if (len > sizeof(entry->hrSWRunPath)-1) {
+ DEBUGMSGTL(("swrun:load:arch:_cn"," truncating long run path\n"));
+ entry->hrSWRunPath[sizeof(entry->hrSWRunPath)-2] = '$';
+@@ -326,8 +325,7 @@ _set_command_name_jaguar(netsnmp_swrun_entry *entry)
+ DEBUGMSGTL(("swrun:load:arch:_cn",
+ SWRUNINDENT "kernel name %s\n", command));
+ if (strncmp(command, entry->hrSWRunName, sizeof(entry->hrSWRunName)-1)) {
+- strncpy(entry->hrSWRunName, command, sizeof(entry->hrSWRunName)-1);
+- entry->hrSWRunName[sizeof(entry->hrSWRunName)-1] = 0;
++ strlcpy(entry->hrSWRunName, command, sizeof(entry->hrSWRunName));
+ entry->hrSWRunName_len = strlen(entry->hrSWRunName);
+ DEBUGMSGTL(("swrun:load:arch:_cn", "**"
+ SWRUNINDENT "updated name to %s\n", entry->hrSWRunName));
+@@ -369,8 +367,7 @@ _set_command_name(netsnmp_swrun_entry *entry)
+
+ exec_path = arg_buf + sizeof(nargs);
+ len = strlen(exec_path);
+- strncpy(entry->hrSWRunPath, exec_path, sizeof(entry->hrSWRunPath)-1);
+- entry->hrSWRunPath[sizeof(entry->hrSWRunPath)-1] = 0;
++ strlcpy(entry->hrSWRunPath, exec_path, sizeof(entry->hrSWRunPath));
+ if (len > sizeof(entry->hrSWRunPath)-1) {
+ DEBUGMSGTL(("swrun:load:arch:_cn"," truncating long run path\n"));
+ entry->hrSWRunPath[sizeof(entry->hrSWRunPath)-2] = '$';
+@@ -459,8 +456,8 @@ _set_command_name(netsnmp_swrun_entry *entry)
+ * save arg
+ */
+ if(entry->hrSWRunParameters_len < sizeof(entry->hrSWRunParameters)-1) {
+- strncat(&entry->hrSWRunParameters[entry->hrSWRunParameters_len], argN,
+- sizeof(entry->hrSWRunParameters) - entry->hrSWRunParameters_len - 2);
++ strlcat(&entry->hrSWRunParameters[entry->hrSWRunParameters_len],
++ argN, sizeof(entry->hrSWRunParameters));
+ entry->hrSWRunParameters_len = strlen(entry->hrSWRunParameters);
+ if ((entry->hrSWRunParameters_len+2 < sizeof(entry->hrSWRunParameters)-1) && (0 != nargs)) {
+ /* add space between params */
+@@ -486,8 +483,7 @@ _set_command_name(netsnmp_swrun_entry *entry)
+
+ /* Allocate space for the command and copy. */
+ if (strncmp(command, entry->hrSWRunName, sizeof(entry->hrSWRunName)-1)) {
+- strncpy(entry->hrSWRunName, command, sizeof(entry->hrSWRunName)-1);
+- entry->hrSWRunName[sizeof(entry->hrSWRunName)-1] = 0;
++ strlcpy(entry->hrSWRunName, command, sizeof(entry->hrSWRunName));
+ entry->hrSWRunName_len = strlen(entry->hrSWRunName);
+ DEBUGMSGTL(("swrun:load:arch:_cn",
+ " **updated name to %s\n", entry->hrSWRunName));
+diff --git a/agent/mibgroup/host/data_access/swrun_kinfo.c b/agent/mibgroup/host/data_access/swrun_kinfo.c
+index aae5f62..64583bf 100644
+--- a/agent/mibgroup/host/data_access/swrun_kinfo.c
++++ b/agent/mibgroup/host/data_access/swrun_kinfo.c
+@@ -236,7 +236,7 @@ netsnmp_arch_swrun_container_load( netsnmp_container *container, u_int flags)
+ : 4 /* application */
+ ;
+
+-#ifdef netbsdelf5
++#ifdef netbsd5
+ switch (proc_table[i].SWRUN_K_STAT) {
+ case LSONPROC:
+ case LSRUN: entry->hrSWRunStatus = HRSWRUNSTATUS_RUNNING;
+diff --git a/agent/mibgroup/host/data_access/swrun_procfs_status.c b/agent/mibgroup/host/data_access/swrun_procfs_status.c
+index 367f422..a9aa2d8 100644
+--- a/agent/mibgroup/host/data_access/swrun_procfs_status.c
++++ b/agent/mibgroup/host/data_access/swrun_procfs_status.c
+@@ -123,32 +123,26 @@ netsnmp_arch_swrun_container_load( netsnmp_container *container, u_int flags)
+ }
+ fclose(fp);
+
+- if ( cp ) {
+- /*
+- * argv[0] is hrSWRunPath
+- */
+- entry->hrSWRunPath_len = snprintf(entry->hrSWRunPath,
+- sizeof(entry->hrSWRunPath)-1, "%s", buf);
+- /*
+- * Stitch together argv[1..] to construct hrSWRunParameters
+- */
+- cp = buf + entry->hrSWRunPath_len+1;
+- while ( 1 ) {
+- while (*cp)
+- cp++;
+- if ( '\0' == *(cp+1))
+- break; /* '\0''\0' => End of command line */
+- *cp = ' ';
+- }
+- entry->hrSWRunParameters_len
+- = sprintf(entry->hrSWRunParameters, "%.*s",
+- (int)sizeof(entry->hrSWRunParameters) - 1,
+- buf + entry->hrSWRunPath_len + 1);
+- } else {
+- memcpy(entry->hrSWRunPath, entry->hrSWRunName, entry->hrSWRunName_len);
+- entry->hrSWRunPath_len = entry->hrSWRunName_len;
+- entry->hrSWRunParameters_len = 0;
++ /*
++ * argv[0] is hrSWRunPath
++ */
++ entry->hrSWRunPath_len = snprintf(entry->hrSWRunPath,
++ sizeof(entry->hrSWRunPath)-1, "%s", buf);
++ /*
++ * Stitch together argv[1..] to construct hrSWRunParameters
++ */
++ cp = buf + entry->hrSWRunPath_len+1;
++ while ( 1 ) {
++ while (*cp)
++ cp++;
++ if ( '\0' == *(cp+1))
++ break; /* '\0''\0' => End of command line */
++ *cp = ' ';
+ }
++ entry->hrSWRunParameters_len
++ = sprintf(entry->hrSWRunParameters, "%.*s",
++ (int)sizeof(entry->hrSWRunParameters) - 1,
++ buf + entry->hrSWRunPath_len + 1);
+
+ /*
+ * XXX - No information regarding system processes vs applications
+diff --git a/agent/mibgroup/host/hrSWInstalledTable.c b/agent/mibgroup/host/hrSWInstalledTable.c
+index 71d2a38..ad8aee3 100644
+--- a/agent/mibgroup/host/hrSWInstalledTable.c
++++ b/agent/mibgroup/host/hrSWInstalledTable.c
+@@ -143,6 +143,7 @@ initialize_table_hrSWInstalledTable(void)
+ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
+ snmp_log(LOG_ERR,"error registering table handler for "
+ MYTABLE "\n");
++ reg = NULL; /* it was freed inside netsnmp_register_table */
+ goto bail;
+ }
+
+diff --git a/agent/mibgroup/host/hrSWRunPerfTable.c b/agent/mibgroup/host/hrSWRunPerfTable.c
+index 7a9adfa..43b44d1 100644
+--- a/agent/mibgroup/host/hrSWRunPerfTable.c
++++ b/agent/mibgroup/host/hrSWRunPerfTable.c
+@@ -115,6 +115,7 @@ initialize_table_hrSWRunPerfTable(void)
+ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
+ snmp_log(LOG_ERR,"error registering table handler for "
+ MYTABLE "\n");
++ reg = NULL; /* it was freed inside netsnmp_register_table */
+ goto bail;
+ }
+
+diff --git a/agent/mibgroup/host/hrSWRunTable.c b/agent/mibgroup/host/hrSWRunTable.c
+index 946813e..03ad256 100644
+--- a/agent/mibgroup/host/hrSWRunTable.c
++++ b/agent/mibgroup/host/hrSWRunTable.c
+@@ -128,6 +128,7 @@ initialize_table_hrSWRunTable(void)
+ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
+ snmp_log(LOG_ERR,"error registering table handler for "
+ MYTABLE "\n");
++ reg = NULL; /* it was freed inside netsnmp_register_table */
+ goto bail;
+ }
+
+diff --git a/agent/mibgroup/host/hr_device.c b/agent/mibgroup/host/hr_device.c
+index c2e112c..24031bf 100644
+--- a/agent/mibgroup/host/hr_device.c
++++ b/agent/mibgroup/host/hr_device.c
+@@ -250,8 +250,7 @@ really_try_next:
+ case HRDEV_DESCR:
+ if ((device_descr[type] != NULL) &&
+ (NULL!=(tmp_str=((*device_descr[type])(dev_idx))))) {
+- strncpy(string, tmp_str, sizeof(string)-1);
+- string[ sizeof(string)-1] = 0;
++ strlcpy(string, tmp_str, sizeof(string));
+ } else
+ #if NETSNMP_NO_DUMMY_VALUES
+ goto try_next;
+diff --git a/agent/mibgroup/host/hr_disk.c b/agent/mibgroup/host/hr_disk.c
+index d8f874f..679264b 100644
+--- a/agent/mibgroup/host/hr_disk.c
++++ b/agent/mibgroup/host/hr_disk.c
+@@ -355,7 +355,7 @@ parse_disk_config(const char *token, char *cptr)
+ di_curr->item_details = (void *) 0;
+ name++;
+ } else if (*name == '[') {
+- d_set = (details_set *) malloc(sizeof(details_set));
++ d_set = (details_set *) calloc(sizeof(details_set), 1);
+ if (!d_set) {
+ config_perror("Out of memory");
+ SNMP_FREE(d_new);
+@@ -364,8 +364,6 @@ parse_disk_config(const char *token, char *cptr)
+ SNMP_FREE(d_str);
+ return;
+ }
+- for (i = 0; i < sizeof(details_set); i++)
+- (*d_set)[i] = (unsigned char) 0;
+ name++;
+ if (*name == '^' || *name == '!') {
+ neg = 1;
+@@ -904,16 +902,14 @@ Get_HR_Disk_Label(char *string, size_t str_len, const char *devfull)
+
+ sess_ref = DASessionCreate( NULL );
+ if (NULL == sess_ref) {
+- strncpy(string, devfull, str_len);
+- string[str_len-1] = 0;
++ strlcpy(string, devfull, str_len);
+ return -1;
+ }
+
+ disk = DADiskCreateFromBSDName( NULL, sess_ref, devfull );
+ if (NULL == disk) {
+ CFRelease(sess_ref);
+- strncpy(string, devfull, str_len);
+- string[str_len-1] = 0;
++ strlcpy(string, devfull, str_len);
+ return -1;
+ }
+
+@@ -924,7 +920,7 @@ Get_HR_Disk_Label(char *string, size_t str_len, const char *devfull)
+ devfull);
+ CFRelease(disk);
+ CFRelease(sess_ref);
+- strncpy(string, devfull, str_len);
++ strlcpy(string, devfull, str_len);
+ return -1;
+ }
+
+@@ -932,14 +928,12 @@ Get_HR_Disk_Label(char *string, size_t str_len, const char *devfull)
+ str_ref = (CFStringRef)
+ CFDictionaryGetValue(desc, kDADiskDescriptionMediaNameKey);
+ if (str_ref) {
+- strncpy(string, CFStringGetCStringPtr(str_ref, sys_encoding),
++ strlcpy(string, CFStringGetCStringPtr(str_ref, sys_encoding),
+ str_len);
+- string[str_len-1] = 0;
+ DEBUGMSGTL(("verbose:diskmgr:darwin", " name %s\n", string));
+ }
+ else {
+- strncpy(string, devfull, str_len);
+- string[str_len-1] = 0;
++ strlcpy(string, devfull, str_len);
+ }
+
+ CFRelease(disk);
+@@ -984,27 +978,21 @@ static void
+ Save_HR_Disk_General(void)
+ {
+ #ifdef DIOC_DESCRIBE
+- strncpy(HRD_savedModel, HRD_info.model_num, sizeof(HRD_savedModel)-1);
+- HRD_savedModel[ sizeof(HRD_savedModel)-1 ] = 0;
++ strlcpy(HRD_savedModel, HRD_info.model_num, sizeof(HRD_savedModel));
+ #endif
+ #ifdef DKIOCINFO
+- strncpy(HRD_savedModel, HRD_info.dki_dname, sizeof(HRD_savedModel)-1);
+- HRD_savedModel[ sizeof(HRD_savedModel)-1 ] = 0;
++ strlcpy(HRD_savedModel, HRD_info.dki_dname, sizeof(HRD_savedModel));
+ #endif
+ #ifdef HAVE_LINUX_HDREG_H
+- strncpy(HRD_savedModel, (const char *) HRD_info.model,
+- sizeof(HRD_savedModel)-1);
+- HRD_savedModel[ sizeof(HRD_savedModel)-1 ] = 0;
++ strlcpy(HRD_savedModel, (const char *) HRD_info.model,
++ sizeof(HRD_savedModel));
+ #endif
+ #ifdef DIOCGDINFO
+- strncpy(HRD_savedModel, dktypenames[HRD_info.d_type],
+- sizeof(HRD_savedModel)-1);
+- HRD_savedModel[ sizeof(HRD_savedModel)-1 ] = 0;
++ strlcpy(HRD_savedModel, dktypenames[HRD_info.d_type],
++ sizeof(HRD_savedModel));
+ #endif
+ #ifdef darwin
+- strncpy(HRD_savedModel, HRD_model,
+- sizeof(HRD_savedModel)-1);
+- HRD_savedModel[ sizeof(HRD_savedModel)-1 ] = 0;
++ strlcpy(HRD_savedModel, HRD_model, sizeof(HRD_savedModel));
+ #endif
+ }
+
+@@ -1149,9 +1137,8 @@ Query_Disk(int fd, const char *devfull)
+ str_ref = (CFStringRef)
+ CFDictionaryGetValue(desc, kDADiskDescriptionDeviceModelKey);
+ if (str_ref) {
+- strncpy(HRD_model, CFStringGetCStringPtr(str_ref, sys_encoding),
++ strlcpy(HRD_model, CFStringGetCStringPtr(str_ref, sys_encoding),
+ sizeof(HRD_model));
+- HRD_savedModel[ sizeof(HRD_savedModel)-1 ] = 0;
+ DEBUGMSGTL(("verbose:diskmgr:darwin", " model %s\n", HRD_model));
+ }
+ else
+diff --git a/agent/mibgroup/host/hr_filesys.c b/agent/mibgroup/host/hr_filesys.c
+index 660e706..b23d322 100644
+--- a/agent/mibgroup/host/hr_filesys.c
++++ b/agent/mibgroup/host/hr_filesys.c
+@@ -361,15 +361,13 @@ var_hrfilesys(struct variable *vp,
+ long_return = fsys_idx;
+ return (u_char *) & long_return;
+ case HRFSYS_MOUNT:
+- snprintf(string, sizeof(string), "%s", HRFS_entry->HRFS_mount);
+- string[ sizeof(string)-1 ] = 0;
++ strlcpy(string, HRFS_entry->HRFS_mount, sizeof(string));
+ *var_len = strlen(string);
+ return (u_char *) string;
+ case HRFSYS_RMOUNT:
+- if (Check_HR_FileSys_NFS()) {
+- snprintf(string, sizeof(string), "%s", HRFS_entry->HRFS_name);
+- string[ sizeof(string)-1 ] = 0;
+- } else
++ if (Check_HR_FileSys_NFS())
++ strlcpy(string, HRFS_entry->HRFS_name, sizeof(string));
++ else
+ string[0] = '\0';
+ *var_len = strlen(string);
+ return (u_char *) string;
+@@ -945,17 +943,14 @@ cook_device(char *dev)
+ static char cooked_dev[SNMP_MAXPATH+1];
+
+ if (!strncmp(dev, RAW_DEVICE_PREFIX, strlen(RAW_DEVICE_PREFIX))) {
+- strncpy(cooked_dev, COOKED_DEVICE_PREFIX, sizeof(cooked_dev)-1);
+- cooked_dev[ sizeof(cooked_dev)-1 ] = 0;
+- strncat(cooked_dev, dev + strlen(RAW_DEVICE_PREFIX),
+- sizeof(cooked_dev)-strlen(cooked_dev)-1);
+- cooked_dev[ sizeof(cooked_dev)-1 ] = 0;
++ strlcpy(cooked_dev, COOKED_DEVICE_PREFIX, sizeof(cooked_dev));
++ strlcat(cooked_dev, dev + strlen(RAW_DEVICE_PREFIX),
++ sizeof(cooked_dev));
+ } else {
+- strncpy(cooked_dev, dev, sizeof(cooked_dev)-1);
+- cooked_dev[ sizeof(cooked_dev)-1 ] = 0;
++ strlcpy(cooked_dev, dev, sizeof(cooked_dev));
+ }
+
+- return (cooked_dev);
++ return cooked_dev;
+ }
+
+
+diff --git a/agent/mibgroup/host/hr_proc.c b/agent/mibgroup/host/hr_proc.c
+index 9d44c7b..6f93079 100644
+--- a/agent/mibgroup/host/hr_proc.c
++++ b/agent/mibgroup/host/hr_proc.c
+@@ -164,6 +164,7 @@ var_hrproc(struct variable * vp,
+ int exact, size_t * var_len, WriteMethod ** write_method)
+ {
+ int proc_idx;
++ unsigned long long value;
+ netsnmp_cpu_info *cpu;
+
+ proc_idx =
+@@ -181,9 +182,9 @@ var_hrproc(struct variable * vp,
+ ( cpu->history[0].total_hist == cpu->total_ticks ))
+ return NULL;
+
+- long_return = (cpu->idle_ticks - cpu->history[0].idle_hist)*100;
+- long_return /= (cpu->total_ticks - cpu->history[0].total_hist);
+- long_return = 100 - long_return;
++ value = (cpu->idle_ticks - cpu->history[0].idle_hist)*100;
++ value /= (cpu->total_ticks - cpu->history[0].total_hist);
++ long_return = 100 - value;
+ if (long_return < 0)
+ long_return = 0;
+ return (u_char *) & long_return;
+diff --git a/agent/mibgroup/host/hr_storage.c b/agent/mibgroup/host/hr_storage.c
+index 4b8ba8a..264fecc 100644
+--- a/agent/mibgroup/host/hr_storage.c
++++ b/agent/mibgroup/host/hr_storage.c
+@@ -595,8 +595,7 @@ really_try_next:
+ return (u_char *) storage_type_id;
+ case HRSTORE_DESCR:
+ if (store_idx > NETSNMP_MEM_TYPE_MAX) {
+- strncpy(string, HRFS_entry->HRFS_mount, sizeof(string)-1);
+- string[ sizeof(string)-1 ] = 0;
++ strlcpy(string, HRFS_entry->HRFS_mount, sizeof(string));
+ *var_len = strlen(string);
+ return (u_char *) string;
+ } else {
+diff --git a/agent/mibgroup/host/hr_swinst.c b/agent/mibgroup/host/hr_swinst.c
+index 91c660c..4aa4593 100644
+--- a/agent/mibgroup/host/hr_swinst.c
++++ b/agent/mibgroup/host/hr_swinst.c
+@@ -405,10 +405,8 @@ var_hrswinst(struct variable * vp,
+ case HRSWINST_UPDATE:
+ string[0] = '\0';
+
+- if (swi->swi_directory != NULL) {
+- strncpy(string, swi->swi_directory, sizeof(string));
+- string[ sizeof(string)-1 ] = 0;
+- }
++ if (swi->swi_directory != NULL)
++ strlcpy(string, swi->swi_directory, sizeof(string));
+
+ if (*string && (stat(string, &stat_buf) != -1)) {
+ if (stat_buf.st_mtime > starttime.tv_sec)
+@@ -436,7 +434,7 @@ var_hrswinst(struct variable * vp,
+ #ifdef HAVE_PKGINFO
+ char *pver;
+ # endif
+- strncpy(string, swi->swi_name, sizeof(string) - 1);
++ strlcpy(string, swi->swi_name, sizeof(string));
+
+ /* If we are on a solaris machine, the package names do not include versioning info,
+ * so we must add it manually
+diff --git a/agent/mibgroup/host/hr_swrun.c b/agent/mibgroup/host/hr_swrun.c
+index 9e11f2e..644e7bd 100644
+--- a/agent/mibgroup/host/hr_swrun.c
++++ b/agent/mibgroup/host/hr_swrun.c
+@@ -657,14 +657,12 @@ var_hrswrun(struct variable * vp,
+ return (u_char *) & long_return;
+ case HRSWRUN_NAME:
+ #ifdef HAVE_SYS_PSTAT_H
+- snprintf(string, sizeof(string), "%s", proc_buf.pst_cmd);
+- string[ sizeof(string)-1 ] = 0;
++ strlcpy(string, proc_buf.pst_cmd, sizeof(string));
+ cp = strchr(string, ' ');
+ if (cp != NULL)
+ *cp = '\0';
+ #elif defined(dynix)
+- snprintf(string, sizeof(string), "%s", lowpsinfo.pr_fname);
+- string[ sizeof(string)-1 ] = 0;
++ strlcpy(string, lowpsinfo.pr_fname, sizeof(string));
+ cp = strchr(string, ' ');
+ if (cp != NULL)
+ *cp = '\0';
+@@ -673,19 +671,16 @@ var_hrswrun(struct variable * vp,
+ if (proc_buf) {
+ char *pos=strchr(proc_buf->pr_psargs,' ');
+ if (pos != NULL) *pos = '\0';
+- strlcpy(string, basename(proc_buf->pr_psargs),sizeof(string));
++ strlcpy(string, basename(proc_buf->pr_psargs), sizeof(string));
+ if (pos != NULL) *pos=' ';
+ } else {
+- strcpy(string, "<exited>");
++ strlcpy(string, "<exited>", sizeof(string));
+ }
+- string[ sizeof(string)-1 ] = 0;
+ #else
+- strncpy(string, proc_buf->p_user.u_comm, sizeof(string));
+- string[ sizeof(string)-1 ] = 0;
++ strlcpy(string, proc_buf->p_user.u_comm, sizeof(string));
+ #endif
+ #elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
+- strncpy(string, proc_table[LowProcIndex].pi_comm, sizeof(string));
+- string[ sizeof(string)-1 ] = 0;
++ strlcpy(string, proc_table[LowProcIndex].pi_comm, sizeof(string));
+ cp = strchr(string, ' ');
+ if (cp != NULL)
+ *cp = '\0';
+@@ -806,8 +801,7 @@ var_hrswrun(struct variable * vp,
+ *cp1 = 0;
+ #endif
+ #elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
+- strncpy(string, proc_table[LowProcIndex].pi_comm, sizeof(string));
+- string[ sizeof(string)-1 ] = 0;
++ strlcpy(string, proc_table[LowProcIndex].pi_comm, sizeof(string));
+ cp = strchr(string, ' ');
+ if (cp != NULL)
+ *cp = '\0';
+diff --git a/agent/mibgroup/host/hr_system.c b/agent/mibgroup/host/hr_system.c
+index da38c74..9fea4f4 100644
+--- a/agent/mibgroup/host/hr_system.c
++++ b/agent/mibgroup/host/hr_system.c
+@@ -469,9 +469,7 @@ static int set_solaris_eeprom_parameter(const char *key, const char *value,
+ }
+
+
+- sprintf(pbuffer,"eeprom %s=\"",key);
+- strncat(pbuffer,value,var_val_len);
+- strcat(pbuffer,"\"\n");
++ sprintf(pbuffer, "eeprom %s=\"%.*s\"\n", key, var_val_len, value);
+
+ status=system(pbuffer);
+
+diff --git a/agent/mibgroup/host/hrh_filesys.c b/agent/mibgroup/host/hrh_filesys.c
+index fd84bde..4aab6a0 100644
+--- a/agent/mibgroup/host/hrh_filesys.c
++++ b/agent/mibgroup/host/hrh_filesys.c
+@@ -350,13 +350,13 @@ when_dumped(char *filesys, int level, size_t * length)
+ continue;
+
+ ++cp2;
+- while (isspace(*cp2))
++ while (isspace(0xFF & *cp2))
+ ++cp2; /* Now find the dump level */
+
+ if (level == FULL_DUMP) {
+ if (*(cp2++) != '0')
+ continue; /* Not interested in partial dumps */
+- while (isspace(*cp2))
++ while (isspace(0xFF & *cp2))
+ ++cp2;
+
+ dumpdate = ctime_to_timet(cp2);
+@@ -365,7 +365,7 @@ when_dumped(char *filesys, int level, size_t * length)
+ } else { /* Partial Dump */
+ if (*(cp2++) == '0')
+ continue; /* Not interested in full dumps */
+- while (isspace(*cp2))
++ while (isspace(0xFF & *cp2))
+ ++cp2;
+
+ tmp = ctime_to_timet(cp2);
+@@ -390,17 +390,14 @@ cook_device(char *dev)
+ static char cooked_dev[SNMP_MAXPATH+1];
+
+ if (!strncmp(dev, RAW_DEVICE_PREFIX, strlen(RAW_DEVICE_PREFIX))) {
+- strncpy(cooked_dev, COOKED_DEVICE_PREFIX, sizeof(cooked_dev)-1);
+- cooked_dev[ sizeof(cooked_dev)-1 ] = 0;
+- strncat(cooked_dev, dev + strlen(RAW_DEVICE_PREFIX),
+- sizeof(cooked_dev)-strlen(cooked_dev)-1);
+- cooked_dev[ sizeof(cooked_dev)-1 ] = 0;
++ strlcpy(cooked_dev, COOKED_DEVICE_PREFIX, sizeof(cooked_dev));
++ strlcat(cooked_dev, dev + strlen(RAW_DEVICE_PREFIX),
++ sizeof(cooked_dev));
+ } else {
+- strncpy(cooked_dev, dev, sizeof(cooked_dev)-1);
+- cooked_dev[ sizeof(cooked_dev)-1 ] = 0;
++ strlcpy(cooked_dev, dev, sizeof(cooked_dev));
+ }
+
+- return (cooked_dev);
++ return cooked_dev;
+ }
+
+
+diff --git a/agent/mibgroup/host/hrh_storage.c b/agent/mibgroup/host/hrh_storage.c
+index 27841a4..ca2f854 100644
+--- a/agent/mibgroup/host/hrh_storage.c
++++ b/agent/mibgroup/host/hrh_storage.c
+@@ -408,8 +408,7 @@ really_try_next:
+ return (u_char *) storage_type_id;
+ case HRSTORE_DESCR:
+ if (store_idx > NETSNMP_MEM_TYPE_MAX) {
+- strncpy(string, HRFS_entry->path, sizeof(string)-1);
+- string[ sizeof(string)-1 ] = 0;
++ strlcpy(string, HRFS_entry->path, sizeof(string));
+ *var_len = strlen(string);
+ return (u_char *) string;
+ } else {
+diff --git a/agent/mibgroup/if-mib/data_access/interface_ioctl.c b/agent/mibgroup/if-mib/data_access/interface_ioctl.c
+index 66aec99..db2c245 100644
+--- a/agent/mibgroup/if-mib/data_access/interface_ioctl.c
++++ b/agent/mibgroup/if-mib/data_access/interface_ioctl.c
+@@ -70,8 +70,7 @@ _ioctl_get(int fd, int which, struct ifreq *ifrq, const char* name)
+ }
+ }
+
+- strncpy(ifrq->ifr_name, name, sizeof(ifrq->ifr_name));
+- ifrq->ifr_name[ sizeof(ifrq->ifr_name)-1 ] = 0;
++ strlcpy(ifrq->ifr_name, name, sizeof(ifrq->ifr_name));
+ rc = ioctl(fd, which, ifrq);
+ if (rc < 0) {
+ snmp_log(LOG_ERR,"ioctl %d returned %d\n", which, rc);
+@@ -157,6 +156,11 @@ netsnmp_access_interface_ioctl_physaddr_get(int fd,
+ ifentry->type = IANAIFTYPE_TUNNEL;
+ break; /* tunnel */
+ #endif
++#ifdef ARPHRD_INFINIBAND
++ case ARPHRD_INFINIBAND:
++ ifentry->type = IANAIFTYPE_INFINIBAND;
++ break;
++#endif
+ #ifdef ARPHRD_SLIP
+ case ARPHRD_SLIP:
+ case ARPHRD_CSLIP:
+@@ -323,8 +327,7 @@ netsnmp_access_interface_ioctl_flags_set(int fd,
+ }
+ }
+
+- strncpy(ifrq.ifr_name, ifentry->name, sizeof(ifrq.ifr_name));
+- ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
++ strlcpy(ifrq.ifr_name, ifentry->name, sizeof(ifrq.ifr_name));
+ rc = ioctl(fd, SIOCGIFFLAGS, &ifrq);
+ if(rc < 0) {
+ snmp_log(LOG_ERR,"error getting flags\n");
+diff --git a/agent/mibgroup/if-mib/data_access/interface_linux.c b/agent/mibgroup/if-mib/data_access/interface_linux.c
+index 9810b15..e291b9f 100644
+--- a/agent/mibgroup/if-mib/data_access/interface_linux.c
++++ b/agent/mibgroup/if-mib/data_access/interface_linux.c
+@@ -589,6 +589,7 @@ netsnmp_arch_interface_container_load(netsnmp_container* container,
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if(fd < 0) {
+ snmp_log(LOG_ERR, "could not create socket\n");
++ fclose(devin);
+ return -2;
+ }
+
+@@ -727,6 +728,7 @@ netsnmp_arch_interface_container_load(netsnmp_container* container,
+ {IANAIFTYPE_ISO88025TOKENRING, "tr"},
+ {IANAIFTYPE_FASTETHER, "feth"},
+ {IANAIFTYPE_GIGABITETHERNET,"gig"},
++ {IANAIFTYPE_INFINIBAND,"ib"},
+ {IANAIFTYPE_PPP, "ppp"},
+ {IANAIFTYPE_SLIP, "sl"},
+ {IANAIFTYPE_TUNNEL, "sit"},
+@@ -891,40 +893,38 @@ unsigned long long
+ netsnmp_linux_interface_get_if_speed(int fd, const char *name,
+ unsigned long long defaultspeed)
+ {
++ int ret;
+ struct ifreq ifr;
+ struct ethtool_cmd edata;
++ uint16_t speed_hi;
++ uint32_t speed;
+
+ memset(&ifr, 0, sizeof(ifr));
++ memset(&edata, 0, sizeof(edata));
+ edata.cmd = ETHTOOL_GSET;
+- edata.speed = 0;
+
+- strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)-1);
++ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ ifr.ifr_data = (char *) &edata;
+
+- if (ioctl(fd, SIOCETHTOOL, &ifr) == -1) {
+- DEBUGMSGTL(("mibII/interfaces", "ETHTOOL_GSET on %s failed\n",
+- ifr.ifr_name));
+- return netsnmp_linux_interface_get_if_speed_mii(fd,name,defaultspeed);
+- }
+-
+- if (edata.speed != SPEED_10 && edata.speed != SPEED_100
+-#ifdef SPEED_10000
+- && edata.speed != SPEED_10000
+-#endif
+-#ifdef SPEED_2500
+- && edata.speed != SPEED_2500
+-#endif
+- && edata.speed != SPEED_1000 ) {
+- DEBUGMSGTL(("mibII/interfaces", "fallback to mii for %s\n",
+- ifr.ifr_name));
+- /* try MII */
++ ret = ioctl(fd, SIOCETHTOOL, &ifr);
++ if (ret == -1 || edata.speed == 0) {
++ DEBUGMSGTL(("mibII/interfaces", "ETHTOOL_GSET on %s failed (%d / %d)\n",
++ ifr.ifr_name, ret, edata.speed));
+ return netsnmp_linux_interface_get_if_speed_mii(fd,name,defaultspeed);
+ }
+
++#ifdef HAVE_STRUCT_ETHTOOL_CMD_SPEED_HI
++ speed_hi = edata.speed_hi;
++#else
++ speed_hi = 0;
++#endif
++ speed = speed_hi << 16 | edata.speed;
++ if (speed == 0xffff || speed == 0xffffffffUL /*SPEED_UNKNOWN*/)
++ speed = defaultspeed;
+ /* return in bps */
+- DEBUGMSGTL(("mibII/interfaces", "ETHTOOL_GSET on %s speed = %d\n",
+- ifr.ifr_name, edata.speed));
+- return edata.speed*1000LL*1000LL;
++ DEBUGMSGTL(("mibII/interfaces", "ETHTOOL_GSET on %s speed = %#x -> %d\n",
++ ifr.ifr_name, speed_hi << 16 | edata.speed, speed));
++ return speed * 1000LL * 1000LL;
+ }
+ #endif
+
+@@ -954,8 +954,7 @@ netsnmp_linux_interface_get_if_speed(int fd, const char *name,
+ const unsigned long long media_speeds[] = {10000000, 10000000, 100000000, 100000000, 10000000, 0};
+ /* It corresponds to "10baseT", "10baseT-FD", "100baseTx", "100baseTx-FD", "100baseT4", "Flow-control", 0, */
+
+- strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+- ifr.ifr_name[ sizeof(ifr.ifr_name)-1 ] = 0;
++ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ data[0] = 0;
+
+ /*
+@@ -1042,6 +1041,10 @@ int netsnmp_prefix_listen()
+ unsigned groups = 0;
+
+ int fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
++ if (fd < 0) {
++ snmp_log(LOG_ERR, "netsnmp_prefix_listen: Cannot create socket.\n");
++ return -1;
++ }
+
+ memset(&localaddrinfo, 0, sizeof(struct sockaddr_nl));
+
+@@ -1052,6 +1055,7 @@ int netsnmp_prefix_listen()
+
+ if (bind(fd, (struct sockaddr*)&localaddrinfo, sizeof(localaddrinfo)) < 0) {
+ snmp_log(LOG_ERR,"netsnmp_prefix_listen: Bind failed.\n");
++ close(fd);
+ return -1;
+ }
+
+@@ -1066,11 +1070,13 @@ int netsnmp_prefix_listen()
+ status = send(fd, &req, req.n.nlmsg_len, 0);
+ if (status < 0) {
+ snmp_log(LOG_ERR,"netsnmp_prefix_listen: send failed\n");
++ close(fd);
+ return -1;
+ }
+
+ if (register_readfd(fd, netsnmp_prefix_process, NULL) != 0) {
+ snmp_log(LOG_ERR,"netsnmp_prefix_listen: error registering netlink socket\n");
++ close(fd);
+ return -1;
+ }
+ return 0;
+diff --git a/agent/mibgroup/if-mib/data_access/interface_openbsd.c b/agent/mibgroup/if-mib/data_access/interface_openbsd.c
+index 552043a..8340dc6 100644
+--- a/agent/mibgroup/if-mib/data_access/interface_openbsd.c
++++ b/agent/mibgroup/if-mib/data_access/interface_openbsd.c
+@@ -343,12 +343,10 @@ netsnmp_openbsd_interface_get_if_speed(char *name, u_int *speed, u_int *speed_hi
+ return 0;
+ }
+
+- (void) memset(&ifmr, 0, sizeof(ifmr));
+- (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
+-
+- if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0 ||
+- ifmr.ifm_count == 0) {
++ memset(&ifmr, 0, sizeof(ifmr));
++ strlcpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
+
++ if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0 || ifmr.ifm_count == 0) {
+ close(s);
+ return 0;
+ }
+diff --git a/agent/mibgroup/if-mib/data_access/interface_sysctl.c b/agent/mibgroup/if-mib/data_access/interface_sysctl.c
+index 0669ffc..81efbef 100644
+--- a/agent/mibgroup/if-mib/data_access/interface_sysctl.c
++++ b/agent/mibgroup/if-mib/data_access/interface_sysctl.c
+@@ -252,8 +252,8 @@ netsnmp_sysctl_get_if_speed(char *name, u_int *speed,
+ return 0;
+ }
+
+- (void) memset(&ifmr, 0, sizeof(ifmr));
+- (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
++ memset(&ifmr, 0, sizeof(ifmr));
++ strlcpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
+
+ DEBUGMSGTL(("access:interface:container:sysctl"," speed in\n"));
+ if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0 ||
+@@ -326,6 +326,11 @@ netsnmp_arch_interface_container_load(netsnmp_container* container,
+ int amask;
+ char *if_name;
+ int flags;
++#ifdef HAVE_STRUCT_IFNET_IF_LASTCHANGE_TV_NSEC
++ struct timespec startspec;
++
++ TIMEVAL_TO_TIMESPEC(&starttime, &startspec);
++#endif
+
+ DEBUGMSGTL(("access:interface:container:sysctl",
+ "load (flags %u)\n", load_flags));
+@@ -477,7 +482,11 @@ netsnmp_arch_interface_container_load(netsnmp_container* container,
+ NETSNMP_INTERFACE_FLAGS_HAS_DROPS |
+ NETSNMP_INTERFACE_FLAGS_HAS_MCAST_PKTS;
+
++#ifdef HAVE_STRUCT_IFNET_IF_LASTCHANGE_TV_NSEC
++ if (timespeccmp(&ifp->ifm_data.ifi_lastchange, &startspec, >)) {
++#else
+ if (timercmp(&ifp->ifm_data.ifi_lastchange, &starttime, >)) {
++#endif
+ entry->lastchange = (ifp->ifm_data.ifi_lastchange.tv_sec -
+ starttime.tv_sec) * 100;
+ entry->ns_flags |= NETSNMP_INTERFACE_FLAGS_HAS_LASTCHANGE;
+@@ -502,7 +511,7 @@ netsnmp_arch_interface_container_load(netsnmp_container* container,
+
+ CONTAINER_INSERT(container, entry);
+ DEBUGMSGTL(("access:interface:container:sysctl",
+- "created entry %d for %s\n", entry->index, entry->name));
++ "created entry %d for %s\n", (int)entry->index, entry->name));
+ } /* for (each interface entry) */
+
+ /* pass 2: walk addresses */
+diff --git a/agent/mibgroup/if-mib/ifXTable/ifXTable_interface.c b/agent/mibgroup/if-mib/ifXTable/ifXTable_interface.c
+index e82c2fd..6434b46 100644
+--- a/agent/mibgroup/if-mib/ifXTable/ifXTable_interface.c
++++ b/agent/mibgroup/if-mib/ifXTable/ifXTable_interface.c
+@@ -2021,7 +2021,7 @@ _ifXTable_container_row_restore(const char *token, char *buf)
+ }
+ rowreq_ctx = (ifXTable_rowreq_ctx*)CONTAINER_FIND(container, &index);
+ if (NULL == rowreq_ctx) {
+- snmp_log(LOG_ERR, "error finding row index in "
++ snmp_log(LOG_DEBUG, "error finding row index in "
+ "_ifXTable_container_row_restore\n");
+ return;
+ }
+diff --git a/agent/mibgroup/ip-forward-mib/data_access/route_linux.c b/agent/mibgroup/ip-forward-mib/data_access/route_linux.c
+index d620834..926ccb7 100644
+--- a/agent/mibgroup/ip-forward-mib/data_access/route_linux.c
++++ b/agent/mibgroup/ip-forward-mib/data_access/route_linux.c
+@@ -103,8 +103,7 @@ _load_ipv4(netsnmp_container* container, u_long *index )
+ /*
+ * temporary null terminated name
+ */
+- strncpy(name, rtent_name, sizeof(name));
+- name[ sizeof(name)-1 ] = 0;
++ strlcpy(name, rtent_name, sizeof(name));
+
+ /*
+ * don't bother to try and get the ifindex for routes with
+diff --git a/agent/mibgroup/ip-mib/data_access/arp_netlink.c b/agent/mibgroup/ip-mib/data_access/arp_netlink.c
+index 01a535a..2059c23 100644
+--- a/agent/mibgroup/ip-mib/data_access/arp_netlink.c
++++ b/agent/mibgroup/ip-mib/data_access/arp_netlink.c
+@@ -43,7 +43,7 @@ netsnmp_access_arp_create(u_int init_flags,
+ if (cache_timeout != NULL)
+ *cache_timeout = 5;
+ if (cache_flags != NULL)
+- *cache_flags |= NETSNMP_CACHE_RESET_TIMER_ON_USE;
++ *cache_flags |= NETSNMP_CACHE_RESET_TIMER_ON_USE | NETSNMP_CACHE_DONT_FREE_BEFORE_LOAD;
+ access->cache_expired = cache_expired;
+
+ DEBUGMSGTL(("access:netlink:arp", "create arp cache\n"));
+@@ -131,6 +131,7 @@ int netsnmp_access_arp_unload(netsnmp_arp_access *access)
+ unregister_readfd(fd);
+ close(fd);
+ access->arch_magic = NULL;
++ access->synchronized = 0;
+ }
+ return 0;
+ }
+diff --git a/agent/mibgroup/ip-mib/data_access/ipaddress_ioctl.c b/agent/mibgroup/ip-mib/data_access/ipaddress_ioctl.c
+index b4f7e3a..ba145cb 100644
+--- a/agent/mibgroup/ip-mib/data_access/ipaddress_ioctl.c
++++ b/agent/mibgroup/ip-mib/data_access/ipaddress_ioctl.c
+@@ -230,7 +230,7 @@ _netsnmp_ioctl_ipaddress_container_load_v4(netsnmp_container *container,
+ /* restore the interface name if we modifed it due to unaliasing
+ * above
+ */
+- if (entry->flags | NETSNMP_ACCESS_IPADDRESS_ISALIAS) {
++ if (entry->flags & NETSNMP_ACCESS_IPADDRESS_ISALIAS) {
+ memcpy(ifrp->ifr_name, extras->name, sizeof(extras->name));
+ }
+
+@@ -242,7 +242,7 @@ _netsnmp_ioctl_ipaddress_container_load_v4(netsnmp_container *container,
+ addr_info = netsnmp_access_other_info_get(entry->if_index, AF_INET);
+ if(addr_info.bcastflg) {
+ bcastentry = netsnmp_access_ipaddress_entry_create();
+- if(NULL == entry) {
++ if(NULL == bcastentry) {
+ rc = -3;
+ break;
+ }
+@@ -491,11 +491,10 @@ _netsnmp_ioctl_ipaddress_set_v4(netsnmp_ipaddress_entry * entry)
+ alias_idx = _next_alias(name);
+ snprintf(ifrq.ifr_name,sizeof(ifrq.ifr_name), "%s:%d",
+ name, alias_idx);
++ ifrq.ifr_name[sizeof(ifrq.ifr_name) - 1] = 0;
+ }
+ else
+- strncpy(ifrq.ifr_name, (char *) extras->name, sizeof(ifrq.ifr_name));
+-
+- ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
++ strlcpy(ifrq.ifr_name, (char *) extras->name, sizeof(ifrq.ifr_name));
+
+ sin = (struct sockaddr_in*)&ifrq.ifr_addr;
+ sin->sin_family = AF_INET;
+@@ -543,8 +542,7 @@ _netsnmp_ioctl_ipaddress_delete_v4(netsnmp_ipaddress_entry * entry)
+
+ memset(&ifrq, 0, sizeof(ifrq));
+
+- strncpy(ifrq.ifr_name, (char *) extras->name, sizeof(ifrq.ifr_name));
+- ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
++ strlcpy(ifrq.ifr_name, (char *) extras->name, sizeof(ifrq.ifr_name));
+
+ ifrq.ifr_flags = 0;
+
+diff --git a/agent/mibgroup/ip-mib/data_access/ipaddress_solaris2.c b/agent/mibgroup/ip-mib/data_access/ipaddress_solaris2.c
+index 1a7d169..e2485e3 100644
+--- a/agent/mibgroup/ip-mib/data_access/ipaddress_solaris2.c
++++ b/agent/mibgroup/ip-mib/data_access/ipaddress_solaris2.c
+@@ -191,7 +191,7 @@ _load_v4(netsnmp_container *container, int idx_offset)
+
+ entry->ns_ia_index = ++idx_offset;
+
+- DEBUGMSGTL(("access:ipaddress:container", "insert if %d, addrlen %d\n",
++ DEBUGMSGTL(("access:ipaddress:container", "insert if %" NETSNMP_PRIo "u, addrlen %d\n",
+ entry->if_index, entry->ia_address_len));
+
+ if (CONTAINER_INSERT(container, entry) < 0) {
+@@ -276,7 +276,7 @@ _load_v6(netsnmp_container *container, int idx_offset)
+
+ entry->ns_ia_index = ++idx_offset;
+
+- DEBUGMSGTL(("access:ipaddress:container", "insert if %d, addrlen %d\n",
++ DEBUGMSGTL(("access:ipaddress:container", "insert if %" NETSNMP_PRIo "u, addrlen %d\n",
+ entry->if_index, entry->ia_address_len));
+
+ if (CONTAINER_INSERT(container, entry) < 0) {
+diff --git a/agent/mibgroup/ip-mib/data_access/systemstats_linux.c b/agent/mibgroup/ip-mib/data_access/systemstats_linux.c
+index 61a4855..717fc17 100644
+--- a/agent/mibgroup/ip-mib/data_access/systemstats_linux.c
++++ b/agent/mibgroup/ip-mib/data_access/systemstats_linux.c
+@@ -356,7 +356,6 @@ _systemstats_v6_load_file(netsnmp_systemstats_entry *entry, FILE *devin)
+ char line[1024];
+ char *stats, *start = line;
+ int len, rc;
+- int scan_count;
+ uintmax_t scan_val;
+
+ /*
+@@ -516,8 +515,6 @@ _systemstats_v6_load_file(netsnmp_systemstats_entry *entry, FILE *devin)
+
+ if (rc)
+ DEBUGMSGTL(("access:systemstats", "unknown stat %s\n", line));
+- else
+- ++scan_count;
+ }
+ /*
+ * Let DiscontinuityTime and RefreshRate active
+diff --git a/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c b/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c
+index dd39b07..4437829 100644
+--- a/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c
++++ b/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c
+@@ -287,6 +287,7 @@ ipAddressPrefixTable_container_load(netsnmp_container *container)
+ "error setting index while loading "
+ "ipAddressPrefixTable data.\n");
+ ipAddressPrefixTable_release_rowreq_ctx(rowreq_ctx);
++ rowreq_ctx = NULL;
+ continue;
+ }
+
+diff --git a/agent/mibgroup/ip-mib/ipv4InterfaceTable/ipv4InterfaceTable_data_access.c b/agent/mibgroup/ip-mib/ipv4InterfaceTable/ipv4InterfaceTable_data_access.c
+index 84a98ff..c9e14ff 100644
+--- a/agent/mibgroup/ip-mib/ipv4InterfaceTable/ipv4InterfaceTable_data_access.c
++++ b/agent/mibgroup/ip-mib/ipv4InterfaceTable/ipv4InterfaceTable_data_access.c
+@@ -138,7 +138,7 @@ ipv4InterfaceTable_check_entry_for_updates(const ifTable_rowreq_ctx *
+ * yes.
+ */
+ DEBUGMSGTL(("ipv4InterfaceTable:check_entry_for_updates",
+- "inserted row for %d\n", entry->index));
++ "inserted row for %" NETSNMP_PRIo "d\n", entry->index));
+ CONTAINER_INSERT(c, ift_rrc);
+ changed = 1;
+ }
+@@ -152,7 +152,7 @@ ipv4InterfaceTable_check_entry_for_updates(const ifTable_rowreq_ctx *
+ * no
+ */
+ DEBUGMSGTL(("ipv4InterfaceTable:check_entry_for_updates",
+- "removed row for %d\n",
++ "removed row for %" NETSNMP_PRIo "d\n",
+ ift_rrc->data.ifentry->index));
+ CONTAINER_REMOVE(c, ift_rrc);
+ changed = 1;
+@@ -164,7 +164,7 @@ ipv4InterfaceTable_check_entry_for_updates(const ifTable_rowreq_ctx *
+ ift_rrc->data.ifentry->retransmit_v4) ||
+ (entry->reasm_max_v4 != ift_rrc->data.ifentry->reasm_max_v4)) {
+ DEBUGMSGTL(("ipv4InterfaceTable:check_entry_for_updates",
+- "row changed for %d\n",
++ "row changed for %" NETSNMP_PRIo "d\n",
+ ift_rrc->data.ifentry->index));
+ changed = 1;
+ }
+diff --git a/agent/mibgroup/ip-mib/ipv6InterfaceTable/ipv6InterfaceTable_data_access.c b/agent/mibgroup/ip-mib/ipv6InterfaceTable/ipv6InterfaceTable_data_access.c
+index ef7d533..33c65a9 100644
+--- a/agent/mibgroup/ip-mib/ipv6InterfaceTable/ipv6InterfaceTable_data_access.c
++++ b/agent/mibgroup/ip-mib/ipv6InterfaceTable/ipv6InterfaceTable_data_access.c
+@@ -138,7 +138,7 @@ ipv6InterfaceTable_check_entry_for_updates(const ifTable_rowreq_ctx *
+ * yes.
+ */
+ DEBUGMSGTL(("ipv6InterfaceTable:check_entry_for_updates",
+- "inserted row for index %d\n", entry->index));
++ "inserted row for index %" NETSNMP_PRIo "d\n", entry->index));
+ CONTAINER_INSERT(c, ift_rrc);
+ changed = 1;
+ }
+@@ -152,7 +152,7 @@ ipv6InterfaceTable_check_entry_for_updates(const ifTable_rowreq_ctx *
+ * no
+ */
+ DEBUGMSGTL(("ipv6InterfaceTable:check_entry_for_updates",
+- "removed row for index %d\n",
++ "removed row for index %" NETSNMP_PRIo "d\n",
+ ift_rrc->data.ifentry->index));
+ CONTAINER_REMOVE(c, ift_rrc);
+ changed = 1;
+@@ -190,7 +190,7 @@ ipv6InterfaceTable_check_entry_for_updates(const ifTable_rowreq_ctx *
+ && (entry->forwarding_v6 !=
+ ift_rrc->data.ifentry->forwarding_v6))) {
+ DEBUGMSGTL(("ipv6InterfaceTable:check_entry_for_updates",
+- "row changed for index %d\n",
++ "row changed for index %" NETSNMP_PRIo "d\n",
+ ift_rrc->data.ifentry->index));
+ changed = 1;
+ }
+diff --git a/agent/mibgroup/kernel_sunos5.c b/agent/mibgroup/kernel_sunos5.c
+index 984fc77..9ee0284 100644
+--- a/agent/mibgroup/kernel_sunos5.c
++++ b/agent/mibgroup/kernel_sunos5.c
+@@ -469,8 +469,7 @@ getKstat(const char *statname, const char *varname, void *value)
+ case KSTAT_DATA_CHAR:
+ DEBUGMSGTL(("kernel_sunos5", "value: %s\n", d->value.c));
+ *(char **)v = buf;
+- buf[sizeof(buf)-1] = 0;
+- strncpy(buf, d->value.c, sizeof(buf)-1);
++ strlcpy(buf, d->value.c, sizeof(buf));
+ break;
+ #ifdef KSTAT_DATA_INT32 /* Solaris 2.6 and up */
+ case KSTAT_DATA_INT32:
+@@ -623,8 +622,7 @@ getKstatString(const char *statname, const char *varname,
+ if (strcmp(d->name, varname) == 0) {
+ switch (d->data_type) {
+ case KSTAT_DATA_CHAR:
+- value[value_len-1] = '\0';
+- strncpy(value, d->value.c, value_len-1);
++ strlcpy(value, d->value.c, value_len);
+ DEBUGMSGTL(("kernel_sunos5", "value: %s\n", d->value.c));
+ break;
+ default:
+diff --git a/agent/mibgroup/mibII/icmp.c b/agent/mibgroup/mibII/icmp.c
+index 977effa..429fa0b 100644
+--- a/agent/mibgroup/mibII/icmp.c
++++ b/agent/mibgroup/mibII/icmp.c
+@@ -456,9 +456,11 @@ icmp_msg_stats_first_entry(void **loop_context,
+ void
+ init_icmp(void)
+ {
+- netsnmp_handler_registration *reginfo;
++ netsnmp_handler_registration *scalar_reginfo = NULL;
++ int rc;
+ #ifdef linux
+- netsnmp_handler_registration *msg_stats_reginfo;
++ netsnmp_handler_registration *msg_stats_reginfo = NULL;
++ netsnmp_handler_registration *table_reginfo = NULL;
+ netsnmp_iterator_info *iinfo;
+ netsnmp_iterator_info *msg_stats_iinfo;
+ netsnmp_table_registration_info *table_info;
+@@ -469,15 +471,17 @@ init_icmp(void)
+ * register ourselves with the agent as a group of scalars...
+ */
+ DEBUGMSGTL(("mibII/icmp", "Initialising ICMP group\n"));
+- reginfo = netsnmp_create_handler_registration("icmp", icmp_handler,
++ scalar_reginfo = netsnmp_create_handler_registration("icmp", icmp_handler,
+ icmp_oid, OID_LENGTH(icmp_oid), HANDLER_CAN_RONLY);
+- netsnmp_register_scalar_group(reginfo, ICMPINMSGS, ICMPOUTADDRMASKREPS);
++ rc = netsnmp_register_scalar_group(scalar_reginfo, ICMPINMSGS, ICMPOUTADDRMASKREPS);
++ if (rc != SNMPERR_SUCCESS)
++ return;
+ /*
+ * .... with a local cache
+ * (except for HP-UX 11, which extracts objects individually)
+ */
+ #ifndef hpux11
+- netsnmp_inject_handler( reginfo,
++ netsnmp_inject_handler( scalar_reginfo,
+ netsnmp_get_cache_handler(ICMP_STATS_CACHE_TIMEOUT,
+ icmp_load, icmp_free,
+ icmp_oid, OID_LENGTH(icmp_oid)));
+@@ -485,63 +489,64 @@ init_icmp(void)
+ #ifdef linux
+
+ /* register icmpStatsTable */
+- reginfo = netsnmp_create_handler_registration("icmpStatsTable",
+- icmp_stats_table_handler, icmp_stats_tbl_oid,
+- OID_LENGTH(icmp_stats_tbl_oid), HANDLER_CAN_RONLY);
+-
+ table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
+- if (!table_info) {
+- return;
+- }
+-
++ if (!table_info)
++ goto bail;
+ netsnmp_table_helper_add_indexes(table_info, ASN_INTEGER, 0);
+ table_info->min_column = ICMP_STAT_INMSG;
+ table_info->max_column = ICMP_STAT_OUTERR;
+
+
+ iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
+- if (!iinfo) {
+- return;
+- }
++ if (!iinfo)
++ goto bail;
+ iinfo->get_first_data_point = icmp_stats_first_entry;
+ iinfo->get_next_data_point = icmp_stats_next_entry;
+ iinfo->table_reginfo = table_info;
+
+- netsnmp_register_table_iterator2(reginfo, iinfo);
+-
+- /* register icmpMsgStatsTable */
+- msg_stats_reginfo = netsnmp_create_handler_registration("icmpMsgStatsTable",
+- icmp_msg_stats_table_handler, icmp_msg_stats_tbl_oid,
+- OID_LENGTH(icmp_msg_stats_tbl_oid), HANDLER_CAN_RONLY);
++ table_reginfo = netsnmp_create_handler_registration("icmpStatsTable",
++ icmp_stats_table_handler, icmp_stats_tbl_oid,
++ OID_LENGTH(icmp_stats_tbl_oid), HANDLER_CAN_RONLY);
+
+- msg_stats_table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
+- if (!msg_stats_table_info) {
+- return;
++ rc = netsnmp_register_table_iterator2(table_reginfo, iinfo);
++ if (rc != SNMPERR_SUCCESS) {
++ table_reginfo = NULL;
++ goto bail;
+ }
++ netsnmp_inject_handler( table_reginfo,
++ netsnmp_get_cache_handler(ICMP_STATS_CACHE_TIMEOUT,
++ icmp_load, icmp_free,
++ icmp_stats_tbl_oid, OID_LENGTH(icmp_stats_tbl_oid)));
+
++ /* register icmpMsgStatsTable */
++ msg_stats_table_info = SNMP_MALLOC_TYPEDEF(netsnmp_table_registration_info);
++ if (!msg_stats_table_info)
++ goto bail;
+ netsnmp_table_helper_add_indexes(msg_stats_table_info, ASN_INTEGER, ASN_INTEGER, 0);
+ msg_stats_table_info->min_column = ICMP_MSG_STAT_IN_PKTS;
+ msg_stats_table_info->max_column = ICMP_MSG_STAT_OUT_PKTS;
+
+ msg_stats_iinfo = SNMP_MALLOC_TYPEDEF(netsnmp_iterator_info);
+- if (!msg_stats_iinfo) {
+- return;
+- }
++ if (!msg_stats_iinfo)
++ goto bail;
+ msg_stats_iinfo->get_first_data_point = icmp_msg_stats_first_entry;
+ msg_stats_iinfo->get_next_data_point = icmp_msg_stats_next_entry;
+ msg_stats_iinfo->table_reginfo = msg_stats_table_info;
+
+- netsnmp_register_table_iterator2(msg_stats_reginfo, msg_stats_iinfo);
++ msg_stats_reginfo = netsnmp_create_handler_registration("icmpMsgStatsTable",
++ icmp_msg_stats_table_handler, icmp_msg_stats_tbl_oid,
++ OID_LENGTH(icmp_msg_stats_tbl_oid), HANDLER_CAN_RONLY);
++
++ rc = netsnmp_register_table_iterator2(msg_stats_reginfo, msg_stats_iinfo);
++ if (rc != SNMPERR_SUCCESS) {
++ msg_stats_reginfo = NULL;
++ goto bail;
++ }
++
+ netsnmp_inject_handler( msg_stats_reginfo,
+ netsnmp_get_cache_handler(ICMP_STATS_CACHE_TIMEOUT,
+ icmp_load, icmp_free,
+ icmp_msg_stats_tbl_oid, OID_LENGTH(icmp_msg_stats_tbl_oid)));
+-#ifndef hpux11
+- netsnmp_inject_handler( reginfo,
+- netsnmp_get_cache_handler(ICMP_STATS_CACHE_TIMEOUT,
+- icmp_load, icmp_free,
+- icmp_stats_tbl_oid, OID_LENGTH(icmp_stats_tbl_oid)));
+-#endif /* ! hpux11 */
+ #endif /* linux */
+
+ #ifdef USING_MIBII_IP_MODULE
+@@ -558,6 +563,17 @@ init_icmp(void)
+ init_kernel_sunos5();
+ #endif
+ #endif
++ return;
++
++#ifdef linux
++bail:
++ if (scalar_reginfo)
++ netsnmp_unregister_handler(scalar_reginfo);
++ if (table_reginfo)
++ netsnmp_unregister_handler(table_reginfo);
++ if (msg_stats_reginfo)
++ netsnmp_unregister_handler(msg_stats_reginfo);
++#endif
+ }
+
+
+diff --git a/agent/mibgroup/mibII/interfaces.c b/agent/mibgroup/mibII/interfaces.c
+index 08c2a85..41d7287 100644
+--- a/agent/mibgroup/mibII/interfaces.c
++++ b/agent/mibgroup/mibII/interfaces.c
+@@ -463,10 +463,8 @@ Interface_Scan_By_Index(int iindex,
+ a = get_address(ifp + 1, ifp->ifm_addrs, RTA_IFP);
+ if (a == NULL)
+ return 0;
+- strncpy(if_name,
+- ((const struct sockaddr_in *) a)->sin_zero,
+- ((const u_char *) a)[5]);
+- if_name[((const u_char *) a)[5]] = 0;
++ sprintf(if_name, "%.*s", ((const u_char *) a)[5],
++ ((const struct sockaddr_in *) a)->sin_zero);
+ *if_msg = *ifp;
+ ++have_ifinfo;
+ }
+@@ -1603,8 +1601,7 @@ Interface_Scan_Init(void)
+ }
+
+ *stats = 0;
+- strncpy(ifname_buf, ifstart, sizeof(ifname_buf));
+- ifname_buf[ sizeof(ifname_buf)-1 ] = 0;
++ strlcpy(ifname_buf, ifstart, sizeof(ifname_buf));
+ *stats++ = ':';
+ while (*stats == ' ')
+ stats++;
+@@ -1671,31 +1668,27 @@ Interface_Scan_Init(void)
+ nnew->if_unit = strdup(*ptr ? ptr : "");
+ *ptr = 0;
+
+- strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
+- ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
++ strlcpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
+ if (ioctl(fd, SIOCGIFADDR, &ifrq) < 0)
+ memset((char *) &nnew->if_addr, 0, sizeof(nnew->if_addr));
+ else
+ nnew->if_addr = ifrq.ifr_addr;
+
+- strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
+- ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
++ strlcpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
+ if (ioctl(fd, SIOCGIFBRDADDR, &ifrq) < 0)
+ memset((char *) &nnew->ifu_broadaddr, 0,
+ sizeof(nnew->ifu_broadaddr));
+ else
+ nnew->ifu_broadaddr = ifrq.ifr_broadaddr;
+
+- strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
+- ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
++ strlcpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
+ if (ioctl(fd, SIOCGIFNETMASK, &ifrq) < 0)
+ memset((char *) &nnew->ia_subnetmask, 0,
+ sizeof(nnew->ia_subnetmask));
+ else
+ nnew->ia_subnetmask = ifrq.ifr_netmask;
+
+- strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
+- ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
++ strlcpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
+ nnew->if_flags = ioctl(fd, SIOCGIFFLAGS, &ifrq) < 0
+ ? 0 : ifrq.ifr_flags;
+
+@@ -1707,8 +1700,7 @@ Interface_Scan_Init(void)
+ * 4 bytes of sa_data.
+ */
+ memset(ifrq.ifr_hwaddr.sa_data, (0), IFHWADDRLEN);
+- strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
+- ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
++ strlcpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
+ if (ioctl(fd, SIOCGIFHWADDR, &ifrq) < 0)
+ memset(nnew->if_hwaddr, (0), IFHWADDRLEN);
+ else {
+@@ -1765,14 +1757,12 @@ Interface_Scan_Init(void)
+ #endif
+ }
+
+- strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
+- ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
++ strlcpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
+ nnew->if_metric = ioctl(fd, SIOCGIFMETRIC, &ifrq) < 0
+ ? 0 : ifrq.ifr_metric;
+
+ #ifdef SIOCGIFMTU
+- strncpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
+- ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
++ strlcpy(ifrq.ifr_name, ifname, sizeof(ifrq.ifr_name));
+ nnew->if_mtu = (ioctl(fd, SIOCGIFMTU, &ifrq) < 0)
+ ? 0 : ifrq.ifr_mtu;
+ #else
+@@ -1882,14 +1872,13 @@ Interface_Scan_Next(short *Index,
+ }
+ #else
+ ifnet = *ifnetaddr;
+- strncpy(saveName, ifnet.if_name, sizeof(saveName));
++ strlcpy(saveName, ifnet.if_name, sizeof(saveName));
+ #endif
+
+ saveName[sizeof(saveName) - 1] = '\0';
+ cp = (char *) strchr(saveName, '\0');
+ #ifdef linux
+- strncat(cp, ifnet.if_unit, sizeof(saveName)-strlen(saveName)-1);
+- saveName[sizeof(saveName) - 1] = '\0';
++ strlcat(saveName, ifnet.if_unit, sizeof(saveName));
+ #else
+ #ifdef NETSNMP_FEATURE_CHECKIN
+ /* this exists here just so we don't copy ifdef logic elsewhere */
+@@ -2000,7 +1989,7 @@ Interface_Scan_Next(short *Index,
+ }
+ #if HAVE_STRUCT_IFNET_IF_XNAME
+ #if defined(netbsd1) || defined(openbsd2)
+- strncpy(saveName, ifnet.if_xname, sizeof saveName);
++ strlcpy(saveName, ifnet.if_xname, sizeof(saveName));
+ #else
+ if (!NETSNMP_KLOOKUP(ifnet.if_xname, (char *) saveName, sizeof saveName)) {
+ DEBUGMSGTL(("mibII/interfaces:Interface_Scan_Next", "klookup failed\n"));
+diff --git a/agent/mibgroup/mibII/ip.c b/agent/mibgroup/mibII/ip.c
+index 56de408..40b5d2f 100644
+--- a/agent/mibgroup/mibII/ip.c
++++ b/agent/mibgroup/mibII/ip.c
+@@ -151,6 +151,7 @@ void
+ init_ip(void)
+ {
+ netsnmp_handler_registration *reginfo;
++ int rc;
+
+ /*
+ * register ourselves with the agent as a group of scalars...
+@@ -158,7 +159,9 @@ init_ip(void)
+ DEBUGMSGTL(("mibII/ip", "Initialising IP group\n"));
+ reginfo = netsnmp_create_handler_registration("ip", ip_handler,
+ ip_oid, OID_LENGTH(ip_oid), HANDLER_CAN_RONLY);
+- netsnmp_register_scalar_group(reginfo, IPFORWARDING, IPROUTEDISCARDS);
++ rc = netsnmp_register_scalar_group(reginfo, IPFORWARDING, IPROUTEDISCARDS);
++ if (rc != SNMPERR_SUCCESS)
++ return;
+
+ /*
+ * .... with a local cache
+diff --git a/agent/mibgroup/mibII/ipv6.c b/agent/mibgroup/mibII/ipv6.c
+index a372ca4..5714647 100644
+--- a/agent/mibgroup/mibII/ipv6.c
++++ b/agent/mibgroup/mibII/ipv6.c
+@@ -817,8 +817,7 @@ var_ifv6Entry(register struct variable * vp,
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_addr.sa_family = AF_INET6;
+- strncpy(ifr.ifr_name, if_getname(interface),
+- sizeof(ifr.ifr_name) - 1);
++ strlcpy(ifr.ifr_name, if_getname(interface), sizeof(ifr.ifr_name));
+ if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
+ break;
+ if (ioctl(s, SIOCGIFMTU, (caddr_t) & ifr) < 0) {
+@@ -1019,8 +1018,7 @@ var_ifv6Entry(register struct variable * vp,
+ int s;
+
+ memset(&ifr, 0, sizeof(ifr));
+- strncpy(ifr.ifr_name, if_getname(interface),
+- sizeof(ifr.ifr_name) - 1);
++ strlcpy(ifr.ifr_name, if_getname(interface), sizeof(ifr.ifr_name));
+ if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
+ break;
+ if (ioctl(s, SIOCGIFSTAT_IN6, (caddr_t) & ifr) < 0) {
+@@ -1176,8 +1174,7 @@ var_icmpv6Entry(register struct variable * vp,
+ int s;
+
+ memset(&ifr, 0, sizeof(ifr));
+- strncpy(ifr.ifr_name, if_getname(interface),
+- sizeof(ifr.ifr_name) - 1);
++ strlcpy(ifr.ifr_name, if_getname(interface), sizeof(ifr.ifr_name));
+ if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
+ break;
+ if (ioctl(s, SIOCGIFSTAT_ICMP6, (caddr_t) & ifr) < 0) {
+@@ -2101,7 +2098,7 @@ var_ifv6Entry(register struct variable * vp,
+ break;
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_addr.sa_family = AF_INET6;
+- strncpy(ifr.ifr_name, p, sizeof(ifr.ifr_name) - 1);
++ strlcpy(ifr.ifr_name, p, sizeof(ifr.ifr_name));
+ if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
+ break;
+ if (ioctl(s, SIOCGIFMTU, (caddr_t) & ifr) < 0) {
+@@ -2121,7 +2118,7 @@ var_ifv6Entry(register struct variable * vp,
+ break;
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_addr.sa_family = AF_INET6;
+- strncpy(ifr.ifr_name, p, sizeof(ifr.ifr_name) - 1);
++ strlcpy(ifr.ifr_name, p, sizeof(ifr.ifr_name));
+ if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
+ break;
+ if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
+@@ -2150,7 +2147,7 @@ var_ifv6Entry(register struct variable * vp,
+ break;
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_addr.sa_family = AF_INET6;
+- strncpy(ifr.ifr_name, p, sizeof(ifr.ifr_name) - 1);
++ strlcpy(ifr.ifr_name, p, sizeof(ifr.ifr_name));
+ if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0)
+ break;
+ if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) {
+diff --git a/agent/mibgroup/mibII/kernel_linux.c b/agent/mibgroup/mibII/kernel_linux.c
+index dfa0b2b..b21a166 100644
+--- a/agent/mibgroup/mibII/kernel_linux.c
++++ b/agent/mibgroup/mibII/kernel_linux.c
+@@ -66,8 +66,8 @@ decode_icmp_msg(char *line, char *data, struct icmp4_msg_mib *msg)
+ * getting modified. So we take a local copy for this purpose even though
+ * its expensive.
+ */
+- strncpy(line_cpy, line, sizeof(line_cpy));
+- strncpy(data_cpy, data, sizeof(data_cpy));
++ strlcpy(line_cpy, line, sizeof(line_cpy));
++ strlcpy(data_cpy, data, sizeof(data_cpy));
+
+ lineptr = line_cpy;
+ dataptr = data_cpy;
+diff --git a/agent/mibgroup/mibII/kernel_netbsd.c b/agent/mibgroup/mibII/kernel_netbsd.c
+index 7f0a690..93f38b7 100644
+--- a/agent/mibgroup/mibII/kernel_netbsd.c
++++ b/agent/mibgroup/mibII/kernel_netbsd.c
+@@ -32,8 +32,8 @@
+ int
+ netbsd_read_icmp_stat(struct icmp_mib *mib)
+ {
+- size_t size;
+ uint64_t icmpstat[ICMP_NSTATS];
++ size_t size = sizeof(icmpstat);
+ int i;
+
+ (void)memset(mib, 0, sizeof(*mib));
+@@ -89,8 +89,8 @@ netbsd_read_icmp_stat(struct icmp_mib *mib)
+ int
+ netbsd_read_ip_stat(struct ip_mib *mib)
+ {
+- size_t size;
+ uint64_t ipstat[IP_NSTATS];
++ size_t size = sizeof(ipstat);
+ int i;
+ static int sname[4] = { 4, 2, 0, 0 }; /* CTL_NET, PF_INET, IPPROTO_IP, 0 */
+ size_t len;
+@@ -141,8 +141,8 @@ netbsd_read_ip_stat(struct ip_mib *mib)
+ int
+ netbsd_read_tcp_stat(struct tcp_mib *mib)
+ {
+- size_t size;
+ uint64_t tcpstat[TCP_NSTATS];
++ size_t size = sizeof(tcpstat);
+
+ (void)memset(mib, 0, sizeof(*mib));
+
+@@ -177,8 +177,8 @@ netbsd_read_tcp_stat(struct tcp_mib *mib)
+ int
+ netbsd_read_udp_stat(struct udp_mib *mib)
+ {
+- size_t size;
+ uint64_t udpstat[UDP_NSTATS];
++ size_t size = sizeof(udpstat);
+
+ (void)memset(mib, 0, sizeof(*mib));
+
+diff --git a/agent/mibgroup/mibII/mta_sendmail.c b/agent/mibgroup/mibII/mta_sendmail.c
+index 79a5182..00397d3 100644
+--- a/agent/mibgroup/mibII/mta_sendmail.c
++++ b/agent/mibgroup/mibII/mta_sendmail.c
+@@ -853,8 +853,7 @@ read_sendmailcf(BOOL config)
+ }
+
+ if (strncasecmp(line + 2, "StatusFile", 10) == 0) {
+- strncpy(sendmailst_fn, filename, sizeof(sendmailst_fn));
+- sendmailst_fn[ sizeof(sendmailst_fn)-1 ] = 0;
++ strlcpy(sendmailst_fn, filename, sizeof(sendmailst_fn));
+ found_sendmailst = TRUE;
+ DEBUGMSGTL(("mibII/mta_sendmail.c:read_sendmailcf",
+ "found statatistics file \"%s\"\n",
+@@ -975,11 +974,7 @@ read_sendmailcf(BOOL config)
+ linenr++;
+ }
+
+- for (i = 0; i < 10 && fclose(sendmailcf_fp) != 0; i++) {
+- /*
+- * nothing to do
+- */
+- }
++ fclose(sendmailcf_fp);
+
+ for (i = mailers; i < MAXMAILERS; i++) {
+ mailernames[i][0] = '\0';
+diff --git a/agent/mibgroup/mibII/route_write.c b/agent/mibgroup/mibII/route_write.c
+index b2e941b..5820ee1 100644
+--- a/agent/mibgroup/mibII/route_write.c
++++ b/agent/mibgroup/mibII/route_write.c
+@@ -434,11 +434,6 @@ write_rte(int action,
+
+ memcpy(buf, var_val, (var_val_len > 8) ? 8 : var_val_len);
+
+- if (var_val_type != ASN_IPADDRESS) {
+- snmp_log(LOG_ERR, "not IP address 2");
+- return SNMP_ERR_WRONGTYPE;
+- }
+-
+ rp->xx_dst = *((u_long *) buf);
+
+
+@@ -509,16 +504,12 @@ write_rte(int action,
+
+ memcpy(buf, var_val, (var_val_len > 8) ? 8 : var_val_len);
+
+- if (var_val_type != ASN_IPADDRESS) {
+- snmp_log(LOG_ERR, "not right5");
+- return SNMP_ERR_WRONGTYPE;
+- }
+-
+ rp->xx_nextIR = *((u_long *) buf);
+
+ } else if (action == COMMIT) {
+ rp->rt_nextIR = rp->xx_nextIR;
+ }
++ break;
+
+
+ case IPROUTETYPE:
+diff --git a/agent/mibgroup/mibII/system_mib.c b/agent/mibgroup/mibII/system_mib.c
+index 7ca1227..65b0b7c 100644
+--- a/agent/mibgroup/mibII/system_mib.c
++++ b/agent/mibgroup/mibII/system_mib.c
+@@ -262,9 +262,9 @@ init_system_mib(void)
+ extmp.type = EXECPROC;
+ extmp.next = NULL;
+ exec_command(&extmp);
+- strncpy(version_descr, extmp.output, sizeof(version_descr));
+- version_descr[sizeof(version_descr) - 1] = 0;
+- version_descr[strlen(version_descr) - 1] = 0; /* chomp new line */
++ strlcpy(version_descr, extmp.output, sizeof(version_descr));
++ if (strlen(version_descr) >= 1)
++ version_descr[strlen(version_descr) - 1] = 0; /* chomp new line */
+ #else
+ #if (defined (WIN32) && defined (HAVE_WIN32_PLATFORM_SDK)) || defined (mingw32)
+ windowsOSVersionString(version_descr, sizeof(version_descr));
+@@ -278,7 +278,7 @@ init_system_mib(void)
+ gethostname(sysName, sizeof(sysName));
+ #else
+ #ifdef HAVE_UNAME
+- strncpy(sysName, utsName.nodename, sizeof(sysName));
++ strlcpy(sysName, utsName.nodename, sizeof(sysName));
+ #else
+ #if defined (HAVE_EXECV) && !defined (mingw32)
+ sprintf(extmp.command, "%s -n", UNAMEPROG);
+@@ -288,8 +288,9 @@ init_system_mib(void)
+ extmp.type = EXECPROC;
+ extmp.next = NULL;
+ exec_command(&extmp);
+- strncpy(sysName, extmp.output, sizeof(sysName));
+- sysName[strlen(sysName) - 1] = 0; /* chomp new line */
++ strlcpy(sysName, extmp.output, sizeof(sysName));
++ if (strlen(sysName) >= 1)
++ sysName[strlen(sysName) - 1] = 0; /* chomp new line */
+ #else
+ strcpy(sysName, "unknown");
+ #endif /* HAVE_EXECV */
+diff --git a/agent/mibgroup/mibII/tcp.c b/agent/mibgroup/mibII/tcp.c
+index d68e699..3c79fad 100644
+--- a/agent/mibgroup/mibII/tcp.c
++++ b/agent/mibgroup/mibII/tcp.c
+@@ -113,6 +113,7 @@ void
+ init_tcp(void)
+ {
+ netsnmp_handler_registration *reginfo;
++ int rc;
+
+ /*
+ * register ourselves with the agent as a group of scalars...
+@@ -120,7 +121,9 @@ init_tcp(void)
+ DEBUGMSGTL(("mibII/tcpScalar", "Initialising TCP scalar group\n"));
+ reginfo = netsnmp_create_handler_registration("tcp", tcp_handler,
+ tcp_oid, OID_LENGTH(tcp_oid), HANDLER_CAN_RONLY);
+- netsnmp_register_scalar_group(reginfo, TCPRTOALGORITHM, TCPOUTRSTS);
++ rc = netsnmp_register_scalar_group(reginfo, TCPRTOALGORITHM, TCPOUTRSTS);
++ if (rc != SNMPERR_SUCCESS)
++ return;
+
+ /*
+ * .... with a local cache
+diff --git a/agent/mibgroup/mibII/tcpTable.c b/agent/mibgroup/mibII/tcpTable.c
+index 01d00e5..088dd06 100644
+--- a/agent/mibgroup/mibII/tcpTable.c
++++ b/agent/mibgroup/mibII/tcpTable.c
+@@ -147,6 +147,7 @@ init_tcpTable(void)
+ netsnmp_table_registration_info *table_info;
+ netsnmp_iterator_info *iinfo;
+ netsnmp_handler_registration *reginfo;
++ int rc;
+
+ DEBUGMSGTL(("mibII/tcpTable", "Initialising TCP Table\n"));
+ /*
+@@ -186,7 +187,9 @@ init_tcpTable(void)
+ tcpTable_handler,
+ tcpTable_oid, OID_LENGTH(tcpTable_oid),
+ HANDLER_CAN_RONLY),
+- netsnmp_register_table_iterator2(reginfo, iinfo);
++ rc = netsnmp_register_table_iterator2(reginfo, iinfo);
++ if (rc != SNMPERR_SUCCESS)
++ return;
+
+ /*
+ * .... with a local cache
+diff --git a/agent/mibgroup/mibII/udp.c b/agent/mibgroup/mibII/udp.c
+index 8d2654d..1ddcbc5 100644
+--- a/agent/mibgroup/mibII/udp.c
++++ b/agent/mibgroup/mibII/udp.c
+@@ -74,6 +74,7 @@ void
+ init_udp(void)
+ {
+ netsnmp_handler_registration *reginfo;
++ int rc;
+
+ /*
+ * register ourselves with the agent as a group of scalars...
+@@ -81,7 +82,9 @@ init_udp(void)
+ DEBUGMSGTL(("mibII/udpScalar", "Initialising UDP scalar group\n"));
+ reginfo = netsnmp_create_handler_registration("udp", udp_handler,
+ udp_oid, OID_LENGTH(udp_oid), HANDLER_CAN_RONLY);
+- netsnmp_register_scalar_group(reginfo, UDPINDATAGRAMS, UDPOUTDATAGRAMS);
++ rc = netsnmp_register_scalar_group(reginfo, UDPINDATAGRAMS, UDPOUTDATAGRAMS);
++ if (rc != SNMPERR_SUCCESS)
++ return;
+
+ /*
+ * .... with a local cache
+diff --git a/agent/mibgroup/mibII/udpTable.c b/agent/mibgroup/mibII/udpTable.c
+index 162de1b..64f6dfb 100644
+--- a/agent/mibgroup/mibII/udpTable.c
++++ b/agent/mibgroup/mibII/udpTable.c
+@@ -129,6 +129,7 @@ init_udpTable(void)
+ netsnmp_table_registration_info *table_info;
+ netsnmp_iterator_info *iinfo;
+ netsnmp_handler_registration *reginfo;
++ int rc;
+
+ DEBUGMSGTL(("mibII/udpTable", "Initialising UDP Table\n"));
+ /*
+@@ -166,7 +167,9 @@ init_udpTable(void)
+ udpTable_handler,
+ udpTable_oid, OID_LENGTH(udpTable_oid),
+ HANDLER_CAN_RONLY),
+- netsnmp_register_table_iterator2(reginfo, iinfo);
++ rc = netsnmp_register_table_iterator2(reginfo, iinfo);
++ if (rc != SNMPERR_SUCCESS)
++ return;
+
+ /*
+ * .... with a local cache
+@@ -496,6 +499,7 @@ udpTable_load(netsnmp_cache *cache, void *vmagic)
+ if (state != 7) /* fix me: UDP_LISTEN ??? */
+ continue;
+
++ memset(&pcb, 0, sizeof(pcb));
+ /* store in network byte order */
+ pcb.inp_laddr.s_addr = htonl(pcb.inp_laddr.s_addr);
+ pcb.inp_lport = htons((unsigned short) (lport));
+diff --git a/agent/mibgroup/mibII/vacm_conf.c b/agent/mibgroup/mibII/vacm_conf.c
+index f62c6cc..f2faf86 100644
+--- a/agent/mibgroup/mibII/vacm_conf.c
++++ b/agent/mibgroup/mibII/vacm_conf.c
+@@ -201,8 +201,7 @@ vacm_parse_group(const char *token, char *param)
+ config_perror("failed to create group entry");
+ return;
+ }
+- strncpy(gp->groupName, group, sizeof(gp->groupName));
+- gp->groupName[ sizeof(gp->groupName)-1 ] = 0;
++ strlcpy(gp->groupName, group, sizeof(gp->groupName));
+ gp->storageType = SNMP_STORAGE_PERMANENT;
+ gp->status = SNMP_ROW_ACTIVE;
+ free(gp->reserved);
+@@ -542,10 +541,6 @@ vacm_parse_setaccess(const char *token, char *param)
+ config_perror("failed to create access entry");
+ return;
+ }
+- if (!ap) {
+- config_perror("failed to create access entry");
+- return;
+- }
+
+ strcpy(ap->views[viewnum], viewval);
+ ap->contextMatch = iprefix;
+@@ -990,11 +985,9 @@ vacm_create_simple(const char *token, char *confline,
+ sprintf(viewname,"viewUSM%d",commcount);
+ }
+ if ( strcmp( token, "authgroup" ) == 0 ) {
+- strncpy(grpname, community, sizeof(grpname));
+- grpname[ sizeof(grpname)-1 ] = 0;
++ strlcpy(grpname, community, sizeof(grpname));
+ } else {
+- strncpy(secname, community, sizeof(secname));
+- secname[ sizeof(secname)-1 ] = 0;
++ strlcpy(secname, community, sizeof(secname));
+
+ /*
+ * sec->group mapping
+@@ -1419,7 +1412,7 @@ vacm_check_view_contents(netsnmp_pdu *pdu, oid * name, size_t namelen,
+ * NULL termination of the pdu field is ugly here. Do in PDU parsing?
+ */
+ if (pdu->contextName)
+- strncpy(contextNameIndex, pdu->contextName, pdu->contextNameLen);
++ memcpy(contextNameIndex, pdu->contextName, pdu->contextNameLen);
+ else
+ contextNameIndex[0] = '\0';
+
+diff --git a/agent/mibgroup/mibII/vacm_vars.c b/agent/mibgroup/mibII/vacm_vars.c
+index 7860573..85cef94 100644
+--- a/agent/mibgroup/mibII/vacm_vars.c
++++ b/agent/mibgroup/mibII/vacm_vars.c
+@@ -1084,7 +1084,7 @@ write_vacmAccessStatus(int action,
+ {
+ static long long_ret;
+ int model, level;
+- char *newGroupName, *newContextPrefix;
++ char *newGroupName = NULL, *newContextPrefix = NULL;
+ size_t groupNameLen, contextPrefixLen;
+ struct vacm_accessEntry *aptr = NULL;
+
+diff --git a/agent/mibgroup/mibII/var_route.c b/agent/mibgroup/mibII/var_route.c
+index b5daed0..8488019 100644
+--- a/agent/mibgroup/mibII/var_route.c
++++ b/agent/mibgroup/mibII/var_route.c
+@@ -919,7 +919,7 @@ load_rtentries(struct radix_node *pt)
+ }
+ #if HAVE_STRUCT_IFNET_IF_XNAME
+ #if defined(netbsd1) || defined(openbsd2)
+- strncpy(name, ifnet.if_xname, sizeof name);
++ strlcpy(name, ifnet.if_xname, sizeof(name));
+ #else
+ if (!NETSNMP_KLOOKUP(ifnet.if_xname, name, sizeof name)) {
+ DEBUGMSGTL(("mibII/var_route", "klookup failed\n"));
+@@ -1366,8 +1366,7 @@ Route_Scan_Reload(void)
+ &(((struct sockaddr_in *) &(rtent.rt_genmask))->sin_addr.s_addr)))
+ continue;
+
+- strncpy(name, rt->rt_dev, sizeof(name));
+- name[ sizeof(name)-1 ] = 0;
++ strlcpy(name, rt->rt_dev, sizeof(name));
+
+ rt->rt_flags = flags, rt->rt_refcnt = refcnt;
+ rt->rt_use = use, rt->rt_metric = metric;
+diff --git a/agent/mibgroup/notification-log-mib/notification_log.c b/agent/mibgroup/notification-log-mib/notification_log.c
+index 86efb34..a12a338 100644
+--- a/agent/mibgroup/notification-log-mib/notification_log.c
++++ b/agent/mibgroup/notification-log-mib/notification_log.c
+@@ -136,11 +136,9 @@ check_log_size(unsigned int clientreg, void *clientarg)
+ netsnmp_table_row *row;
+ netsnmp_table_data_set_storage *data;
+ u_long count = 0;
+- struct timeval now;
+ u_long uptime;
+
+- gettimeofday(&now, NULL);
+- uptime = netsnmp_timeval_uptime(&now);
++ uptime = netsnmp_get_agent_uptime();
+
+ if (!nlmLogTable || !nlmLogTable->table ) {
+ DEBUGMSGTL(("notification_log", "missing log table\n"));
+@@ -580,7 +578,6 @@ void
+ log_notification(netsnmp_pdu *pdu, netsnmp_transport *transport)
+ {
+ long tmpl;
+- struct timeval now;
+ netsnmp_table_row *row;
+
+ static u_long default_num = 0;
+@@ -620,8 +617,7 @@ log_notification(netsnmp_pdu *pdu, netsnmp_transport *transport)
+ /*
+ * add the data
+ */
+- gettimeofday(&now, NULL);
+- tmpl = netsnmp_timeval_uptime(&now);
++ tmpl = netsnmp_get_agent_uptime();
+ netsnmp_set_row_column(row, COLUMN_NLMLOGTIME, ASN_TIMETICKS,
+ &tmpl, sizeof(tmpl));
+ time(&timetnow);
+diff --git a/agent/mibgroup/notification/snmpNotifyFilterProfileTable.c b/agent/mibgroup/notification/snmpNotifyFilterProfileTable.c
+index ac7f2ab..b12cdc8 100644
+--- a/agent/mibgroup/notification/snmpNotifyFilterProfileTable.c
++++ b/agent/mibgroup/notification/snmpNotifyFilterProfileTable.c
+@@ -194,6 +194,7 @@ parse_snmpNotifyFilterProfileTable(const char *token, char *line)
+ &StorageTmp->snmpNotifyFilterProfileNameLen);
+ if (StorageTmp->snmpNotifyFilterProfileName == NULL) {
+ config_perror("invalid specification for snmpNotifyFilterProfileName");
++ SNMP_FREE(StorageTmp);
+ return;
+ }
+
+diff --git a/agent/mibgroup/notification/snmpNotifyTable.c b/agent/mibgroup/notification/snmpNotifyTable.c
+index 649b19e..8d09c59 100644
+--- a/agent/mibgroup/notification/snmpNotifyTable.c
++++ b/agent/mibgroup/notification/snmpNotifyTable.c
+@@ -317,9 +317,15 @@ notifyTable_register_notifications(int major, int minor,
+ /*
+ * address
+ */
++ t = snmp_sess_transport(snmp_sess_pointer(ss));
++ if (!t) {
++ snmp_log(LOG_ERR,
++ "Cannot add new trap destination, transport is closed.");
++ snmp_sess_close(ss);
++ return 0;
++ }
+ ptr = snmpTargetAddrTable_create();
+ ptr->name = strdup(buf);
+- t = snmp_sess_transport(snmp_sess_pointer(ss));
+ memcpy(ptr->tDomain, t->domain, t->domain_length * sizeof(oid));
+ ptr->tDomainLen = t->domain_length;
+ ptr->tAddressLen = t->remote_length;
+@@ -346,8 +352,10 @@ notifyTable_register_notifications(int major, int minor,
+ pptr->secModel = ss->securityModel;
+ pptr->secLevel = ss->securityLevel;
+ pptr->secName = (char *) malloc(ss->securityNameLen + 1);
+- if (pptr->secName == NULL)
++ if (pptr->secName == NULL) {
++ snmpTargetParamTable_dispose(pptr);
+ return 0;
++ }
+ memcpy((void *) pptr->secName, (void *) ss->securityName,
+ ss->securityNameLen);
+ pptr->secName[ss->securityNameLen] = 0;
+@@ -363,8 +371,10 @@ notifyTable_register_notifications(int major, int minor,
+ pptr->secName = NULL;
+ if (ss->community && (ss->community_len > 0)) {
+ pptr->secName = (char *) malloc(ss->community_len + 1);
+- if (pptr->secName == NULL)
++ if (pptr->secName == NULL) {
++ snmpTargetParamTable_dispose(pptr);
+ return 0;
++ }
+ memcpy((void *) pptr->secName, (void *) ss->community,
+ ss->community_len);
+ pptr->secName[ss->community_len] = 0;
+@@ -573,6 +583,7 @@ parse_snmpNotifyTable(const char *token, char *line)
+ &StorageTmp->snmpNotifyNameLen);
+ if (StorageTmp->snmpNotifyName == NULL) {
+ config_perror("invalid specification for snmpNotifyName");
++ SNMP_FREE(StorageTmp);
+ return;
+ }
+
+@@ -582,6 +593,7 @@ parse_snmpNotifyTable(const char *token, char *line)
+ &StorageTmp->snmpNotifyTagLen);
+ if (StorageTmp->snmpNotifyTag == NULL) {
+ config_perror("invalid specification for snmpNotifyTag");
++ SNMP_FREE(StorageTmp);
+ return;
+ }
+
+diff --git a/agent/mibgroup/rmon-mib/data_access/etherstats_linux.c b/agent/mibgroup/rmon-mib/data_access/etherstats_linux.c
+index cd35d09..d4b6e69 100644
+--- a/agent/mibgroup/rmon-mib/data_access/etherstats_linux.c
++++ b/agent/mibgroup/rmon-mib/data_access/etherstats_linux.c
+@@ -46,8 +46,8 @@ etherstats_interface_name_list_get (struct ifname *list_head, int *retval)
+ *retval = -2;
+ return NULL;
+ }
+- memset (list_head, 0, sizeof (struct ifname));
+- strncpy (list_head->name, p->ifa_name, IF_NAMESIZE);
++ memset(list_head, 0, sizeof(struct ifname));
++ strlcpy(list_head->name, p->ifa_name, IF_NAMESIZE);
+ continue;
+ }
+ for (nameptr1 = list_head; nameptr1; nameptr2 = nameptr1, nameptr1 = nameptr1->ifn_next)
+@@ -67,10 +67,9 @@ etherstats_interface_name_list_get (struct ifname *list_head, int *retval)
+ return NULL;
+ }
+ nameptr2 = nameptr2->ifn_next;
+- memset (nameptr2, 0, sizeof (struct ifname));
+- strncpy (nameptr2->name, p->ifa_name, IF_NAMESIZE);
++ memset(nameptr2, 0, sizeof(struct ifname));
++ strlcpy(nameptr2->name, p->ifa_name, IF_NAMESIZE);
+ continue;
+-
+ }
+
+ freeifaddrs(addrs);
+@@ -162,7 +161,7 @@ interface_ioctl_etherstats_get (etherStatsTable_rowreq_ctx *rowreq_ctx , int fd,
+ "called\n"));
+
+ memset(&ifr, 0, sizeof(ifr));
+- strcpy(ifr.ifr_name, name);
++ strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+
+ memset(&driver_info, 0, sizeof(driver_info));
+ driver_info.cmd = ETHTOOL_GDRVINFO;
+@@ -238,8 +237,8 @@ interface_ioctl_etherstats_get (etherStatsTable_rowreq_ctx *rowreq_ctx , int fd,
+ for (i = 0; i < nstats; i++) {
+ char s[ETH_GSTRING_LEN];
+
+- strncpy(s, (const char *) &eth_strings->data[i * ETH_GSTRING_LEN],
+- ETH_GSTRING_LEN);
++ strlcpy(s, (const char *) &eth_strings->data[i * ETH_GSTRING_LEN],
++ sizeof(s));
+
+ if (ETHERSTATSJABBERS(s)) {
+ data->etherStatsJabbers = (u_long)eth_stats->data[i];
+@@ -300,8 +299,7 @@ _etherStats_ioctl_get(int fd, int which, struct ifreq *ifrq, const char* name)
+ }
+ }
+
+- strncpy(ifrq->ifr_name, name, sizeof(ifrq->ifr_name));
+- ifrq->ifr_name[ sizeof(ifrq->ifr_name)-1 ] = 0;
++ strlcpy(ifrq->ifr_name, name, sizeof(ifrq->ifr_name));
+ rc = ioctl(fd, which, ifrq);
+ if (rc < 0) {
+ DEBUGMSGTL(("access:etherStatsTable:ioctl",
+diff --git a/agent/mibgroup/sctp-mib/sctpAssocLocalAddrTable.c b/agent/mibgroup/sctp-mib/sctpAssocLocalAddrTable.c
+index bc22430..d6023e5 100644
+--- a/agent/mibgroup/sctp-mib/sctpAssocLocalAddrTable.c
++++ b/agent/mibgroup/sctp-mib/sctpAssocLocalAddrTable.c
+@@ -102,6 +102,7 @@ initialize_table_sctpAssocLocalAddrTable(void)
+ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
+ snmp_log(LOG_ERR,
+ "error registering table handler for sctpAssocLocalAddrTable\n");
++ reg = NULL; /* it was freed inside netsnmp_register_table */
+ goto bail;
+ }
+
+diff --git a/agent/mibgroup/sctp-mib/sctpAssocRemAddrTable.c b/agent/mibgroup/sctp-mib/sctpAssocRemAddrTable.c
+index bea3978..38ca8a3 100644
+--- a/agent/mibgroup/sctp-mib/sctpAssocRemAddrTable.c
++++ b/agent/mibgroup/sctp-mib/sctpAssocRemAddrTable.c
+@@ -101,6 +101,7 @@ initialize_table_sctpAssocRemAddrTable(void)
+ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
+ snmp_log(LOG_ERR,
+ "error registering table handler for sctpAssocRemAddrTable\n");
++ reg = NULL; /* it was freed inside netsnmp_register_table */
+ goto bail;
+ }
+
+diff --git a/agent/mibgroup/sctp-mib/sctpAssocTable.c b/agent/mibgroup/sctp-mib/sctpAssocTable.c
+index 951f778..9919075 100644
+--- a/agent/mibgroup/sctp-mib/sctpAssocTable.c
++++ b/agent/mibgroup/sctp-mib/sctpAssocTable.c
+@@ -135,6 +135,7 @@ initialize_table_sctpAssocTable(void)
+ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
+ snmp_log(LOG_ERR,
+ "error registering table handler for sctpAssocTable\n");
++ reg = NULL; /* it was freed inside netsnmp_register_table */
+ goto bail;
+ }
+
+diff --git a/agent/mibgroup/sctp-mib/sctpLookupLocalPortTable.c b/agent/mibgroup/sctp-mib/sctpLookupLocalPortTable.c
+index f40db3a..1a6fd35 100644
+--- a/agent/mibgroup/sctp-mib/sctpLookupLocalPortTable.c
++++ b/agent/mibgroup/sctp-mib/sctpLookupLocalPortTable.c
+@@ -97,6 +97,7 @@ initialize_table_sctpLookupLocalPortTable(void)
+ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
+ snmp_log(LOG_ERR,
+ "error registering table handler for sctpLookupLocalPortTable\n");
++ reg = NULL; /* it was freed inside netsnmp_register_table */
+ goto bail;
+ }
+
+diff --git a/agent/mibgroup/sctp-mib/sctpLookupRemHostNameTable.c b/agent/mibgroup/sctp-mib/sctpLookupRemHostNameTable.c
+index cfbceab..ae2ec91 100644
+--- a/agent/mibgroup/sctp-mib/sctpLookupRemHostNameTable.c
++++ b/agent/mibgroup/sctp-mib/sctpLookupRemHostNameTable.c
+@@ -99,6 +99,7 @@ initialize_table_sctpLookupRemHostNameTable(void)
+ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
+ snmp_log(LOG_ERR,
+ "error registering table handler for sctpLookupRemHostNameTable\n");
++ reg = NULL; /* it was freed inside netsnmp_register_table */
+ goto bail;
+ }
+
+diff --git a/agent/mibgroup/sctp-mib/sctpLookupRemIPAddrTable.c b/agent/mibgroup/sctp-mib/sctpLookupRemIPAddrTable.c
+index c95bdf1..368dd51 100644
+--- a/agent/mibgroup/sctp-mib/sctpLookupRemIPAddrTable.c
++++ b/agent/mibgroup/sctp-mib/sctpLookupRemIPAddrTable.c
+@@ -98,6 +98,7 @@ initialize_table_sctpLookupRemIPAddrTable(void)
+ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
+ snmp_log(LOG_ERR,
+ "error registering table handler for sctpLookupRemIPAddrTable\n");
++ reg = NULL; /* it was freed inside netsnmp_register_table */
+ goto bail;
+ }
+
+diff --git a/agent/mibgroup/sctp-mib/sctpLookupRemPortTable.c b/agent/mibgroup/sctp-mib/sctpLookupRemPortTable.c
+index eb1828b..c8a8874 100644
+--- a/agent/mibgroup/sctp-mib/sctpLookupRemPortTable.c
++++ b/agent/mibgroup/sctp-mib/sctpLookupRemPortTable.c
+@@ -97,6 +97,7 @@ initialize_table_sctpLookupRemPortTable(void)
+ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
+ snmp_log(LOG_ERR,
+ "error registering table handler for sctpLookupRemPortTable\n");
++ reg = NULL; /* it was freed inside netsnmp_register_table */
+ goto bail;
+ }
+
+diff --git a/agent/mibgroup/sctp-mib/sctpLookupRemPrimIPAddrTable.c b/agent/mibgroup/sctp-mib/sctpLookupRemPrimIPAddrTable.c
+index 44d384f..d9966fc 100644
+--- a/agent/mibgroup/sctp-mib/sctpLookupRemPrimIPAddrTable.c
++++ b/agent/mibgroup/sctp-mib/sctpLookupRemPrimIPAddrTable.c
+@@ -99,6 +99,7 @@ initialize_table_sctpLookupRemPrimIPAddrTable(void)
+ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
+ snmp_log(LOG_ERR,
+ "error registering table handler for sctpLookupRemPrimIPAddrTable\n");
++ reg = NULL; /* it was freed inside netsnmp_register_table */
+ goto bail;
+ }
+
+diff --git a/agent/mibgroup/sctp-mib/sctpScalars.c b/agent/mibgroup/sctp-mib/sctpScalars.c
+index 6bcefd2..821079a 100644
+--- a/agent/mibgroup/sctp-mib/sctpScalars.c
++++ b/agent/mibgroup/sctp-mib/sctpScalars.c
+@@ -18,6 +18,7 @@ init_sctpScalars(void)
+ {
+ netsnmp_handler_registration *reginfo_stats;
+ netsnmp_handler_registration *reginfo_params;
++ int rc;
+
+ DEBUGMSGTL(("sctp:scalars:init", "Initializing\n"));
+
+@@ -27,8 +28,14 @@ init_sctpScalars(void)
+ sctp_stats_oid,
+ OID_LENGTH(sctp_stats_oid),
+ HANDLER_CAN_RONLY);
+- netsnmp_register_scalar_group(reginfo_stats, SCTP_CURRESTAB,
++ if (!reginfo_stats)
++ return;
++
++ rc = netsnmp_register_scalar_group(reginfo_stats, SCTP_CURRESTAB,
+ SCTP_DISCONTINUITYTIME);
++ if (rc != SNMPERR_SUCCESS)
++ return;
++
+ netsnmp_inject_handler(reginfo_stats,
+ netsnmp_get_cache_handler
+ (SCTP_STATS_CACHE_TIMEOUT,
+@@ -43,8 +50,13 @@ init_sctpScalars(void)
+ sctp_params_oid,
+ OID_LENGTH(sctp_params_oid),
+ HANDLER_CAN_RONLY);
+- netsnmp_register_scalar_group(reginfo_params, SCTP_RTOALGORITHM,
++ if (!reginfo_params)
++ return;
++
++ rc = netsnmp_register_scalar_group(reginfo_params, SCTP_RTOALGORITHM,
+ SCTP_MAXINITRETR);
++ if (!rc)
++ return;
+ netsnmp_inject_handler(reginfo_params,
+ netsnmp_get_cache_handler
+ (SCTP_PARAMS_CACHE_TIMEOUT,
+diff --git a/agent/mibgroup/sctp-mib/sctpScalars_freebsd.c b/agent/mibgroup/sctp-mib/sctpScalars_freebsd.c
+index a62b788..b8c723f 100644
+--- a/agent/mibgroup/sctp-mib/sctpScalars_freebsd.c
++++ b/agent/mibgroup/sctp-mib/sctpScalars_freebsd.c
+@@ -60,9 +60,7 @@ netsnmp_access_sctp_params_arch_init()
+ int
+ netsnmp_access_sctp_params_arch_load(netsnmp_sctp_params * sctp_params)
+ {
+- int ret;
+ size_t len = sizeof(uint32_t);
+- unsigned int cnt = 0;
+
+ sctp_params->rto_algorithm = NETSNMP_SCTP_ALGORITHM_VANJ;
+ sctp_params->max_assocs = SCTP_MAX_NUM_OF_ASOC;
+diff --git a/agent/mibgroup/sctp-mib/sctpScalars_linux.c b/agent/mibgroup/sctp-mib/sctpScalars_linux.c
+index 8cbe90f..2e5b5af 100644
+--- a/agent/mibgroup/sctp-mib/sctpScalars_linux.c
++++ b/agent/mibgroup/sctp-mib/sctpScalars_linux.c
+@@ -35,6 +35,7 @@ load_uint_file(const char *filename, u_int * value)
+ if (ret != 1) {
+ DEBUGMSGTL(("sctp:scalars:arch:load", "Malformed file %s\n",
+ filename));
++ fclose(f);
+ return -2;
+ }
+
+@@ -71,6 +72,7 @@ netsnmp_access_sctp_stats_arch_load(netsnmp_sctp_stats * sctp_stats)
+ if (delimiter == NULL) {
+ DEBUGMSGTL(("sctp:scalars:stats:arch_load",
+ "Malformed line, cannot find '\\t'!\n"));
++ fclose(f);
+ return -1;
+ }
+ errno = 0;
+@@ -78,6 +80,7 @@ netsnmp_access_sctp_stats_arch_load(netsnmp_sctp_stats * sctp_stats)
+ if (errno != 0) {
+ DEBUGMSGTL(("sctp:scalars:stats:arch_load",
+ "Malformed value!'\n"));
++ fclose(f);
+ return -1;
+ }
+
+@@ -136,11 +139,13 @@ netsnmp_access_sctp_stats_arch_load(netsnmp_sctp_stats * sctp_stats)
+ if (ret < 0) {
+ DEBUGMSGTL(("sctp:scalars:stats:arch_load",
+ "Unknown entry!'\n"));
++ fclose(f);
+ return ret;
+ }
+ }
+
+ sctp_stats->discontinuity_time = 0;
++ fclose(f);
+ return 0;
+ }
+
+diff --git a/agent/mibgroup/sctp-mib/sctpTables_common.c b/agent/mibgroup/sctp-mib/sctpTables_common.c
+index 899d8d5..b28ea03 100644
+--- a/agent/mibgroup/sctp-mib/sctpTables_common.c
++++ b/agent/mibgroup/sctp-mib/sctpTables_common.c
+@@ -435,7 +435,7 @@ sctpTables_load(void)
+
+ ret = sctpTables_arch_load(&containers, &flags);
+
+- if (flags | SCTP_TABLES_LOAD_FLAG_DELETE_INVALID) {
++ if (flags & SCTP_TABLES_LOAD_FLAG_DELETE_INVALID) {
+ sctpAssocTable_delete_invalid(containers.sctpAssocTable);
+ sctpAssocRemAddrTable_delete_invalid(containers.
+ sctpAssocRemAddrTable);
+@@ -443,7 +443,7 @@ sctpTables_load(void)
+ sctpAssocLocalAddrTable);
+ }
+
+- if (flags | SCTP_TABLES_LOAD_FLAG_AUTO_LOOKUP) {
++ if (flags & SCTP_TABLES_LOAD_FLAG_AUTO_LOOKUP) {
+ ret = sctpTables_fill_lookup(&containers);
+ }
+
+diff --git a/agent/mibgroup/sctp-mib/sctpTables_freebsd.c b/agent/mibgroup/sctp-mib/sctpTables_freebsd.c
+index db73e00..516e9f5 100644
+--- a/agent/mibgroup/sctp-mib/sctpTables_freebsd.c
++++ b/agent/mibgroup/sctp-mib/sctpTables_freebsd.c
+@@ -58,8 +58,6 @@ parse_assoc_local_addresses(sctpTables_containers * containers,
+ static int
+ parse_assoc_xstcb(sctpTables_containers * containers, struct xsctp_tcb *xstcb)
+ {
+- long inode;
+- char *token;
+ int ret;
+ sctpAssocTable_entry *entry;
+
+@@ -124,7 +122,6 @@ static int
+ parse_remaddr_xraddr(sctpTables_containers * containers,
+ struct xsctp_raddr *xraddr)
+ {
+- char *token;
+ int ret;
+ sctpAssocRemAddrTable_entry *entry;
+
+@@ -184,8 +181,6 @@ sctpTables_arch_load(sctpTables_containers * containers, u_long * flags)
+ struct xsctp_tcb *xstcb;
+ struct xsctp_laddr *xladdr;
+ struct xsctp_raddr *xraddr;
+- sa_family_t family;
+- void *addr;
+
+
+ *flags |= SCTP_TABLES_LOAD_FLAG_DELETE_INVALID;
+diff --git a/agent/mibgroup/smux/smux.c b/agent/mibgroup/smux/smux.c
+index fdb5e11..2055974 100644
+--- a/agent/mibgroup/smux/smux.c
++++ b/agent/mibgroup/smux/smux.c
+@@ -91,7 +91,7 @@ static u_char *smux_parse(u_char *, oid *, size_t *, size_t *, u_char *);
+ static u_char *smux_parse_var(u_char *, size_t *, oid *, size_t *,
+ size_t *, u_char *);
+ static void smux_send_close(int, int);
+-static void smux_list_detach(smux_reg **, smux_reg **);
++static void smux_list_detach(smux_reg **, smux_reg *);
+ static void smux_replace_active(smux_reg *, smux_reg *);
+ static void smux_peer_cleanup(int);
+ static int smux_auth_peer(oid *, size_t, char *, int);
+@@ -145,6 +145,7 @@ smux_parse_peer_auth(const char *token, char *cptr)
+ }
+ if (nauths == SMUX_MAX_PEERS) {
+ config_perror("Too many smuxpeers");
++ free(aptr);
+ return;
+ }
+
+@@ -169,10 +170,8 @@ smux_parse_peer_auth(const char *token, char *cptr)
+ /*
+ * password
+ */
+- if (*password_cptr) {
+- strncpy(aptr->sa_passwd, password_cptr, SMUXMAXSTRLEN-1);
+- aptr->sa_passwd[SMUXMAXSTRLEN-1] = '\0';
+- }
++ if (*password_cptr)
++ strlcpy(aptr->sa_passwd, password_cptr, sizeof(aptr->sa_passwd));
+ } else {
+ /*
+ * null passwords OK
+@@ -369,6 +368,11 @@ var_smux_write(int action,
+ break;
+ }
+
++ if (!rptr) {
++ DEBUGMSGTL(("smux", "[var_smux_write] unknown registration\n"));
++ return SNMP_ERR_GENERR;
++ }
++
+ switch (action) {
+ case RESERVE1:
+ DEBUGMSGTL(("smux", "[var_smux_write] entering RESERVE1\n"));
+@@ -1049,7 +1053,7 @@ smux_rreq_process(int sd, u_char * ptr, size_t * len)
+ /*
+ * no replacement found
+ */
+- smux_list_detach(&ActiveRegs, &rptr);
++ smux_list_detach(&ActiveRegs, rptr);
+ free(rptr);
+ }
+ smux_send_rrsp(sd, rpriority);
+@@ -1063,7 +1067,7 @@ smux_rreq_process(int sd, u_char * ptr, size_t * len)
+ priority);
+ if (rptr) {
+ rpriority = rptr->sr_priority;
+- smux_list_detach(&PassiveRegs, &rptr);
++ smux_list_detach(&PassiveRegs, rptr);
+ free(rptr);
+ smux_send_rrsp(sd, rpriority);
+ return ptr;
+@@ -1104,7 +1108,7 @@ smux_rreq_process(int sd, u_char * ptr, size_t * len)
+ snmp_oid_compare(oid_name, oid_name_len, rptr->sr_name,
+ rptr->sr_name_len);
+ if (result == 0) {
+- if ((oid_name_len == rptr->sr_name_len)) {
++ if (oid_name_len == rptr->sr_name_len) {
+ if ((nrptr->sr_priority == -1)) {
+ nrptr->sr_priority = rptr->sr_priority;
+ do {
+@@ -1154,9 +1158,17 @@ smux_rreq_process(int sd, u_char * ptr, size_t * len)
+ if (nrptr->sr_priority == -1)
+ nrptr->sr_priority = 0;
+ smux_list_add(&ActiveRegs, nrptr);
+- register_mib("smux", (struct variable *)
+- smux_variables, sizeof(struct variable2),
+- 1, nrptr->sr_name, nrptr->sr_name_len);
++ if (register_mib("smux", (struct variable *)
++ smux_variables, sizeof(struct variable2),
++ 1, nrptr->sr_name, nrptr->sr_name_len)
++ != SNMPERR_SUCCESS) {
++ DEBUGMSGTL(("smux", "[smux_rreq_process] Failed to register subtree\n"));
++ smux_list_detach(&ActiveRegs, nrptr);
++ free(nrptr);
++ smux_send_rrsp(sd, -1);
++ return NULL;
++ }
++
+ done:
+ smux_send_rrsp(sd, nrptr->sr_priority);
+ return ptr;
+@@ -1202,10 +1214,10 @@ smux_find_match(smux_reg * regs, int sd, oid * oid_name,
+ static void
+ smux_replace_active(smux_reg * actptr, smux_reg * pasptr)
+ {
+- smux_list_detach(&ActiveRegs, &actptr);
++ smux_list_detach(&ActiveRegs, actptr);
+ unregister_mib(actptr->sr_name, actptr->sr_name_len);
+
+- smux_list_detach(&PassiveRegs, &pasptr);
++ smux_list_detach(&PassiveRegs, pasptr);
+ (void) smux_list_add(&ActiveRegs, pasptr);
+
+ register_mib("smux", (struct variable *) smux_variables,
+@@ -1215,7 +1227,7 @@ smux_replace_active(smux_reg * actptr, smux_reg * pasptr)
+ }
+
+ static void
+-smux_list_detach(smux_reg ** head, smux_reg ** m_remove)
++smux_list_detach(smux_reg ** head, smux_reg * m_remove)
+ {
+ smux_reg *rptr, *rptr2;
+
+@@ -1223,15 +1235,13 @@ smux_list_detach(smux_reg ** head, smux_reg ** m_remove)
+ DEBUGMSGTL(("smux", "[smux_list_detach] Ouch!"));
+ return;
+ }
+- if (*head == *m_remove) {
+- *m_remove = *head;
++ if (*head == m_remove) {
+ *head = (*head)->sr_next;
+ return;
+ }
+ for (rptr = *head, rptr2 = rptr->sr_next; rptr2;
+ rptr2 = rptr2->sr_next, rptr = rptr->sr_next) {
+- if (rptr2 == *m_remove) {
+- *m_remove = rptr2;
++ if (rptr2 == m_remove) {
+ rptr->sr_next = rptr2->sr_next;
+ return;
+ }
+@@ -1337,7 +1347,7 @@ smux_find_replacement(oid * name, size_t name_len)
+ if (!snmp_oidtree_compare(rptr->sr_name, rptr->sr_name_len,
+ name, name_len)) {
+ if ((difflen = rptr->sr_name_len - name_len)
+- < bestlen) {
++ < bestlen || !bestptr) {
+ bestlen = difflen;
+ bestptr = rptr;
+ } else if ((difflen == bestlen) &&
+@@ -1759,7 +1769,7 @@ smux_peer_cleanup(int sd)
+ for (rptr = PassiveRegs; rptr; rptr = nrptr) {
+ nrptr = rptr->sr_next;
+ if (rptr->sr_fd == sd) {
+- smux_list_detach(&PassiveRegs, &rptr);
++ smux_list_detach(&PassiveRegs, rptr);
+ free(rptr);
+ }
+ rptr = nrptr;
+@@ -1770,12 +1780,12 @@ smux_peer_cleanup(int sd)
+ for (rptr = ActiveRegs; rptr; rptr = rptr2) {
+ rptr2 = rptr->sr_next;
+ if (rptr->sr_fd == sd) {
+- smux_list_detach(&ActiveRegs, &rptr);
++ smux_list_detach(&ActiveRegs, rptr);
+ unregister_mib(rptr->sr_name, rptr->sr_name_len);
+ if ((nrptr = smux_find_replacement(rptr->sr_name,
+ rptr->sr_name_len)) !=
+ NULL) {
+- smux_list_detach(&PassiveRegs, &nrptr);
++ smux_list_detach(&PassiveRegs, nrptr);
+ smux_list_add(&ActiveRegs, nrptr);
+ register_mib("smux", (struct variable *)
+ smux_variables, sizeof(struct variable2),
+diff --git a/agent/mibgroup/smux/snmp_bgp.c b/agent/mibgroup/smux/snmp_bgp.c
+index 70596a1..16b0185 100644
+--- a/agent/mibgroup/smux/snmp_bgp.c
++++ b/agent/mibgroup/smux/snmp_bgp.c
+@@ -109,8 +109,6 @@ init_snmp_bdp(void)
+ bgp_variables_oid);
+ }
+
+-
+-#endif
+ static oid max_bgp_mib[] =
+ { 1, 3, 6, 1, 2, 1, 15, 5, 1, 6, 255, 255, 255, 255 };
+ static oid min_bgp_mib[] = { 1, 3, 6, 1, 2, 1, 15, 1, 0 };
+diff --git a/agent/mibgroup/snmp-notification-mib/snmpNotifyFilterTable/snmpNotifyFilterTable_data_access.c b/agent/mibgroup/snmp-notification-mib/snmpNotifyFilterTable/snmpNotifyFilterTable_data_access.c
+index fd7ab8e..942a865 100644
+--- a/agent/mibgroup/snmp-notification-mib/snmpNotifyFilterTable/snmpNotifyFilterTable_data_access.c
++++ b/agent/mibgroup/snmp-notification-mib/snmpNotifyFilterTable/snmpNotifyFilterTable_data_access.c
+@@ -247,7 +247,7 @@ snmpNotifyFilterTable_container_load(netsnmp_container *container)
+ }
+
+ DEBUGMSGT(("verbose:snmpNotifyFilterTable:snmpNotifyFilterTable_container_load",
+- "inserted %lu records\n", (long)count));
++ "inserted %" NETSNMP_PRIz "u records\n", count));
+
+ return MFD_SUCCESS;
+ } /* snmpNotifyFilterTable_container_load */
+diff --git a/agent/mibgroup/target/snmpTargetAddrEntry.c b/agent/mibgroup/target/snmpTargetAddrEntry.c
+index ac77d52..50cfed6 100644
+--- a/agent/mibgroup/target/snmpTargetAddrEntry.c
++++ b/agent/mibgroup/target/snmpTargetAddrEntry.c
+@@ -372,9 +372,7 @@ snmpTargetAddr_addName(struct targetAddrTable_struct *entry, char *cptr)
+ "ERROR snmpTargetAddrEntry: name out of range in config string\n"));
+ return (0);
+ }
+- entry->name = (char *) malloc(len + 1);
+- strncpy(entry->name, cptr, len);
+- entry->name[len] = '\0';
++ entry->name = strdup(cptr);
+ }
+ return (1);
+ } /* addName */
+@@ -508,9 +506,7 @@ snmpTargetAddr_addTagList(struct targetAddrTable_struct *entry, char *cptr)
+ return (0);
+ }
+ SNMP_FREE(entry->tagList);
+- entry->tagList = (char *) malloc(len + 1);
+- strncpy(entry->tagList, cptr, len);
+- entry->tagList[len] = '\0';
++ entry->tagList = strdup(cptr);
+ }
+ return (1);
+ } /* snmpTargetAddr_addTagList */
+@@ -534,9 +530,7 @@ snmpTargetAddr_addParams(struct targetAddrTable_struct *entry, char *cptr)
+ "ERROR snmpTargetAddrEntry: params out of range in config string\n"));
+ return (0);
+ }
+- entry->params = (char *) malloc(len + 1);
+- strncpy(entry->params, cptr, len);
+- entry->params[len] = '\0';
++ entry->params = strdup(cptr);
+ }
+ return (1);
+ } /* snmpTargetAddr_addParams */
+@@ -725,10 +719,7 @@ store_snmpTargetAddrEntry(int majorID, int minorID, void *serverarg,
+ (int) curr_struct->tDomain[i]);
+ line[ sizeof(line)-1 ] = 0;
+ }
+- if ( strlen(line)+2 < sizeof(line) ) {
+- line[ strlen(line)+1 ] = 0;
+- line[ strlen(line) ] = ' ';
+- }
++ strlcat(line, " ", sizeof(line));
+ read_config_save_octet_string(&line[strlen(line)],
+ curr_struct->tAddress,
+ curr_struct->tAddressLen);
+@@ -860,7 +851,7 @@ var_snmpTargetAddrEntry(struct variable * vp,
+
+ case SNMPTARGETADDRTAGLIST:
+ if (temp_struct->tagList != NULL) {
+- strcpy(string, temp_struct->tagList);
++ strlcpy(string, temp_struct->tagList, sizeof(string));
+ *var_len = strlen(string);
+ return (unsigned char *) string;
+ } else {
+@@ -870,7 +861,7 @@ var_snmpTargetAddrEntry(struct variable * vp,
+ case SNMPTARGETADDRPARAMS:
+ if (temp_struct->params == NULL)
+ return NULL;
+- strcpy(string, temp_struct->params);
++ strlcpy(string, temp_struct->params, sizeof(string));
+ *var_len = strlen(string);
+ return (unsigned char *) string;
+
+@@ -1342,7 +1333,7 @@ write_snmpTargetAddrParams(int action,
+ }
+
+ old_params = target->params;
+- target->params = (char*)malloc(var_val_len + 1);
++ target->params = malloc(var_val_len + 1);
+ if (target->params == NULL) {
+ return SNMP_ERR_RESOURCEUNAVAILABLE;
+ }
+diff --git a/agent/mibgroup/target/snmpTargetParamsEntry.c b/agent/mibgroup/target/snmpTargetParamsEntry.c
+index 3a796c8..eed43f0 100644
+--- a/agent/mibgroup/target/snmpTargetParamsEntry.c
++++ b/agent/mibgroup/target/snmpTargetParamsEntry.c
+@@ -319,9 +319,7 @@ snmpTargetParams_addParamName(struct targetParamTable_struct *entry,
+ "ERROR snmpTargetParamsEntry: param name out of range in config string\n"));
+ return (0);
+ }
+- entry->paramName = (char *) malloc(len + 1);
+- strncpy(entry->paramName, cptr, len);
+- entry->paramName[len] = '\0';
++ entry->paramName = strdup(cptr);
+ }
+ return (1);
+ }
+@@ -382,16 +380,12 @@ int
+ snmpTargetParams_addSecName(struct targetParamTable_struct *entry,
+ char *cptr)
+ {
+- size_t len;
+ if (cptr == NULL) {
+ DEBUGMSGTL(("snmpTargetParamsEntry",
+ "ERROR snmpTargetParamsEntry: no security name in config string\n"));
+ return (0);
+ } else {
+- len = strlen(cptr);
+- entry->secName = (char *) malloc(len + 1);
+- strncpy(entry->secName, cptr, len);
+- entry->secName[len] = '\0';
++ entry->secName = strdup(cptr);
+ }
+ return (1);
+ } /* snmpTargetParams_addSecName */
+diff --git a/agent/mibgroup/target/snmpTargetParamsEntry.h b/agent/mibgroup/target/snmpTargetParamsEntry.h
+index 2bd6e25..bd30582 100644
+--- a/agent/mibgroup/target/snmpTargetParamsEntry.h
++++ b/agent/mibgroup/target/snmpTargetParamsEntry.h
+@@ -47,6 +47,7 @@
+ targetParamTable_struct
+ *newEntry);
+ struct targetParamTable_struct *snmpTargetParamTable_create(void);
++ void snmpTargetParamTable_dispose(struct targetParamTable_struct *);
+
+ /*
+ * function definitions
+diff --git a/agent/mibgroup/tcp-mib/data_access/tcpConn_linux.c b/agent/mibgroup/tcp-mib/data_access/tcpConn_linux.c
+index ec0cbf0..9a5b466 100644
+--- a/agent/mibgroup/tcp-mib/data_access/tcpConn_linux.c
++++ b/agent/mibgroup/tcp-mib/data_access/tcpConn_linux.c
+@@ -291,7 +291,7 @@ _load6(netsnmp_container *container, u_int load_flags)
+ */
+ while (fgets(line, sizeof(line), in)) {
+ netsnmp_tcpconn_entry *entry;
+- int state, rc, local_port, remote_port, tmp_state;
++ int state, local_port, remote_port, tmp_state;
+ unsigned long long inode;
+ size_t buf_len, offset;
+ char local_addr[48], remote_addr[48];
+diff --git a/agent/mibgroup/tlstm-mib/snmpTlstmAddrTable/snmpTlstmAddrTable.c b/agent/mibgroup/tlstm-mib/snmpTlstmAddrTable/snmpTlstmAddrTable.c
+index f8df440..5493ff9 100644
+--- a/agent/mibgroup/tlstm-mib/snmpTlstmAddrTable/snmpTlstmAddrTable.c
++++ b/agent/mibgroup/tlstm-mib/snmpTlstmAddrTable/snmpTlstmAddrTable.c
+@@ -1415,8 +1415,7 @@ _tlstmAddrTable_row_restore_mib(const char *token, char *buf)
+ addr->hashType = hashType;
+ addr->flags = TLSTM_ADDR_FROM_MIB | TLSTM_ADDR_NONVOLATILE;
+
+- if (netsnmp_tlstmAddr_add(addr) != 0)
+- netsnmp_tlstmAddr_free(addr);
++ netsnmp_tlstmAddr_add(addr);
+ }
+ else {
+ netsnmp_tdata_row *row;
+diff --git a/agent/mibgroup/tlstm-mib/snmpTlstmParamsTable/snmpTlstmParamsTable.c b/agent/mibgroup/tlstm-mib/snmpTlstmParamsTable/snmpTlstmParamsTable.c
+index 7027114..cd54452 100644
+--- a/agent/mibgroup/tlstm-mib/snmpTlstmParamsTable/snmpTlstmParamsTable.c
++++ b/agent/mibgroup/tlstm-mib/snmpTlstmParamsTable/snmpTlstmParamsTable.c
+@@ -1275,7 +1275,7 @@ _tlstmParamsTable_row_restore_mib(const char *token, char *buf)
+ entry = row->data;
+
+ entry->hashType = params->hashType;
+- strncpy(entry->snmpTlstmParamsClientFingerprint,params->fingerprint,
++ strlcpy(entry->snmpTlstmParamsClientFingerprint, params->fingerprint,
+ sizeof(entry->snmpTlstmParamsClientFingerprint));
+ entry->snmpTlstmParamsClientFingerprint_len =
+ strlen(entry->snmpTlstmParamsClientFingerprint);
+diff --git a/agent/mibgroup/ucd-snmp/disk.c b/agent/mibgroup/ucd-snmp/disk.c
+index 70f67f5..324fbc4 100644
+--- a/agent/mibgroup/ucd-snmp/disk.c
++++ b/agent/mibgroup/ucd-snmp/disk.c
+@@ -409,9 +409,8 @@ add_device(char *path, char *device, int minspace, int minpercent, int override)
+ /* add if and only if the device was found */
+ if(device[0] != 0) {
+ /* The following buffers are cleared above, no need to add '\0' */
+- strncpy(disks[numdisks].path, path, sizeof(disks[numdisks].path) - 1);
+- strncpy(disks[numdisks].device, device,
+- sizeof(disks[numdisks].device) - 1);
++ strlcpy(disks[numdisks].path, path, sizeof(disks[numdisks].path));
++ strlcpy(disks[numdisks].device, device, sizeof(disks[numdisks].device));
+ disks[numdisks].minimumspace = minspace;
+ disks[numdisks].minpercent = minpercent;
+ numdisks++;
+@@ -595,8 +594,7 @@ find_device(char *path)
+ }
+ while (mntfp && NULL != (mntent = getmntent(mntfp)))
+ if (strcmp(path, mntent->mnt_dir) == 0) {
+- strncpy(device, mntent->mnt_fsname, sizeof(device));
+- device[sizeof(device) - 1] = '\0';
++ strlcpy(device, mntent->mnt_fsname, sizeof(device));
+ DEBUGMSGTL(("ucd-snmp/disk", "Disk: %s\n",
+ mntent->mnt_fsname));
+ break;
+@@ -620,18 +618,14 @@ find_device(char *path)
+ path, mnttab.mnt_mountp));
+ }
+ fclose(mntfp);
+- if (i == 0) {
+- strncpy(device, mnttab.mnt_special, sizeof(device));
+- device[sizeof(device) - 1] = '\0';
+- }
++ if (i == 0)
++ strlcpy(device, mnttab.mnt_special, sizeof(device));
+ #endif /* HAVE_SETMNTENT */
+ #elif HAVE_FSTAB_H
+ stat(path, &stat1);
+ setfsent();
+- if ((fstab = getfsfile(path))) {
+- strncpy(device, fstab->fs_spec, sizeof(device));
+- device[sizeof(device) - 1] = '\0';
+- }
++ if ((fstab = getfsfile(path)))
++ strlcpy(device, fstab->fs_spec, sizeof(device));
+ endfsent();
+ if (device[0] != '\0') {
+ /*
+@@ -641,8 +635,7 @@ find_device(char *path)
+
+ #elif HAVE_STATFS
+ if (statfs(path, &statf) == 0) {
+- strncpy(device, statf.f_mntfromname, sizeof(device) - 1);
+- device[sizeof(device) - 1] = '\0';
++ strlcpy(device, statf.f_mntfromname, sizeof(device));
+ DEBUGMSGTL(("ucd-snmp/disk", "Disk: %s\n",
+ statf.f_mntfromname));
+ }
+diff --git a/agent/mibgroup/ucd-snmp/disk_hw.c b/agent/mibgroup/ucd-snmp/disk_hw.c
+index 6fb9418..ba26479 100644
+--- a/agent/mibgroup/ucd-snmp/disk_hw.c
++++ b/agent/mibgroup/ucd-snmp/disk_hw.c
+@@ -1,5 +1,5 @@
+ /*
+- * disk.c
++ * disk_hw.c
+ */
+
+ #include <net-snmp/net-snmp-config.h>
+@@ -137,6 +137,7 @@ disk_free_config(void)
+ if (disks) {
+ free( disks );
+ disks = NULL;
++ maxdisks = numdisks = 0;
+ }
+ allDisksIncluded = 0;
+ }
+@@ -321,7 +322,7 @@ tryAgain:
+
+ switch (vp->magic) {
+ case MIBINDEX:
+- long_ret = disknum;
++ long_ret = disknum + 1;
+ return ((u_char *) (&long_ret));
+ case ERRORNAME: /* DISKPATH */
+ *var_len = strlen(entry->path);
+diff --git a/agent/mibgroup/ucd-snmp/diskio.c b/agent/mibgroup/ucd-snmp/diskio.c
+index 769a365..4d6d05c 100644
+--- a/agent/mibgroup/ucd-snmp/diskio.c
++++ b/agent/mibgroup/ucd-snmp/diskio.c
+@@ -502,7 +502,8 @@ getstats(void)
+ {
+ time_t now;
+ char *t, *tp;
+- int size, dkn_size, i;
++ size_t size, dkn_size;
++ int i;
+
+ now = time(NULL);
+ if (cache_time + CACHE_TIMEOUT > now) {
+@@ -526,6 +527,7 @@ getstats(void)
+ if (ndisk == 0)
+ return 0;
+ dkname = malloc(ndisk * sizeof(char *));
++ dkn_size = 0;
+ if (sysctl(nmib, 2, NULL, &dkn_size, NULL, 0) < 0) {
+ perror("Can't get size of HW_DISKNAMES mib");
+ return 0;
+diff --git a/agent/mibgroup/ucd-snmp/dlmod.c b/agent/mibgroup/ucd-snmp/dlmod.c
+index eecd38f..e9742f2 100644
+--- a/agent/mibgroup/ucd-snmp/dlmod.c
++++ b/agent/mibgroup/ucd-snmp/dlmod.c
+@@ -18,8 +18,6 @@
+ #include <net-snmp/net-snmp-includes.h>
+ #include <net-snmp/agent/net-snmp-agent-includes.h>
+
+-#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
+-
+ #include <dlfcn.h>
+ #include "dlmod.h"
+
+@@ -124,7 +122,7 @@ dlmod_load_module(struct dlmod *dlm)
+ dlm->status = DLMOD_ERROR;
+ }
+ }
+- strncpy(dlm->path, tmp_path, sizeof(dlm->path));
++ strlcpy(dlm->path, tmp_path, sizeof(dlm->path));
+ if (dlm->status == DLMOD_ERROR)
+ return;
+ }
+@@ -219,16 +217,16 @@ dlmod_parse_config(const char *token, char *cptr)
+ dlmod_delete_module(dlm);
+ return;
+ }
+- strncpy(dlm->name, dlm_name, sizeof(dlm->name));
++ strlcpy(dlm->name, dlm_name, sizeof(dlm->name));
+
+ /*
+ * dynamic module path
+ */
+ dlm_path = strtok_r(NULL, "\t ", &st);
+ if (dlm_path)
+- strncpy(dlm->path, dlm_path, sizeof(dlm->path));
++ strlcpy(dlm->path, dlm_path, sizeof(dlm->path));
+ else
+- strncpy(dlm->path, dlm_name, sizeof(dlm->path));
++ strlcpy(dlm->path, dlm_name, sizeof(dlm->path));
+
+ dlmod_load_module(dlm);
+
+@@ -573,9 +571,6 @@ static oid dlmod_variables_oid[] = { 1, 3, 6, 1, 4, 1, 2021, 13, 14 };
+ void
+ init_dlmod(void)
+ {
+- char *p;
+- int len;
+-
+ REGISTER_MIB("dlmod", dlmod_variables, variable4, dlmod_variables_oid);
+
+ /*
+@@ -588,20 +583,23 @@ init_dlmod(void)
+ dlmod_free_config,
+ "module-name module-path");
+
+- p = getenv("SNMPDLMODPATH");
+- strncpy(dlmod_path, SNMPDLMODPATH, sizeof(dlmod_path));
+- dlmod_path[ sizeof(dlmod_path)-1 ] = 0;
+- if (p) {
+- if (p[0] == ':') {
+- len = strlen(dlmod_path);
+- if (dlmod_path[len - 1] != ':') {
+- strncat(dlmod_path, ":", sizeof(dlmod_path) - len -1);
+- len++;
+- }
+- strncat(dlmod_path, p + 1, sizeof(dlmod_path) - len);
+- } else
+- strncpy(dlmod_path, p, sizeof(dlmod_path));
++ {
++ const char * const p = getenv("SNMPDLMODPATH");
++ strncpy(dlmod_path, SNMPDLMODPATH, sizeof(dlmod_path));
++ dlmod_path[ sizeof(dlmod_path) - 1 ] = 0;
++ if (p) {
++ if (p[0] == ':') {
++ int len = strlen(dlmod_path);
++ if (dlmod_path[len - 1] != ':') {
++ strncat(dlmod_path, ":", sizeof(dlmod_path) - len - 1);
++ len++;
++ }
++ strncat(dlmod_path, p + 1, sizeof(dlmod_path) - len);
++ } else
++ strncpy(dlmod_path, p, sizeof(dlmod_path));
++ }
+ }
++
+ dlmod_path[ sizeof(dlmod_path)-1 ] = 0;
+ DEBUGMSGTL(("dlmod", "dlmod_path: %s\n", dlmod_path));
+ }
+@@ -614,19 +612,3 @@ shutdown_dlmod(void)
+ snmpd_unregister_config_handler("dlmod");
+ unregister_mib(dlmod_variables_oid, OID_LENGTH(dlmod_variables_oid));
+ }
+-
+-#else /* no dlopen support */
+-
+-void
+-init_dlmod(void)
+-{
+- DEBUGMSGTL(("dlmod",
+- "Dynamic modules not support on this platform\n"));
+-}
+-
+-void
+-shutdown_dlmod(void)
+-{
+-}
+-
+-#endif
+diff --git a/agent/mibgroup/ucd-snmp/dlmod.h b/agent/mibgroup/ucd-snmp/dlmod.h
+index 79d960b..df8bef7 100644
+--- a/agent/mibgroup/ucd-snmp/dlmod.h
++++ b/agent/mibgroup/ucd-snmp/dlmod.h
+@@ -6,6 +6,10 @@
+ #ifndef MIBGROUP_DLMOD_H
+ #define MIBGROUP_DLMOD_H
+
++#if !defined(HAVE_DLFCN_H) || !defined(HAVE_DLOPEN)
++config_error(Dynamic modules not supported on this platform)
++#endif
++
+ config_add_mib(UCD-DLMOD-MIB)
+
+ void init_dlmod(void);
+diff --git a/agent/mibgroup/ucd-snmp/errormib.c b/agent/mibgroup/ucd-snmp/errormib.c
+index cbdd25b..7f3bcb1 100644
+--- a/agent/mibgroup/ucd-snmp/errormib.c
++++ b/agent/mibgroup/ucd-snmp/errormib.c
+@@ -137,8 +137,7 @@ seterrorstatus(const char *to, int prior)
+ {
+ if (errorstatusprior <= prior ||
+ (NETSNMP_ERRORTIMELENGTH < (time(NULL) - errorstatustime))) {
+- strncpy(errorstring, to, sizeof(errorstring));
+- errorstring[ sizeof(errorstring)-1 ] = 0;
++ strlcpy(errorstring, to, sizeof(errorstring));
+ errorstatusprior = prior;
+ errorstatustime = time(NULL);
+ }
+@@ -219,8 +218,7 @@ var_extensible_errors(struct variable *vp,
+ return ((u_char *) (&long_ret));
+ case ERRORMSG:
+ if ((NETSNMP_ERRORTIMELENGTH >= time(NULL) - errorstatustime) ? 1 : 0) {
+- strncpy(errmsg, errorstring, sizeof(errmsg));
+- errmsg[ sizeof(errmsg)-1 ] = 0;
++ strlcpy(errmsg, errorstring, sizeof(errmsg));
+ } else
+ errmsg[0] = 0;
+ *var_len = strlen(errmsg);
+diff --git a/agent/mibgroup/ucd-snmp/extensible.c b/agent/mibgroup/ucd-snmp/extensible.c
+index edea93a..d1752ef 100644
+--- a/agent/mibgroup/ucd-snmp/extensible.c
++++ b/agent/mibgroup/ucd-snmp/extensible.c
+@@ -262,8 +262,7 @@ extensible_parse_config(const char *token, char *cptr)
+ for (tcptr = cptr; *tcptr != 0 && *tcptr != '#'; tcptr++)
+ if (*tcptr == ';' && ptmp->type == EXECPROC)
+ break;
+- strncpy(ptmp->command, cptr, tcptr - cptr);
+- ptmp->command[tcptr - cptr] = 0;
++ sprintf(ptmp->command, "%.*s", (int) (tcptr - cptr), cptr);
+ }
+ #ifdef NETSNMP_EXECFIXCMD
+ sprintf(ptmp->fixcmd, NETSNMP_EXECFIXCMD, ptmp->name);
+@@ -419,8 +418,7 @@ execfix_parse_config(const char *token, char *cptr)
+ return;
+ }
+
+- strncpy(execp->fixcmd, cptr, sizeof(execp->fixcmd));
+- execp->fixcmd[ sizeof(execp->fixcmd)-1 ] = 0;
++ strlcpy(execp->fixcmd, cptr, sizeof(execp->fixcmd));
+ }
+
+ u_char *
+@@ -623,8 +621,7 @@ var_extensible_relocatable(struct variable *vp,
+ cp = strchr(cp1, '\n');
+ if (cp)
+ *cp = 0;
+- strncpy(errmsg, cp1, sizeof(errmsg));
+- errmsg[ sizeof(errmsg)-1 ] = 0;
++ strlcpy(errmsg, cp1, sizeof(errmsg));
+ *var_len = strlen(errmsg);
+ if (errmsg[*var_len - 1] == '\n')
+ errmsg[--(*var_len)] = '\0';
+diff --git a/agent/mibgroup/ucd-snmp/lmSensors.c b/agent/mibgroup/ucd-snmp/lmSensors.c
+index d6436bf..05c60b7 100644
+--- a/agent/mibgroup/ucd-snmp/lmSensors.c
++++ b/agent/mibgroup/ucd-snmp/lmSensors.c
+@@ -331,7 +331,7 @@ var_lmSensorsTable(struct variable *vp,
+ case LMFANSENSORSDEVICE:
+ case LMVOLTSENSORSDEVICE:
+ case LMMISCSENSORSDEVICE:
+- strncpy(string, s.name, SPRINT_MAX_LEN - 1);
++ strlcpy(string, s.name, sizeof(string));
+ *var_len = strlen(string);
+ ret = (unsigned char *) string;
+ goto leaving;
+@@ -891,32 +891,32 @@ else{
+ DEBUGMSG(("ucd-snmp/lmSensors", "front panel value %d\n",enc_info->value));
+ typ = 3; /* misc */
+ sensor_array[typ].sensor[other].value = enc_info->value;
+- strncpy(sensor_array[typ].sensor[other].name,"FSP",MAX_NAME-1);
+- sensor_array[typ].sensor[other].name[MAX_NAME-1]='\0'; /* null terminate */
++ strlcpy(sensor_array[typ].sensor[other].name, "FSP",
++ MAX_NAME);
+ other++;
+ break;
+ case ENVCTRL_ENCL_AMBTEMPR:
+ DEBUGMSG(("ucd-snmp/lmSensors", "ambient temp mC %d\n",enc_info->value*1000));
+ typ = 0; /* temperature sensor */
+ sensor_array[typ].sensor[temp].value = enc_info->value*1000;
+- strncpy(sensor_array[typ].sensor[temp].name,"Ambient",MAX_NAME-1);
+- sensor_array[typ].sensor[temp].name[MAX_NAME-1]='\0'; /* null terminate */
++ strlcpy(sensor_array[typ].sensor[temp].name, "Ambient",
++ MAX_NAME);
+ temp++;
+ break;
+ case ENVCTRL_ENCL_BACKPLANE4:
+ DEBUGMSG(("ucd-snmp/lmSensors", "There is a backplane4\n"));
+ typ = 3; /* misc */
+ sensor_array[typ].sensor[other].value = enc_info->value;
+- strncpy(sensor_array[typ].sensor[other].name,"Backplane4",MAX_NAME-1);
+- sensor_array[typ].sensor[other].name[MAX_NAME-1]='\0'; /* null terminate */
++ strlcpy(sensor_array[typ].sensor[other].name, "Backplane4",
++ MAX_NAME);
+ other++;
+ break;
+ case ENVCTRL_ENCL_BACKPLANE8:
+ DEBUGMSG(("ucd-snmp/lmSensors", "There is a backplane8\n"));
+ typ = 3; /* misc */
+ sensor_array[typ].sensor[other].value = enc_info->value;
+- strncpy(sensor_array[typ].sensor[other].name,"Backplane8",MAX_NAME-1);
+- sensor_array[typ].sensor[other].name[MAX_NAME-1]='\0'; /* null terminate */
++ strlcpy(sensor_array[typ].sensor[other].name, "Backplane8",
++ MAX_NAME);
+ other++;
+ break;
+ case ENVCTRL_ENCL_CPUTEMPR:
+@@ -1029,7 +1029,7 @@ else{
+ array->current_len = new_size / sizeof(_sensor);
+ DEBUGMSG(("ucd-snmp/lmSensors", "type #%d increased to %d elements\n", type, (int)array->current_len));
+ } /* end if array->current */
+- strncpy(array->sensor[array->n].name, label, MAX_NAME);
++ strlcpy(array->sensor[array->n].name, label, MAX_NAME);
+ array->sensor[array->n].value = (int) (val * mul);
+ DEBUGMSGTL(("sensors","sensor %s, value %d\n",
+ array->sensor[array->n].name,
+diff --git a/agent/mibgroup/ucd-snmp/loadave.c b/agent/mibgroup/ucd-snmp/loadave.c
+index 2321d29..6efc5e9 100644
+--- a/agent/mibgroup/ucd-snmp/loadave.c
++++ b/agent/mibgroup/ucd-snmp/loadave.c
+@@ -393,8 +393,7 @@ write_laConfig(int action,
+ double val;
+ char *endp;
+
+- strncpy(buf, (char *)var_val, var_val_len);
+- buf[var_val_len] = '\0';
++ sprintf(buf, "%.*s", (int) var_val_len, (char *)var_val);
+ val = strtod(buf, &endp);
+
+ if (errno == ERANGE || *endp != '\0' || val < 0 || val > 65536.00) {
+@@ -481,10 +480,12 @@ var_extensible_loadave(struct variable * vp,
+ if (maxload[name[*length - 1] - 1] != 0 &&
+ avenrun[name[*length - 1] - 1] >=
+ maxload[name[*length - 1] - 1]) {
+- sprintf(errmsg, "%d min Load Average too high (= %.2f)",
++ snprintf(errmsg, sizeof(errmsg),
++ "%d min Load Average too high (= %.2f)",
+ (name[*length - 1] ==
+ 1) ? 1 : ((name[*length - 1] == 2) ? 5 : 15),
+ avenrun[name[*length - 1] - 1]);
++ errmsg[sizeof(errmsg) - 1] = '\0';
+ } else {
+ errmsg[0] = 0;
+ }
+diff --git a/agent/mibgroup/ucd-snmp/logmatch.c b/agent/mibgroup/ucd-snmp/logmatch.c
+index eb21a68..abca5ce 100644
+--- a/agent/mibgroup/ucd-snmp/logmatch.c
++++ b/agent/mibgroup/ucd-snmp/logmatch.c
+@@ -110,7 +110,6 @@ static void
+ updateLogmatch(int iindex)
+ {
+
+- regmatch_t myMatch;
+ int matchResultCode;
+ char inbuf[1024];
+ char perfilename[1024];
+@@ -288,7 +287,7 @@ updateLogmatch(int iindex)
+
+ matchResultCode =
+ regexec(&(logmatchTable[iindex].regexBuffer),
+- inbuf, 0, &myMatch, REG_NOTEOL);
++ inbuf, 0, NULL, REG_NOTEOL);
+
+ if (matchResultCode == 0) {
+ logmatchTable[iindex].globalMatchCounter++;
+diff --git a/agent/mibgroup/ucd-snmp/pass.c b/agent/mibgroup/ucd-snmp/pass.c
+index 4440baa..ac14b41 100644
+--- a/agent/mibgroup/ucd-snmp/pass.c
++++ b/agent/mibgroup/ucd-snmp/pass.c
+@@ -33,6 +33,7 @@
+
+ #include "struct.h"
+ #include "pass.h"
++#include "pass_common.h"
+ #include "extensible.h"
+ #include "util_funcs.h"
+
+@@ -55,152 +56,6 @@ struct variable2 extensible_passthru_variables[] = {
+
+
+
+-/*
+- * lexicographical compare two object identifiers.
+- * * Returns -1 if name1 < name2,
+- * * 0 if name1 = name2,
+- * * 1 if name1 > name2
+- * *
+- * * This method differs from snmp_oid_compare
+- * * in that the comparison stops at the length
+- * * of the smallest object identifier.
+- */
+-int
+-snmp_oid_min_compare(const oid * in_name1,
+- size_t len1, const oid * in_name2, size_t len2)
+-{
+- register int len;
+- register const oid *name1 = in_name1;
+- register const oid *name2 = in_name2;
+-
+- /*
+- * len = minimum of len1 and len2
+- */
+- if (len1 < len2)
+- len = len1;
+- else
+- len = len2;
+- /*
+- * find first non-matching OID
+- */
+- while (len-- > 0) {
+- /*
+- * these must be done in seperate comparisons, since
+- * subtracting them and using that result has problems with
+- * subids > 2^31.
+- */
+- if (*(name1) < *(name2))
+- return -1;
+- if (*(name1++) > *(name2++))
+- return 1;
+- }
+- /*
+- * both OIDs equal up to length of shorter OID
+- */
+-
+- return 0;
+-}
+-
+-
+-/*
+- * This is also called from pass_persist.c
+- */
+-int
+-asc2bin(char *p)
+-{
+- char *r, *q = p;
+- char c;
+- int n = 0;
+-
+- for (;;) {
+- c = (char) strtol(q, &r, 16);
+- if (r == q)
+- break;
+- *p++ = c;
+- q = r;
+- n++;
+- }
+- return n;
+-}
+-
+-/*
+- * This is also called from pass_persist.c
+- */
+-int
+-bin2asc(char *p, size_t n)
+-{
+- size_t i, flag = 0;
+- char buffer[SNMP_MAXBUF];
+-
+- /* prevent buffer overflow */
+- if (n > (sizeof(buffer) - 1))
+- n = sizeof(buffer) - 1;
+-
+- for (i = 0; i < n; i++) {
+- buffer[i] = p[i];
+- if (!isprint((unsigned char)(p[i])))
+- flag = 1;
+- }
+- if (flag == 0) {
+- p[n] = 0;
+- return n;
+- }
+- for (i = 0; i < n; i++) {
+- sprintf(p, "%02x ", (unsigned char) (buffer[i] & 0xff));
+- p += 3;
+- }
+- *--p = 0;
+- return 3 * n - 1;
+-}
+-
+-/*
+- * This is also called from pass_persist.c
+- */
+-int
+-netsnmp_pass_str_to_errno(const char *buf)
+-{
+- if (!strncasecmp(buf, "too-big", 7)) {
+- /* Shouldn't happen */
+- return SNMP_ERR_TOOBIG;
+- } else if (!strncasecmp(buf, "no-such-name", 12)) {
+- return SNMP_ERR_NOSUCHNAME;
+- } else if (!strncasecmp(buf, "bad-value", 9)) {
+- return SNMP_ERR_BADVALUE;
+- } else if (!strncasecmp(buf, "read-only", 9)) {
+- return SNMP_ERR_READONLY;
+- } else if (!strncasecmp(buf, "gen-error", 9)) {
+- return SNMP_ERR_GENERR;
+- } else if (!strncasecmp(buf, "no-access", 9)) {
+- return SNMP_ERR_NOACCESS;
+- } else if (!strncasecmp(buf, "wrong-type", 10)) {
+- return SNMP_ERR_WRONGTYPE;
+- } else if (!strncasecmp(buf, "wrong-length", 12)) {
+- return SNMP_ERR_WRONGLENGTH;
+- } else if (!strncasecmp(buf, "wrong-encoding", 14)) {
+- return SNMP_ERR_WRONGENCODING;
+- } else if (!strncasecmp(buf, "wrong-value", 11)) {
+- return SNMP_ERR_WRONGVALUE;
+- } else if (!strncasecmp(buf, "no-creation", 11)) {
+- return SNMP_ERR_NOCREATION;
+- } else if (!strncasecmp(buf, "inconsistent-value", 18)) {
+- return SNMP_ERR_INCONSISTENTVALUE;
+- } else if (!strncasecmp(buf, "resource-unavailable", 20)) {
+- return SNMP_ERR_RESOURCEUNAVAILABLE;
+- } else if (!strncasecmp(buf, "commit-failed", 13)) {
+- return SNMP_ERR_COMMITFAILED;
+- } else if (!strncasecmp(buf, "undo-failed", 11)) {
+- return SNMP_ERR_UNDOFAILED;
+- } else if (!strncasecmp(buf, "authorization-error", 19)) {
+- return SNMP_ERR_AUTHORIZATIONERROR;
+- } else if (!strncasecmp(buf, "not-writable", 12)) {
+- return SNMP_ERR_NOTWRITABLE;
+- } else if (!strncasecmp(buf, "inconsistent-name", 17)) {
+- return SNMP_ERR_INCONSISTENTNAME;
+- }
+-
+- return SNMP_ERR_NOERROR;
+-}
+-
+ void
+ init_pass(void)
+ {
+@@ -276,11 +131,9 @@ pass_parse_config(const char *token, char *cptr)
+ } else {
+ for (tcptr = cptr; *tcptr != 0 && *tcptr != '#' && *tcptr != ';';
+ tcptr++);
+- strncpy((*ppass)->command, cptr, tcptr - cptr);
+- (*ppass)->command[tcptr - cptr] = 0;
++ sprintf((*ppass)->command, "%.*s", (int) (tcptr - cptr), cptr);
+ }
+- strncpy((*ppass)->name, (*ppass)->command, sizeof((*ppass)->name));
+- (*ppass)->name[ sizeof((*ppass)->name)-1 ] = 0;
++ strlcpy((*ppass)->name, (*ppass)->command, sizeof((*ppass)->name));
+ (*ppass)->next = NULL;
+
+ register_mib_priority("pass", (struct variable *) extensible_passthru_variables,
+@@ -337,18 +190,14 @@ var_extensible_pass(struct variable *vp,
+ {
+ oid newname[MAX_OID_LEN];
+ int i, rtest, fd, newlen;
+- static long long_ret;
+- static in_addr_t addr_ret;
+ char buf[SNMP_MAXBUF];
+ static char buf2[SNMP_MAXBUF];
+- static oid objid[MAX_OID_LEN];
+ struct extensible *passthru;
+ FILE *file;
+
+- long_ret = *length;
+ for (i = 1; i <= numpassthrus; i++) {
+ passthru = get_exten_instance(passthrus, i);
+- rtest = snmp_oid_min_compare(name, *length,
++ rtest = snmp_oidtree_compare(name, *length,
+ passthru->miboid, passthru->miblen);
+ if ((exact && rtest == 0) || (!exact && rtest <= 0)) {
+ /*
+@@ -409,89 +258,7 @@ var_extensible_pass(struct variable *vp,
+ fclose(file);
+ wait_on_exec(passthru);
+
+- /*
+- * buf contains the return type, and buf2 contains the data
+- */
+- if (!strncasecmp(buf, "string", 6)) {
+- buf2[strlen(buf2) - 1] = 0; /* zap the linefeed */
+- *var_len = strlen(buf2);
+- vp->type = ASN_OCTET_STR;
+- return ((unsigned char *) buf2);
+- }
+- else if (!strncasecmp(buf, "integer64", 9)) {
+- static struct counter64 c64;
+- uint64_t v64 = strtoull(buf2, NULL, 10);
+- c64.high = (unsigned long)(v64 >> 32);
+- c64.low = (unsigned long)(v64 & 0xffffffff);
+- *var_len = sizeof(c64);
+- vp->type = ASN_INTEGER64;
+- return ((unsigned char *) &c64);
+- }
+- else if (!strncasecmp(buf, "integer", 7)) {
+- *var_len = sizeof(long_ret);
+- long_ret = strtol(buf2, NULL, 10);
+- vp->type = ASN_INTEGER;
+- return ((unsigned char *) &long_ret);
+- } else if (!strncasecmp(buf, "unsigned", 8)) {
+- *var_len = sizeof(long_ret);
+- long_ret = strtoul(buf2, NULL, 10);
+- vp->type = ASN_UNSIGNED;
+- return ((unsigned char *) &long_ret);
+- }
+- else if (!strncasecmp(buf, "counter64", 9)) {
+- static struct counter64 c64;
+- uint64_t v64 = strtoull(buf2, NULL, 10);
+- c64.high = (unsigned long)(v64 >> 32);
+- c64.low = (unsigned long)(v64 & 0xffffffff);
+- *var_len = sizeof(c64);
+- vp->type = ASN_COUNTER64;
+- return ((unsigned char *) &c64);
+- }
+- else if (!strncasecmp(buf, "counter", 7)) {
+- *var_len = sizeof(long_ret);
+- long_ret = strtoul(buf2, NULL, 10);
+- vp->type = ASN_COUNTER;
+- return ((unsigned char *) &long_ret);
+- } else if (!strncasecmp(buf, "octet", 5)) {
+- *var_len = asc2bin(buf2);
+- vp->type = ASN_OCTET_STR;
+- return ((unsigned char *) buf2);
+- } else if (!strncasecmp(buf, "opaque", 6)) {
+- *var_len = asc2bin(buf2);
+- vp->type = ASN_OPAQUE;
+- return ((unsigned char *) buf2);
+- } else if (!strncasecmp(buf, "gauge", 5)) {
+- *var_len = sizeof(long_ret);
+- long_ret = strtoul(buf2, NULL, 10);
+- vp->type = ASN_GAUGE;
+- return ((unsigned char *) &long_ret);
+- } else if (!strncasecmp(buf, "objectid", 8)) {
+- newlen = parse_miboid(buf2, objid);
+- *var_len = newlen * sizeof(oid);
+- vp->type = ASN_OBJECT_ID;
+- return ((unsigned char *) objid);
+- } else if (!strncasecmp(buf, "timetick", 8)) {
+- *var_len = sizeof(long_ret);
+- long_ret = strtoul(buf2, NULL, 10);
+- vp->type = ASN_TIMETICKS;
+- return ((unsigned char *) &long_ret);
+- } else if (!strncasecmp(buf, "ipaddress", 9)) {
+- newlen = parse_miboid(buf2, objid);
+- if (newlen != 4) {
+- snmp_log(LOG_ERR,
+- "invalid ipaddress returned: %s\n",
+- buf2);
+- *var_len = 0;
+- return (NULL);
+- }
+- addr_ret =
+- (objid[0] << (8 * 3)) + (objid[1] << (8 * 2)) +
+- (objid[2] << 8) + objid[3];
+- addr_ret = htonl(addr_ret);
+- *var_len = sizeof(addr_ret);
+- vp->type = ASN_IPADDRESS;
+- return ((unsigned char *) &addr_ret);
+- }
++ return netsnmp_internal_pass_parse(buf, buf2, var_len, vp);
+ }
+ *var_len = 0;
+ return (NULL);
+@@ -504,21 +271,16 @@ var_extensible_pass(struct variable *vp,
+ }
+
+ int
+-setPass(int action,
+- u_char * var_val,
+- u_char var_val_type,
++setPass(int action, u_char * var_val, u_char var_val_type,
+ size_t var_val_len, u_char * statP, oid * name, size_t name_len)
+ {
+ int i, rtest;
+ struct extensible *passthru;
+-
+ char buf[SNMP_MAXBUF], buf2[SNMP_MAXBUF];
+- long tmp;
+- unsigned long utmp;
+
+ for (i = 1; i <= numpassthrus; i++) {
+ passthru = get_exten_instance(passthrus, i);
+- rtest = snmp_oid_min_compare(name, name_len,
++ rtest = snmp_oidtree_compare(name, name_len,
+ passthru->miboid, passthru->miblen);
+ if (rtest <= 0) {
+ if (action != ACTION)
+@@ -533,60 +295,14 @@ setPass(int action,
+ snprintf(passthru->command, sizeof(passthru->command),
+ "%s -s %s ", passthru->name, buf);
+ passthru->command[ sizeof(passthru->command)-1 ] = 0;
+- switch (var_val_type) {
+- case ASN_INTEGER:
+- case ASN_COUNTER:
+- case ASN_GAUGE:
+- case ASN_TIMETICKS:
+- tmp = *((long *) var_val);
+- switch (var_val_type) {
+- case ASN_INTEGER:
+- sprintf(buf, "integer %d\n", (int) tmp);
+- break;
+- case ASN_COUNTER:
+- sprintf(buf, "counter %d\n", (int) tmp);
+- break;
+- case ASN_GAUGE:
+- sprintf(buf, "gauge %d\n", (int) tmp);
+- break;
+- case ASN_TIMETICKS:
+- sprintf(buf, "timeticks %d\n", (int) tmp);
+- break;
+- }
+- break;
+- case ASN_IPADDRESS:
+- utmp = *((u_long *) var_val);
+- utmp = ntohl(utmp);
+- sprintf(buf, "ipaddress %d.%d.%d.%d\n",
+- (int) ((utmp & 0xff000000) >> (8 * 3)),
+- (int) ((utmp & 0xff0000) >> (8 * 2)),
+- (int) ((utmp & 0xff00) >> (8)),
+- (int) ((utmp & 0xff)));
+- break;
+- case ASN_OCTET_STR:
+- memcpy(buf2, var_val, var_val_len);
+- if (var_val_len == 0)
+- sprintf(buf, "string \"\"\n");
+- else if (bin2asc(buf2, var_val_len) == (int) var_val_len)
+- snprintf(buf, sizeof(buf), "string \"%s\"\n", buf2);
+- else
+- snprintf(buf, sizeof(buf), "octet \"%s\"\n", buf2);
+- buf[ sizeof(buf)-1 ] = 0;
+- break;
+- case ASN_OBJECT_ID:
+- sprint_mib_oid(buf2, (oid *) var_val, var_val_len/sizeof(oid));
+- snprintf(buf, sizeof(buf), "objectid \"%s\"\n", buf2);
+- buf[ sizeof(buf)-1 ] = 0;
+- break;
+- }
+- strncat(passthru->command, buf, sizeof(passthru->command)-strlen(passthru->command)-1);
+- passthru->command[ sizeof(passthru->command)-1 ] = 0;
++ netsnmp_internal_pass_set_format(buf, var_val, var_val_type, var_val_len);
++ strlcat(passthru->command, buf, sizeof(passthru->command));
+ DEBUGMSGTL(("ucd-snmp/pass", "pass-running: %s",
+ passthru->command));
+ exec_command(passthru);
+ DEBUGMSGTL(("ucd-snmp/pass", "pass-running returned: %s",
+ passthru->output));
+- return netsnmp_pass_str_to_errno(passthru->output);
++ return netsnmp_internal_pass_str_to_errno(passthru->output);
+ }
+ }
+ if (snmp_get_do_debugging()) {
+diff --git a/agent/mibgroup/ucd-snmp/pass.h b/agent/mibgroup/ucd-snmp/pass.h
+index 089c9ca..51c0689 100644
+--- a/agent/mibgroup/ucd-snmp/pass.h
++++ b/agent/mibgroup/ucd-snmp/pass.h
+@@ -6,7 +6,9 @@
+
+ void init_pass(void);
+
++config_require(ucd-snmp/pass_common)
+ config_require(util_funcs)
++config_require(utilities/execute)
+ config_add_mib(NET-SNMP-PASS-MIB)
+
+ extern FindVarMethod var_extensible_pass;
+diff --git a/agent/mibgroup/ucd-snmp/pass_common.c b/agent/mibgroup/ucd-snmp/pass_common.c
+new file mode 100644
+index 0000000..38a0443
+--- /dev/null
++++ b/agent/mibgroup/ucd-snmp/pass_common.c
+@@ -0,0 +1,264 @@
++#include <net-snmp/net-snmp-config.h>
++
++#include <ctype.h>
++#if HAVE_STDDEF_H
++#include <stddef.h>
++#endif
++#include <stdio.h>
++#if HAVE_STRING_H
++#include <string.h>
++#else
++#include <strings.h>
++#endif
++
++#include <net-snmp/net-snmp-includes.h>
++#include <net-snmp/agent/net-snmp-agent-includes.h>
++#include "mibgroup/util_funcs.h"
++#include "pass_common.h"
++
++static int
++netsnmp_internal_asc2bin(char *p)
++{
++ char *r, *q = p;
++ char c;
++ int n = 0;
++
++ for (;;) {
++ c = (char) strtol(q, &r, 16);
++ if (r == q)
++ break;
++ *p++ = c;
++ q = r;
++ n++;
++ }
++ return n;
++}
++
++static int
++netsnmp_internal_bin2asc(char *p, size_t n)
++{
++ int i, flag = 0;
++ char buffer[SNMP_MAXBUF];
++
++ /* prevent buffer overflow */
++ if ((int)n > (sizeof(buffer) - 1))
++ n = sizeof(buffer) - 1;
++
++ for (i = 0; i < (int) n; i++) {
++ buffer[i] = p[i];
++ if (!isprint((unsigned char) (p[i])))
++ flag = 1;
++ }
++ if (flag == 0) {
++ p[n] = 0;
++ return n;
++ }
++ for (i = 0; i < (int) n; i++) {
++ sprintf(p, "%02x ", (unsigned char) (buffer[i] & 0xff));
++ p += 3;
++ }
++ *--p = 0;
++ return 3 * n - 1;
++}
++
++int
++netsnmp_internal_pass_str_to_errno(const char *buf)
++{
++ if (!strncasecmp(buf, "too-big", 7)) {
++ /* Shouldn't happen */
++ return SNMP_ERR_TOOBIG;
++ } else if (!strncasecmp(buf, "no-such-name", 12)) {
++ return SNMP_ERR_NOSUCHNAME;
++ } else if (!strncasecmp(buf, "bad-value", 9)) {
++ return SNMP_ERR_BADVALUE;
++ } else if (!strncasecmp(buf, "read-only", 9)) {
++ return SNMP_ERR_READONLY;
++ } else if (!strncasecmp(buf, "gen-error", 9)) {
++ return SNMP_ERR_GENERR;
++ } else if (!strncasecmp(buf, "no-access", 9)) {
++ return SNMP_ERR_NOACCESS;
++ } else if (!strncasecmp(buf, "wrong-type", 10)) {
++ return SNMP_ERR_WRONGTYPE;
++ } else if (!strncasecmp(buf, "wrong-length", 12)) {
++ return SNMP_ERR_WRONGLENGTH;
++ } else if (!strncasecmp(buf, "wrong-encoding", 14)) {
++ return SNMP_ERR_WRONGENCODING;
++ } else if (!strncasecmp(buf, "wrong-value", 11)) {
++ return SNMP_ERR_WRONGVALUE;
++ } else if (!strncasecmp(buf, "no-creation", 11)) {
++ return SNMP_ERR_NOCREATION;
++ } else if (!strncasecmp(buf, "inconsistent-value", 18)) {
++ return SNMP_ERR_INCONSISTENTVALUE;
++ } else if (!strncasecmp(buf, "resource-unavailable", 20)) {
++ return SNMP_ERR_RESOURCEUNAVAILABLE;
++ } else if (!strncasecmp(buf, "commit-failed", 13)) {
++ return SNMP_ERR_COMMITFAILED;
++ } else if (!strncasecmp(buf, "undo-failed", 11)) {
++ return SNMP_ERR_UNDOFAILED;
++ } else if (!strncasecmp(buf, "authorization-error", 19)) {
++ return SNMP_ERR_AUTHORIZATIONERROR;
++ } else if (!strncasecmp(buf, "not-writable", 12)) {
++ return SNMP_ERR_NOTWRITABLE;
++ } else if (!strncasecmp(buf, "inconsistent-name", 17)) {
++ return SNMP_ERR_INCONSISTENTNAME;
++ }
++
++ return SNMP_ERR_NOERROR;
++}
++
++unsigned char *
++netsnmp_internal_pass_parse(char * buf,
++ char * buf2,
++ size_t * var_len,
++ struct variable *vp)
++{
++ static long long_ret;
++ static in_addr_t addr_ret;
++ int newlen;
++ static oid objid[MAX_OID_LEN];
++
++ /*
++ * buf contains the return type, and buf2 contains the data
++ */
++ if (!strncasecmp(buf, "string", 6)) {
++ buf2[strlen(buf2) - 1] = 0; /* zap the linefeed */
++ *var_len = strlen(buf2);
++ vp->type = ASN_OCTET_STR;
++ return ((unsigned char *) buf2);
++ }
++#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
++ else if (!strncasecmp(buf, "integer64", 9)) {
++ static struct counter64 c64;
++ uint64_t v64 = strtoull(buf2, NULL, 10);
++ c64.high = (unsigned long)(v64 >> 32);
++ c64.low = (unsigned long)(v64 & 0xffffffff);
++ *var_len = sizeof(c64);
++ vp->type = ASN_INTEGER64;
++ return ((unsigned char *) &c64);
++ }
++#endif
++ else if (!strncasecmp(buf, "integer", 7)) {
++ *var_len = sizeof(long_ret);
++ long_ret = strtol(buf2, NULL, 10);
++ vp->type = ASN_INTEGER;
++ return ((unsigned char *) &long_ret);
++ } else if (!strncasecmp(buf, "unsigned", 8)) {
++ *var_len = sizeof(long_ret);
++ long_ret = strtoul(buf2, NULL, 10);
++ vp->type = ASN_UNSIGNED;
++ return ((unsigned char *) &long_ret);
++ }
++ else if (!strncasecmp(buf, "counter64", 9)) {
++ static struct counter64 c64;
++ uint64_t v64 = strtoull(buf2, NULL, 10);
++ c64.high = (unsigned long)(v64 >> 32);
++ c64.low = (unsigned long)(v64 & 0xffffffff);
++ *var_len = sizeof(c64);
++ vp->type = ASN_COUNTER64;
++ return ((unsigned char *) &c64);
++ }
++ else if (!strncasecmp(buf, "counter", 7)) {
++ *var_len = sizeof(long_ret);
++ long_ret = strtoul(buf2, NULL, 10);
++ vp->type = ASN_COUNTER;
++ return ((unsigned char *) &long_ret);
++ } else if (!strncasecmp(buf, "octet", 5)) {
++ *var_len = netsnmp_internal_asc2bin(buf2);
++ vp->type = ASN_OCTET_STR;
++ return ((unsigned char *) buf2);
++ } else if (!strncasecmp(buf, "opaque", 6)) {
++ *var_len = netsnmp_internal_asc2bin(buf2);
++ vp->type = ASN_OPAQUE;
++ return ((unsigned char *) buf2);
++ } else if (!strncasecmp(buf, "gauge", 5)) {
++ *var_len = sizeof(long_ret);
++ long_ret = strtoul(buf2, NULL, 10);
++ vp->type = ASN_GAUGE;
++ return ((unsigned char *) &long_ret);
++ } else if (!strncasecmp(buf, "objectid", 8)) {
++ newlen = parse_miboid(buf2, objid);
++ *var_len = newlen * sizeof(oid);
++ vp->type = ASN_OBJECT_ID;
++ return ((unsigned char *) objid);
++ } else if (!strncasecmp(buf, "timetick", 8)) {
++ *var_len = sizeof(long_ret);
++ long_ret = strtoul(buf2, NULL, 10);
++ vp->type = ASN_TIMETICKS;
++ return ((unsigned char *) &long_ret);
++ } else if (!strncasecmp(buf, "ipaddress", 9)) {
++ newlen = parse_miboid(buf2, objid);
++ if (newlen != 4) {
++ snmp_log(LOG_ERR, "invalid ipaddress returned: %s\n", buf2);
++ *var_len = 0;
++ return (NULL);
++ }
++ addr_ret =
++ (objid[0] << (8 * 3)) + (objid[1] << (8 * 2)) +
++ (objid[2] << 8) + objid[3];
++ addr_ret = htonl(addr_ret);
++ *var_len = sizeof(addr_ret);
++ vp->type = ASN_IPADDRESS;
++ return ((unsigned char *) &addr_ret);
++ }
++ *var_len = 0;
++ return (NULL);
++}
++
++void
++netsnmp_internal_pass_set_format(char *buf,
++ const u_char *var_val,
++ u_char var_val_type,
++ size_t var_val_len)
++{
++ char buf2[SNMP_MAXBUF];
++ long tmp;
++ unsigned long utmp;
++
++ switch (var_val_type) {
++ case ASN_INTEGER:
++ case ASN_COUNTER:
++ case ASN_GAUGE:
++ case ASN_TIMETICKS:
++ tmp = *((const long *) var_val);
++ switch (var_val_type) {
++ case ASN_INTEGER:
++ sprintf(buf, "integer %d\n", (int) tmp);
++ break;
++ case ASN_COUNTER:
++ sprintf(buf, "counter %d\n", (int) tmp);
++ break;
++ case ASN_GAUGE:
++ sprintf(buf, "gauge %d\n", (int) tmp);
++ break;
++ case ASN_TIMETICKS:
++ sprintf(buf, "timeticks %d\n", (int) tmp);
++ break;
++ }
++ break;
++ case ASN_IPADDRESS:
++ utmp = *((const u_long *) var_val);
++ utmp = ntohl(utmp);
++ sprintf(buf, "ipaddress %d.%d.%d.%d\n",
++ (int) ((utmp & 0xff000000) >> (8 * 3)),
++ (int) ((utmp & 0xff0000) >> (8 * 2)),
++ (int) ((utmp & 0xff00) >> (8)),
++ (int) ((utmp & 0xff)));
++ break;
++ case ASN_OCTET_STR:
++ memcpy(buf2, var_val, var_val_len);
++ if (var_val_len == 0)
++ sprintf(buf, "string \"\"\n");
++ else if (netsnmp_internal_bin2asc(buf2, var_val_len) ==
++ (int) var_val_len)
++ snprintf(buf, sizeof(buf), "string \"%s\"\n", buf2);
++ else
++ snprintf(buf, sizeof(buf), "octet \"%s\"\n", buf2);
++ buf[ sizeof(buf)-1 ] = 0;
++ break;
++ case ASN_OBJECT_ID:
++ sprint_mib_oid(buf2, (const oid *) var_val, var_val_len/sizeof(oid));
++ snprintf(buf, sizeof(buf), "objectid \"%s\"\n", buf2);
++ buf[ sizeof(buf)-1 ] = 0;
++ break;
++ }
++}
+diff --git a/agent/mibgroup/ucd-snmp/pass_common.h b/agent/mibgroup/ucd-snmp/pass_common.h
+new file mode 100644
+index 0000000..b1d7e4b
+--- /dev/null
++++ b/agent/mibgroup/ucd-snmp/pass_common.h
+@@ -0,0 +1,20 @@
++#ifndef NETSNMP_AGENT_MIBGROUP_PASS_COMMON_H
++#define NETSNMP_AGENT_MIBGROUP_PASS_COMMON_H
++
++/*
++ * This is an internal header file. The functions declared here might change
++ * or disappear at any time
++ */
++
++int
++netsnmp_internal_pass_str_to_errno(const char *buf);
++
++unsigned char *
++netsnmp_internal_pass_parse(char *buf, char *buf2, size_t *var_len,
++ struct variable *vp);
++
++void
++netsnmp_internal_pass_set_format(char *buf, const u_char *var_val,
++ u_char var_val_type, size_t var_val_len);
++
++#endif /* !NETSNMP_AGENT_MIBGROUP_PASS_COMMON_H */
+diff --git a/agent/mibgroup/ucd-snmp/pass_persist.c b/agent/mibgroup/ucd-snmp/pass_persist.c
+index c18a84c..6cce6f4 100644
+--- a/agent/mibgroup/ucd-snmp/pass_persist.c
++++ b/agent/mibgroup/ucd-snmp/pass_persist.c
+@@ -38,6 +38,7 @@
+
+ #include "struct.h"
+ #include "pass_persist.h"
++#include "pass_common.h"
+ #include "extensible.h"
+ #include "util_funcs.h"
+
+@@ -60,15 +61,6 @@ static void destruct_persist_pipes(void);
+ static int write_persist_pipe(int iindex, const char *data);
+
+ /*
+- * These are defined in pass.c
+- */
+-extern int asc2bin(char *p);
+-extern int bin2asc(char *p, size_t n);
+-extern int netsnmp_pass_str_to_errno(const char *buf);
+-extern int snmp_oid_min_compare(const oid *, size_t, const oid *,
+- size_t);
+-
+-/*
+ * the relocatable extensible commands variables
+ */
+ struct variable2 extensible_persist_passthru_variables[] = {
+@@ -169,11 +161,9 @@ pass_persist_parse_config(const char *token, char *cptr)
+ } else {
+ for (tcptr = cptr; *tcptr != 0 && *tcptr != '#' && *tcptr != ';';
+ tcptr++);
+- strncpy((*ppass)->command, cptr, tcptr - cptr);
+- (*ppass)->command[tcptr - cptr] = 0;
++ sprintf((*ppass)->command, "%.*s", (int) (tcptr - cptr), cptr);
+ }
+- strncpy((*ppass)->name, (*ppass)->command, sizeof((*ppass)->name));
+- (*ppass)->name[ sizeof((*ppass)->name)-1 ] = 0;
++ strlcpy((*ppass)->name, (*ppass)->command, sizeof((*ppass)->name));
+ (*ppass)->next = NULL;
+
+ register_mib_priority("pass_persist",
+@@ -230,11 +220,8 @@ var_extensible_pass_persist(struct variable *vp,
+ {
+ oid newname[MAX_OID_LEN];
+ int i, rtest, newlen;
+- static long long_ret;
+- static in_addr_t addr_ret;
+ char buf[SNMP_MAXBUF];
+ static char buf2[SNMP_MAXBUF];
+- static oid objid[MAX_OID_LEN];
+ struct extensible *persistpassthru;
+ FILE *file;
+
+@@ -243,10 +230,9 @@ var_extensible_pass_persist(struct variable *vp,
+ */
+ init_persist_pipes();
+
+- long_ret = *length;
+ for (i = 1; i <= numpersistpassthrus; i++) {
+ persistpassthru = get_exten_instance(persistpassthrus, i);
+- rtest = snmp_oid_min_compare(name, *length,
++ rtest = snmp_oidtree_compare(name, *length,
+ persistpassthru->miboid,
+ persistpassthru->miblen);
+ if ((exact && rtest == 0) || (!exact && rtest <= 0)) {
+@@ -325,89 +311,7 @@ var_extensible_pass_persist(struct variable *vp,
+ close_persist_pipe(i);
+ return (NULL);
+ }
+- /*
+- * buf contains the return type, and buf2 contains the data
+- */
+- if (!strncasecmp(buf, "string", 6)) {
+- buf2[strlen(buf2) - 1] = 0; /* zap the linefeed */
+- *var_len = strlen(buf2);
+- vp->type = ASN_OCTET_STR;
+- return ((unsigned char *) buf2);
+- }
+- else if (!strncasecmp(buf, "integer64", 9)) {
+- static struct counter64 c64;
+- uint64_t v64 = strtoull(buf2, NULL, 10);
+- c64.high = (unsigned long)(v64 >> 32);
+- c64.low = (unsigned long)(v64 & 0xffffffff);
+- *var_len = sizeof(c64);
+- vp->type = ASN_INTEGER64;
+- return ((unsigned char *) &c64);
+- }
+- else if (!strncasecmp(buf, "integer", 7)) {
+- *var_len = sizeof(long_ret);
+- long_ret = strtol(buf2, NULL, 10);
+- vp->type = ASN_INTEGER;
+- return ((unsigned char *) &long_ret);
+- } else if (!strncasecmp(buf, "unsigned", 8)) {
+- *var_len = sizeof(long_ret);
+- long_ret = strtoul(buf2, NULL, 10);
+- vp->type = ASN_UNSIGNED;
+- return ((unsigned char *) &long_ret);
+- }
+- else if (!strncasecmp(buf, "counter64", 9)) {
+- static struct counter64 c64;
+- uint64_t v64 = strtoull(buf2, NULL, 10);
+- c64.high = (unsigned long)(v64 >> 32);
+- c64.low = (unsigned long)(v64 & 0xffffffff);
+- *var_len = sizeof(c64);
+- vp->type = ASN_COUNTER64;
+- return ((unsigned char *) &c64);
+- }
+- else if (!strncasecmp(buf, "counter", 7)) {
+- *var_len = sizeof(long_ret);
+- long_ret = strtoul(buf2, NULL, 10);
+- vp->type = ASN_COUNTER;
+- return ((unsigned char *) &long_ret);
+- } else if (!strncasecmp(buf, "octet", 5)) {
+- *var_len = asc2bin(buf2);
+- vp->type = ASN_OCTET_STR;
+- return ((unsigned char *) buf2);
+- } else if (!strncasecmp(buf, "opaque", 6)) {
+- *var_len = asc2bin(buf2);
+- vp->type = ASN_OPAQUE;
+- return ((unsigned char *) buf2);
+- } else if (!strncasecmp(buf, "gauge", 5)) {
+- *var_len = sizeof(long_ret);
+- long_ret = strtoul(buf2, NULL, 10);
+- vp->type = ASN_GAUGE;
+- return ((unsigned char *) &long_ret);
+- } else if (!strncasecmp(buf, "objectid", 8)) {
+- newlen = parse_miboid(buf2, objid);
+- *var_len = newlen * sizeof(oid);
+- vp->type = ASN_OBJECT_ID;
+- return ((unsigned char *) objid);
+- } else if (!strncasecmp(buf, "timetick", 8)) {
+- *var_len = sizeof(long_ret);
+- long_ret = strtoul(buf2, NULL, 10);
+- vp->type = ASN_TIMETICKS;
+- return ((unsigned char *) &long_ret);
+- } else if (!strncasecmp(buf, "ipaddress", 9)) {
+- newlen = parse_miboid(buf2, objid);
+- if (newlen != 4) {
+- snmp_log(LOG_ERR,
+- "invalid ipaddress returned: %s\n",
+- buf2);
+- *var_len = 0;
+- return (NULL);
+- }
+- addr_ret =
+- (objid[0] << (8 * 3)) + (objid[1] << (8 * 2)) +
+- (objid[2] << 8) + objid[3];
+- addr_ret = htonl(addr_ret);
+- *var_len = sizeof(addr_ret);
+- vp->type = ASN_IPADDRESS;
+- return ((unsigned char *) &addr_ret);
+- }
++ return netsnmp_internal_pass_parse(buf, buf2, var_len, vp);
+ }
+ *var_len = 0;
+ return (NULL);
+@@ -430,8 +334,6 @@ setPassPersist(int action,
+ struct extensible *persistpassthru;
+
+ char buf[SNMP_MAXBUF], buf2[SNMP_MAXBUF];
+- long tmp;
+- unsigned long utmp;
+
+ /*
+ * Make sure that our basic pipe structure is malloced
+@@ -440,7 +342,7 @@ setPassPersist(int action,
+
+ for (i = 1; i <= numpersistpassthrus; i++) {
+ persistpassthru = get_exten_instance(persistpassthrus, i);
+- rtest = snmp_oid_min_compare(name, name_len,
++ rtest = snmp_oidtree_compare(name, name_len,
+ persistpassthru->miboid,
+ persistpassthru->miblen);
+ if (rtest <= 0) {
+@@ -457,55 +359,9 @@ setPassPersist(int action,
+ snprintf(persistpassthru->command,
+ sizeof(persistpassthru->command), "set\n%s\n", buf);
+ persistpassthru->command[ sizeof(persistpassthru->command)-1 ] = 0;
+- switch (var_val_type) {
+- case ASN_INTEGER:
+- case ASN_COUNTER:
+- case ASN_GAUGE:
+- case ASN_TIMETICKS:
+- tmp = *((long *) var_val);
+- switch (var_val_type) {
+- case ASN_INTEGER:
+- sprintf(buf, "integer %d\n", (int) tmp);
+- break;
+- case ASN_COUNTER:
+- sprintf(buf, "counter %d\n", (int) tmp);
+- break;
+- case ASN_GAUGE:
+- sprintf(buf, "gauge %d\n", (int) tmp);
+- break;
+- case ASN_TIMETICKS:
+- sprintf(buf, "timeticks %d\n", (int) tmp);
+- break;
+- }
+- break;
+- case ASN_IPADDRESS:
+- utmp = *((u_long *) var_val);
+- utmp = ntohl(utmp);
+- sprintf(buf, "ipaddress %d.%d.%d.%d\n",
+- (int) ((utmp & 0xff000000) >> (8 * 3)),
+- (int) ((utmp & 0xff0000) >> (8 * 2)),
+- (int) ((utmp & 0xff00) >> (8)),
+- (int) ((utmp & 0xff)));
+- break;
+- case ASN_OCTET_STR:
+- memcpy(buf2, var_val, var_val_len);
+- if (var_val_len == 0)
+- sprintf(buf, "string \"\"\n");
+- else if (bin2asc(buf2, var_val_len) == (int) var_val_len)
+- snprintf(buf, sizeof(buf), "string \"%s\"\n", buf2);
+- else
+- snprintf(buf, sizeof(buf), "octet \"%s\"\n", buf2);
+- buf[ sizeof(buf)-1 ] = 0;
+- break;
+- case ASN_OBJECT_ID:
+- sprint_mib_oid(buf2, (oid *) var_val, var_val_len/sizeof(oid));
+- snprintf(buf, sizeof(buf), "objectid \"%s\"\n", buf2);
+- buf[ sizeof(buf)-1 ] = 0;
+- break;
+- }
+- strncat(persistpassthru->command, buf,
+- sizeof(persistpassthru->command) -
+- strlen(persistpassthru->command) - 2);
++ netsnmp_internal_pass_set_format(buf, var_val, var_val_type, var_val_len);
++ strlcat(persistpassthru->command, buf,
++ sizeof(persistpassthru->command));
+ persistpassthru->command[ sizeof(persistpassthru->command)-2 ] = '\n';
+ persistpassthru->command[ sizeof(persistpassthru->command)-1 ] = 0;
+
+@@ -526,7 +382,7 @@ setPassPersist(int action,
+ return SNMP_ERR_NOTWRITABLE;
+ }
+
+- return netsnmp_pass_str_to_errno(buf);
++ return netsnmp_internal_pass_str_to_errno(buf);
+ }
+ }
+ if (snmp_get_do_debugging()) {
+@@ -650,8 +506,8 @@ open_persist_pipe(int iindex, char *command)
+ {
+ static int recurse = 0; /* used to allow one level of recursion */
+
+- DEBUGMSGTL(("ucd-snmp/pass_persist", "open_persist_pipe(%d,'%s')\n",
+- iindex, command));
++ DEBUGMSGTL(("ucd-snmp/pass_persist", "open_persist_pipe(%d,'%s') recurse=%d\n",
++ iindex, command, recurse));
+ /*
+ * Open if it's not already open
+ */
+@@ -683,6 +539,7 @@ open_persist_pipe(int iindex, char *command)
+ * Setup our -non-buffered-io-
+ */
+ setbuf(persist_pipes[iindex].fOut, (char *) 0);
++ DEBUGMSGTL(("ucd-snmp/pass_persist", "open_persist_pipe: opened the pipes\n"));
+ }
+
+ /*
+@@ -702,6 +559,7 @@ open_persist_pipe(int iindex, char *command)
+ * Recurse one time if we get a SIGPIPE
+ */
+ if (!recurse) {
++ DEBUGMSGTL(("ucd-snmp/pass_persist", "open_persist_pipe: recursing to reopen\n"));
+ recurse = 1;
+ return open_persist_pipe(iindex, command);
+ }
+@@ -717,7 +575,7 @@ open_persist_pipe(int iindex, char *command)
+ }
+ if (strncmp(buf, "PONG", 4)) {
+ DEBUGMSGTL(("ucd-snmp/pass_persist",
+- "open_persist_pipe: PONG not received!\n"));
++ "open_persist_pipe: Got %s instead of PONG!\n", buf));
+ close_persist_pipe(iindex);
+ recurse = 0;
+ return 0;
+@@ -728,17 +586,6 @@ open_persist_pipe(int iindex, char *command)
+ return 1;
+ }
+
+-#if HAVE_STRUCT_SIGACTION_SA_SIGACTION
+-/*
+- * Generic handler
+- */
+-void
+-sigpipe_handler(int sig, siginfo_t * sip, void *uap)
+-{
+- return;
+-}
+-#endif
+-
+ static int
+ write_persist_pipe(int iindex, const char *data)
+ {
+@@ -750,16 +597,16 @@ write_persist_pipe(int iindex, const char *data)
+ * Don't write to a non-existant process
+ */
+ if (persist_pipes[iindex].pid == NETSNMP_NO_SUCH_PROCESS) {
++ DEBUGMSGTL(("ucd-snmp/pass_persist",
++ "write_persist_pipe: not writing %s, process is non-existent",
++ data));
+ return 0;
+ }
+
+ /*
+- * Setup our signal action to catch SIGPIPEs
++ * Setup our signal action to ignore SIGPIPEs
+ */
+- sa.sa_handler = NULL;
+-#if HAVE_STRUCT_SIGACTION_SA_SIGACTION
+- sa.sa_sigaction = &sigpipe_handler;
+-#endif
++ sa.sa_handler = SIG_IGN;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ if (sigaction(SIGPIPE, &sa, &osa)) {
+@@ -779,10 +626,10 @@ write_persist_pipe(int iindex, const char *data)
+ sigaction(SIGPIPE, &osa, (struct sigaction *) 0);
+
+ if (wret < 0) {
+- if (werrno != EINTR) {
++ if (werrno != EPIPE) {
+ DEBUGMSGTL(("ucd-snmp/pass_persist",
+- "write_persist_pipe: write returned unknown error %d\n",
+- errno));
++ "write_persist_pipe: write returned unknown error %d (%s)\n",
++ werrno, strerror(werrno)));
+ }
+ close_persist_pipe(iindex);
+ return 0;
+diff --git a/agent/mibgroup/ucd-snmp/pass_persist.h b/agent/mibgroup/ucd-snmp/pass_persist.h
+index c7a2aa8..0537abc 100644
+--- a/agent/mibgroup/ucd-snmp/pass_persist.h
++++ b/agent/mibgroup/ucd-snmp/pass_persist.h
+@@ -4,7 +4,9 @@
+ #ifndef _MIBGROUP_PASS_PERSIST_H
+ #define _MIBGROUP_PASS_PERSIST_H
+
++config_require(ucd-snmp/pass_common)
+ config_require(util_funcs)
++config_require(utilities/execute)
+
+ void init_pass_persist(void);
+ void shutdown_pass_persist(void);
+diff --git a/agent/mibgroup/ucd-snmp/proc.c b/agent/mibgroup/ucd-snmp/proc.c
+index 32ac0df..e90c2e8 100644
+--- a/agent/mibgroup/ucd-snmp/proc.c
++++ b/agent/mibgroup/ucd-snmp/proc.c
+@@ -437,8 +437,7 @@ sh_count_procs(char *procname)
+ count = 0;
+
+ while(getprocs(&pinfo, sizeof(pinfo), NULL, 0, &index, 1) == 1) {
+- strncpy(pinfo_name, pinfo.pi_comm, 256);
+- pinfo_name[255] = 0;
++ strlcpy(pinfo_name, pinfo.pi_comm, sizeof(pinfo_name));
+ sep = strchr(pinfo_name, ' ');
+ if(sep != NULL) *sep = 0;
+ if(strcmp(procname, pinfo_name) == 0) count++;
+diff --git a/agent/mibgroup/ucd-snmp/proxy.c b/agent/mibgroup/ucd-snmp/proxy.c
+index ec1aac7..017fd5c 100644
+--- a/agent/mibgroup/ucd-snmp/proxy.c
++++ b/agent/mibgroup/ucd-snmp/proxy.c
+@@ -285,14 +285,13 @@ proxy_fill_in_session(netsnmp_mib_handler *handler,
+ return 0;
+ }
+
+- *configured = malloc(strlen("-c") + 1);
+- strcpy((char*)*configured, "-c");
++ *configured = strdup("-c");
+ DEBUGMSGTL(("proxy", "pdu has community string\n"));
+ session->community_len = reqinfo->asp->pdu->community_len;
+- session->community = (u_char*)malloc(session->community_len + 1);
+- strncpy((char *)session->community,
+- (const char *)reqinfo->asp->pdu->community,
+- session->community_len);
++ session->community = malloc(session->community_len + 1);
++ sprintf((char *)session->community, "%.*s",
++ (int) session->community_len,
++ (const char *)reqinfo->asp->pdu->community);
+ }
+ }
+ #endif
+@@ -401,6 +400,8 @@ proxy_handler(netsnmp_mib_handler *handler,
+
+ if (!pdu || !sp) {
+ netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
++ if (pdu)
++ snmp_free_pdu(pdu);
+ return SNMP_ERR_NOERROR;
+ }
+
+@@ -561,7 +562,7 @@ proxy_got_response(int operation, netsnmp_session * sess, int reqid,
+ REQUEST_IS_NOT_DELEGATED);
+ }
+ #ifndef NETSNMP_NO_WRITE_SUPPORT
+- else if ((cache->reqinfo->mode == MODE_SET_ACTION)) {
++ else if (cache->reqinfo->mode == MODE_SET_ACTION) {
+ /*
+ * In order for netsnmp_wrap_up_request to consider the
+ * SET request complete,
+diff --git a/agent/mibgroup/ucd-snmp/versioninfo.c b/agent/mibgroup/ucd-snmp/versioninfo.c
+index 60a3c71..f7a8c63 100644
+--- a/agent/mibgroup/ucd-snmp/versioninfo.c
++++ b/agent/mibgroup/ucd-snmp/versioninfo.c
+@@ -108,22 +108,21 @@ var_extensible_version(struct variable *vp,
+ long_ret = name[8];
+ return ((u_char *) (&long_ret));
+ case VERTAG:
+- strcpy(errmsg, netsnmp_get_version());
++ strlcpy(errmsg, netsnmp_get_version(), sizeof(errmsg));
+ *var_len = strlen(errmsg);
+ return ((u_char *) errmsg);
+ case VERDATE:
+- sprintf(errmsg, "$Date$");
++ strlcpy(errmsg, "$Date$", sizeof(errmsg));
+ *var_len = strlen(errmsg);
+ return ((u_char *) errmsg);
+ case VERCDATE:
+ curtime = time(NULL);
+ cptr = ctime(&curtime);
+- strcpy(errmsg, cptr);
+- *var_len = strlen(errmsg) - 1;
++ strlcpy(errmsg, cptr, sizeof(errmsg));
++ *var_len = strlen(errmsg) - 1; /* - 1 to strip trailing newline */
+ return ((u_char *) errmsg);
+ case VERIDENT:
+- sprintf(errmsg,
+- "$Id$");
++ strlcpy(errmsg, "$Id$", sizeof(errmsg));
+ *var_len = strlen(errmsg);
+ return ((u_char *) errmsg);
+ case VERCONFIG:
+@@ -133,7 +132,7 @@ var_extensible_version(struct variable *vp,
+ *var_len = 1024; /* mib imposed restriction */
+ return (u_char *) config_opts;
+ #else
+- sprintf(errmsg, "");
++ strlcpy(errmsg, "", sizeof(errmsg)));
+ *var_len = strlen(errmsg);
+ return ((u_char *) errmsg);
+ #endif
+diff --git a/agent/mibgroup/ucd-snmp/vmstat.c b/agent/mibgroup/ucd-snmp/vmstat.c
+index b613ee1..d52a5b6 100644
+--- a/agent/mibgroup/ucd-snmp/vmstat.c
++++ b/agent/mibgroup/ucd-snmp/vmstat.c
+@@ -31,7 +31,7 @@ vmstat_handler(netsnmp_mib_handler *handler,
+ netsnmp_request_info *requests)
+ {
+ oid obj;
+- long value = 0;
++ unsigned long long value = 0;
+ char cp[300];
+ netsnmp_cpu_info *info = netsnmp_cpu_get_byIdx( -1, 0 );
+
+@@ -147,7 +147,7 @@ vmstat_handler(netsnmp_mib_handler *handler,
+ else
+ value = 0; /* or skip this entry */
+ snmp_set_var_typed_integer(requests->requestvb,
+- ASN_INTEGER, value);
++ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+ case CPUSYSTEM:
+@@ -159,7 +159,7 @@ vmstat_handler(netsnmp_mib_handler *handler,
+ else
+ value = 0; /* or skip this entry */
+ snmp_set_var_typed_integer(requests->requestvb,
+- ASN_INTEGER, value);
++ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+ case CPUIDLE:
+@@ -170,7 +170,7 @@ vmstat_handler(netsnmp_mib_handler *handler,
+ else
+ value = 0; /* or skip this entry */
+ snmp_set_var_typed_integer(requests->requestvb,
+- ASN_INTEGER, value);
++ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+
+@@ -190,14 +190,14 @@ vmstat_handler(netsnmp_mib_handler *handler,
+ if ( info->history && info->history[0].total_hist ) {
+ value = (info->nInterrupts - info->history[0].intr_hist)/60;
+ snmp_set_var_typed_integer(requests->requestvb,
+- ASN_INTEGER, value);
++ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+ case SYSCONTEXT:
+ if ( info->history && info->history[0].total_hist ) {
+ value = (info->nCtxSwitches - info->history[0].ctx_hist)/60;
+ snmp_set_var_typed_integer(requests->requestvb,
+- ASN_INTEGER, value);
++ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+
+@@ -217,7 +217,7 @@ vmstat_handler(netsnmp_mib_handler *handler,
+ value = (info->swapIn - info->history[0].swpi_hist)/60;
+ /* ??? value *= PAGE_SIZE; */
+ snmp_set_var_typed_integer(requests->requestvb,
+- ASN_INTEGER, value);
++ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+ case SWAPOUT:
+@@ -225,7 +225,7 @@ vmstat_handler(netsnmp_mib_handler *handler,
+ value = (info->swapOut - info->history[0].swpo_hist)/60;
+ /* ??? value *= PAGE_SIZE; */
+ snmp_set_var_typed_integer(requests->requestvb,
+- ASN_INTEGER, value);
++ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+
+@@ -244,14 +244,14 @@ vmstat_handler(netsnmp_mib_handler *handler,
+ if ( info->history && info->history[0].total_hist ) {
+ value = (info->pageOut - info->history[0].pageo_hist)/60;
+ snmp_set_var_typed_integer(requests->requestvb,
+- ASN_INTEGER, value);
++ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+ case IORECEIVE:
+ if ( info->history && info->history[0].total_hist ) {
+ value = (info->pageIn - info->history[0].pagei_hist)/60;
+ snmp_set_var_typed_integer(requests->requestvb,
+- ASN_INTEGER, value);
++ ASN_INTEGER, value & 0x7fffffff);
+ }
+ break;
+
+diff --git a/agent/mibgroup/ucd_snmp.h b/agent/mibgroup/ucd_snmp.h
+index c371dd4..0d87ec1 100644
+--- a/agent/mibgroup/ucd_snmp.h
++++ b/agent/mibgroup/ucd_snmp.h
+@@ -8,7 +8,9 @@ config_require(ucd-snmp/loadave)
+ config_require(agent/extend)
+ config_require(ucd-snmp/errormib)
+ config_require(ucd-snmp/file)
++#if defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
+ config_require(ucd-snmp/dlmod)
++#endif
+ config_require(ucd-snmp/proxy)
+ config_require(ucd-snmp/logmatch)
+ config_require(ucd-snmp/memory)
+diff --git a/agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable_data_access.c b/agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable_data_access.c
+index 9ea23a9..0e25c21 100644
+--- a/agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable_data_access.c
++++ b/agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable_data_access.c
+@@ -239,7 +239,7 @@ udpEndpointTable_container_load(netsnmp_container *container)
+ if (NULL == ep_c)
+ return MFD_RESOURCE_UNAVAILABLE;
+ ep_it = CONTAINER_ITERATOR(ep_c);
+- if (NULL == ep_c) {
++ if (NULL == ep_it) {
+ netsnmp_access_udp_endpoint_container_free(ep_c, 0);
+ return MFD_RESOURCE_UNAVAILABLE;
+ }
+diff --git a/agent/mibgroup/util_funcs.c b/agent/mibgroup/util_funcs.c
+index 55d80c5..69d7190 100644
+--- a/agent/mibgroup/util_funcs.c
++++ b/agent/mibgroup/util_funcs.c
+@@ -126,31 +126,7 @@ extern int numprocs, numextens;
+ const char *
+ make_tempfile(void)
+ {
+- static char name[32];
+- int fd = -1;
+-
+- strcpy(name, get_temp_file_pattern());
+-#ifdef HAVE_MKSTEMP
+- fd = mkstemp(name);
+-#else
+- if (mktemp(name)) {
+-# ifndef WIN32
+- fd = open(name, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR);
+-# else
+- /*
+- Win32 needs _S_IREAD | _S_IWRITE to set permissions on file after closing
+- */
+- fd = _open(name, _O_CREAT | _O_EXCL | _O_WRONLY, _S_IREAD | _S_IWRITE);
+-# endif
+- }
+-#endif
+- if (fd >= 0) {
+- close(fd);
+- DEBUGMSGTL(("make_tempfile", "temp file created: %s\n", name));
+- return name;
+- }
+- snmp_log(LOG_ERR,"make_tempfile: error creating file %s\n", name);
+- return NULL;
++ return netsnmp_mktemp();
+ }
+
+ #ifndef NETSNMP_FEATURE_REMOVE_SHELL_COMMAND
+@@ -718,14 +694,12 @@ print_mib_oid(oid name[], size_t len)
+ }
+
+ void
+-sprint_mib_oid(char *buf, oid name[], size_t len)
++sprint_mib_oid(char *buf, const oid *name, size_t len)
+ {
+ int i;
+- for (i = 0; i < (int) len; i++) {
+- sprintf(buf, ".%d", (int) name[i]);
+- while (*buf != 0)
+- buf++;
+- }
++
++ for (i = 0; i < (int) len; i++)
++ buf += sprintf(buf, ".%" NETSNMP_PRIo "u", name[i]);
+ }
+
+ /*
+@@ -798,7 +772,10 @@ parse_miboid(const char *buf, oid * oidout)
+ if (*buf == '.')
+ buf++;
+ for (i = 0; isdigit((unsigned char)(*buf)); i++) {
+- oidout[i] = atoi(buf);
++ /* Subidentifiers are unsigned values, up to 2^32-1
++ * so we need to use 'strtoul' rather than 'atoi'
++ */
++ oidout[i] = strtoul(buf, NULL, 10) & 0xffffffff;
+ while (isdigit((unsigned char)(*buf++)));
+ if (*buf == '.')
+ buf++;
+@@ -1146,7 +1123,7 @@ int net_snmp_delete_prefix_info(prefix_cbx **head,
+ }
+ return 0;
+ }
+-#endif
++#endif /* NETSNMP_FEATURE_REMOVE_DELETE_PREFIX_INFO */
+
+ #endif /* HAVE_LINUX_RTNETLINK_H */
+
+diff --git a/agent/mibgroup/util_funcs.h b/agent/mibgroup/util_funcs.h
+index 5bef2a8..7f59780 100644
+--- a/agent/mibgroup/util_funcs.h
++++ b/agent/mibgroup/util_funcs.h
+@@ -43,7 +43,7 @@ int get_exec_pipes(char *cmd, int *fdIn, int *fdOut, pid_t *pid);
+ #endif
+ WriteMethod clear_cache;
+ void print_mib_oid(oid *, size_t);
+-void sprint_mib_oid(char *, oid *, size_t);
++void sprint_mib_oid(char *, const oid *, size_t);
+ int checkmib(struct variable *, oid *, size_t *, int, size_t *,
+ WriteMethod ** write_method, int);
+ char *find_field(char *, int);
+diff --git a/agent/mibgroup/utilities/override.c b/agent/mibgroup/utilities/override.c
+index 298883e..2b083a9 100644
+--- a/agent/mibgroup/utilities/override.c
++++ b/agent/mibgroup/utilities/override.c
+@@ -216,6 +216,8 @@ netsnmp_parse_override(const char *token, char *line)
+ case ASN_OBJECT_ID:
+ read_config_read_objid(buf, (oid **) & thedata->value,
+ &thedata->value_len);
++ /* We need the size of the value in bytes, not in oids */
++ thedata->value_len *= sizeof(oid);
+ break;
+
+ case ASN_NULL:
+diff --git a/agent/mibgroup/winExtDLL.c b/agent/mibgroup/winExtDLL.c
+index ddf613b..c693913 100644
+--- a/agent/mibgroup/winExtDLL.c
++++ b/agent/mibgroup/winExtDLL.c
+@@ -692,7 +692,6 @@ var_winExtDLL(netsnmp_mib_handler *handler,
+ winextdll *ext_dll_info;
+ netsnmp_request_info *request;
+ UINT nRequestType;
+- const char *mode_name;
+ int rc;
+
+ netsnmp_assert(ext_dll_view_info);
+@@ -711,35 +710,27 @@ var_winExtDLL(netsnmp_mib_handler *handler,
+
+ switch (reqinfo->mode) {
+ case MODE_GET:
+- mode_name = "GET";
+ nRequestType = SNMP_EXTENSION_GET;
+ netsnmp_assert(!context_info_head);
+ break;
+ case MODE_GETNEXT:
+- mode_name = "GETNEXT";
+ nRequestType = SNMP_EXTENSION_GET_NEXT;
+ netsnmp_assert(!context_info_head);
+ break;
+ case MODE_SET_RESERVE1:
+- mode_name = "SET_RESERVE1";
+ nRequestType = SNMP_EXTENSION_SET_TEST;
+ break;
+ case MODE_SET_RESERVE2:
+- mode_name = "SET_RESERVE2";
+ return SNMP_ERR_NOERROR;
+ case MODE_SET_ACTION:
+- mode_name = "SET_ACTION";
+ return SNMP_ERR_NOERROR;
+ case MODE_SET_UNDO:
+- mode_name = "SET_UNDO";
+ nRequestType = SNMP_EXTENSION_SET_UNDO;
+ break;
+ case MODE_SET_COMMIT:
+- mode_name = "SET_COMMIT";
+ nRequestType = SNMP_EXTENSION_SET_COMMIT;
+ break;
+ case MODE_SET_FREE:
+- mode_name = "SET_FREE";
+ nRequestType = SNMP_EXTENSION_SET_CLEANUP;
+ break;
+ default:
+diff --git a/agent/snmp_agent.c b/agent/snmp_agent.c
+index b38ef4a..2532da1 100644
+--- a/agent/snmp_agent.c
++++ b/agent/snmp_agent.c
+@@ -662,8 +662,7 @@ agent_check_and_process(int block)
+ * The caller does not want us to block at all.
+ */
+
+- tvp->tv_sec = 0;
+- tvp->tv_usec = 0;
++ timerclear(tvp);
+ }
+
+ count = select(numfds, &fdset, NULL, NULL, tvp);
+@@ -778,7 +777,7 @@ netsnmp_addrcache_add(const char *addr)
+ /*
+ * found a match
+ */
+- memcpy(&addrCache[i].lastHit, &now, sizeof(struct timeval));
++ addrCache[i].lastHit = now;
+ if (timercmp(&addrCache[i].lastHit, &aged, <))
+ rc = 1; /* should have expired, so is new */
+ else
+@@ -825,7 +824,7 @@ netsnmp_addrcache_add(const char *addr)
+ */
+ addrCache[unused].addr = strdup(addr);
+ addrCache[unused].status = SNMP_ADDRCACHE_USED;
+- memcpy(&addrCache[unused].lastHit, &now, sizeof(struct timeval));
++ addrCache[unused].lastHit = now;
+ }
+ else { /* Otherwise, replace oldest entry */
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
+@@ -835,7 +834,7 @@ netsnmp_addrcache_add(const char *addr)
+
+ free(addrCache[oldest].addr);
+ addrCache[oldest].addr = strdup(addr);
+- memcpy(&addrCache[oldest].lastHit, &now, sizeof(struct timeval));
++ addrCache[oldest].lastHit = now;
+ }
+ rc = 1;
+ }
+@@ -884,7 +883,7 @@ netsnmp_agent_check_packet(netsnmp_session * session,
+ {
+ char *addr_string = NULL;
+ #ifdef NETSNMP_USE_LIBWRAP
+- char *tcpudpaddr, *name;
++ char *tcpudpaddr = NULL, *name;
+ short not_log_connection;
+
+ name = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
+@@ -918,12 +917,13 @@ netsnmp_agent_check_packet(netsnmp_session * session,
+ }
+ #ifdef NETSNMP_USE_LIBWRAP
+ /* Catch udp,udp6,tcp,tcp6 transports using "[" */
+- tcpudpaddr = strstr(addr_string, "[");
++ if (addr_string)
++ tcpudpaddr = strstr(addr_string, "[");
+ if ( tcpudpaddr != 0 ) {
+ char sbuf[64];
+ char *xp;
+- strncpy(sbuf, tcpudpaddr + 1, sizeof(sbuf));
+- sbuf[sizeof(sbuf)-1] = '\0';
++
++ strlcpy(sbuf, tcpudpaddr + 1, sizeof(sbuf));
+ xp = strstr(sbuf, "]");
+ if (xp)
+ *xp = '\0';
+@@ -3310,57 +3310,6 @@ netsnmp_handle_request(netsnmp_agent_session *asp, int status)
+ return 1;
+ }
+
+-/**
+- * This function calls into netsnmp_set_mode_request_error, sets
+- * error_value given a reqinfo->mode value. It's used to send specific
+- * errors back to the agent to process accordingly.
+- *
+- * If error_value is set to SNMP_NOSUCHOBJECT, SNMP_NOSUCHINSTANCE,
+- * or SNMP_ENDOFMIBVIEW the following is applicable:
+- * Sets the error_value to request->requestvb->type if
+- * reqinfo->mode value is set to MODE_GET. If the reqinfo->mode
+- * value is set to MODE_GETNEXT or MODE_GETBULK the code calls
+- * snmp_log logging an error message.
+- *
+- * Otherwise, the request->status value is checked, if it's < 0
+- * snmp_log is called with an error message and SNMP_ERR_GENERR is
+- * assigned to request->status. If the request->status value is >= 0 the
+- * error_value is set to request->status.
+- *
+- * @param reqinfo is a pointer to the netsnmp_agent_request_info struct. It
+- * contains the reqinfo->mode which is required to set error_value or
+- * log error messages.
+- *
+- * @param request is a pointer to the netsnmp_request_info struct. The
+- * error_value is set to request->requestvb->type
+- *
+- * @param error_value is the exception value you want to set, below are
+- * possible values.
+- * - SNMP_NOSUCHOBJECT
+- * - SNMP_NOSUCHINSTANCE
+- * - SNMP_ENDOFMIBVIEW
+- * - SNMP_ERR_NOERROR
+- * - SNMP_ERR_TOOBIG
+- * - SNMP_ERR_NOSUCHNAME
+- * - SNMP_ERR_BADVALUE
+- * - SNMP_ERR_READONLY
+- * - SNMP_ERR_GENERR
+- * - SNMP_ERR_NOACCESS
+- * - SNMP_ERR_WRONGTYPE
+- * - SNMP_ERR_WRONGLENGTH
+- * - SNMP_ERR_WRONGENCODING
+- * - SNMP_ERR_WRONGVALUE
+- * - SNMP_ERR_NOCREATION
+- * - SNMP_ERR_INCONSISTENTVALUE
+- * - SNMP_ERR_RESOURCEUNAVAILABLE
+- * - SNMP_ERR_COMMITFAILED
+- * - SNMP_ERR_UNDOFAILED
+- * - SNMP_ERR_AUTHORIZATIONERROR
+- * - SNMP_ERR_NOTWRITABLE
+- * - SNMP_ERR_INCONSISTENTNAME
+- *
+- * @return Returns error_value under all conditions.
+- */
+ int
+ handle_pdu(netsnmp_agent_session *asp)
+ {
+@@ -3702,9 +3651,13 @@ netsnmp_request_set_error_all( netsnmp_request_info *requests, int error)
+ return result;
+ }
+
+- /*
+- * Return the value of 'sysUpTime' at the given marker
+- */
++/**
++ * Return the value of 'sysUpTime' at the given marker
++ *
++ * @note Use netsnmp_get_agent_runtime() instead of this function if you need
++ * to know how much time elapsed since netsnmp_set_agent_starttime() has been
++ * called.
++ */
+ u_long
+ netsnmp_marker_uptime(marker_t pm)
+ {
+@@ -3738,6 +3691,22 @@ netsnmp_get_agent_starttime(void)
+ }
+
+ /**
++ * Report the time that elapsed since the agent start time in hundredths of a
++ * second.
++ *
++ * @see See also netsnmp_set_agent_starttime().
++ */
++uint64_t
++netsnmp_get_agent_runtime(void)
++{
++ struct timeval now, delta;
++
++ gettimeofday(&now, NULL);
++ NETSNMP_TIMERSUB(&now, &starttime, &delta);
++ return delta.tv_sec * (uint64_t)100 + delta.tv_usec / 10000;
++}
++
++/**
+ * Set the time at which Net-SNMP started either to the current time
+ * (if s == NULL) or to *s (if s is not NULL).
+ */
+diff --git a/agent/snmp_perl.c b/agent/snmp_perl.c
+index f974023..48d9695 100644
+--- a/agent/snmp_perl.c
++++ b/agent/snmp_perl.c
+@@ -36,6 +36,7 @@ maybe_source_perl_startup(void)
+ const char *perl_init_file = netsnmp_ds_get_string(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_PERL_INIT_FILE);
+ char init_file[SNMP_MAXBUF];
++ int res;
+
+ static int have_done_init = 0;
+
+@@ -57,8 +58,11 @@ maybe_source_perl_startup(void)
+ env = NULL;
+ PERL_SYS_INIT3(&argc, &argv, &env);
+ my_perl = perl_alloc();
+- if (!my_perl)
++ if (!my_perl) {
++ snmp_log(LOG_ERR,
++ "embedded perl support failed to initialize (perl_alloc())\n");
+ goto bail_out;
++ }
+
+ perl_construct(my_perl);
+
+@@ -66,11 +70,21 @@ maybe_source_perl_startup(void)
+ PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
+ #endif
+
+- if (perl_parse(my_perl, xs_init, 2, embedargs, NULL))
++ res = perl_parse(my_perl, xs_init, 2, embedargs, NULL);
++ if (res) {
++ snmp_log(LOG_ERR,
++ "embedded perl support failed to initialize (perl_parse(%s)"
++ " returned %d)\n", embedargs[1], res);
+ goto bail_out;
++ }
+
+- if (perl_run(my_perl))
++ res = perl_run(my_perl);
++ if (res) {
++ snmp_log(LOG_ERR,
++ "embedded perl support failed to initialize (perl_run()"
++ " returned %d)\n", res);
+ goto bail_out;
++ }
+
+ free(embedargs[0]);
+ free(embedargs[1]);
+@@ -82,7 +96,6 @@ maybe_source_perl_startup(void)
+ bail_out:
+ free(embedargs[0]);
+ free(embedargs[1]);
+- snmp_log(LOG_ERR, "embedded perl support failed to initialize\n");
+ netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_DISABLE_PERL, 1);
+ return;
+@@ -168,5 +181,6 @@ shutdown_perl(void)
+ }
+ DEBUGMSGTL(("perl", "shutting down perl\n"));
+ perl_destruct(my_perl);
++ my_perl = NULL;
+ DEBUGMSGTL(("perl", "finished shutting down perl\n"));
+ }
+diff --git a/agent/snmpd.c b/agent/snmpd.c
+index 0deff09..ee458c3 100644
+--- a/agent/snmpd.c
++++ b/agent/snmpd.c
+@@ -438,7 +438,6 @@ main(int argc, char *argv[])
+ int arg, i, ret;
+ int dont_fork = 0, do_help = 0;
+ int log_set = 0;
+- int uid = 0, gid = 0;
+ int agent_mode = -1;
+ char *pid_file = NULL;
+ char option_compatability[] = "-Le";
+@@ -446,12 +445,6 @@ main(int argc, char *argv[])
+ int fd;
+ FILE *PID;
+ #endif
+-#if HAVE_GETPWNAM && HAVE_PWD_H
+- struct passwd *info;
+-#endif
+-#if HAVE_UNISTD_H
+- const char *persistent_dir;
+-#endif
+
+ #ifndef WIN32
+ /*
+@@ -602,19 +595,18 @@ main(int argc, char *argv[])
+ int gid;
+
+ gid = strtoul(optarg, &ecp, 10);
++#if HAVE_GETGRNAM && HAVE_PWD_H
+ if (*ecp) {
+-#if HAVE_GETPWNAM && HAVE_PWD_H
+ struct group *info;
++
+ info = getgrnam(optarg);
+- if (info) {
+- gid = info->gr_gid;
+- } else {
+-#endif
+- fprintf(stderr, "Bad group id: %s\n", optarg);
+- exit(1);
+-#if HAVE_GETPWNAM && HAVE_PWD_H
+- }
++ gid = info ? info->gr_gid : -1;
++ endgrent();
++ }
+ #endif
++ if (gid < 0) {
++ fprintf(stderr, "Bad group id: %s\n", optarg);
++ exit(1);
+ }
+ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_GROUPID, gid);
+@@ -781,18 +773,18 @@ main(int argc, char *argv[])
+ int uid;
+
+ uid = strtoul(optarg, &ecp, 10);
+- if (*ecp) {
+ #if HAVE_GETPWNAM && HAVE_PWD_H
++ if (*ecp) {
++ struct passwd *info;
++
+ info = getpwnam(optarg);
+- if (info) {
+- uid = info->pw_uid;
+- } else {
+-#endif
+- fprintf(stderr, "Bad user id: %s\n", optarg);
+- exit(1);
+-#if HAVE_GETPWNAM && HAVE_PWD_H
+- }
++ uid = info ? info->pw_uid : -1;
++ endpwent();
++ }
+ #endif
++ if (uid < 0) {
++ fprintf(stderr, "Bad user id: %s\n", optarg);
++ exit(1);
+ }
+ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_USERID, uid);
+@@ -1009,7 +1001,11 @@ main(int argc, char *argv[])
+ }
+ #endif
+
+-#if HAVE_UNISTD_H
++#if defined(HAVE_UNISTD_H) && (defined(HAVE_CHOWN) || defined(HAVE_SETGID) || defined(HAVE_SETUID))
++ {
++ const char *persistent_dir;
++ int uid, gid;
++
+ persistent_dir = get_persistent_directory();
+ mkdirhier( persistent_dir, NETSNMP_AGENT_DIRECTORY_MODE, 0 );
+
+@@ -1025,7 +1021,7 @@ main(int argc, char *argv[])
+
+ #ifdef HAVE_SETGID
+ if ((gid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
+- NETSNMP_DS_AGENT_GROUPID)) != 0) {
++ NETSNMP_DS_AGENT_GROUPID)) > 0) {
+ DEBUGMSGTL(("snmpd/main", "Changing gid to %d.\n", gid));
+ if (setgid(gid) == -1
+ #ifdef HAVE_SETGROUPS
+@@ -1042,8 +1038,10 @@ main(int argc, char *argv[])
+ #endif
+ #ifdef HAVE_SETUID
+ if ((uid = netsnmp_ds_get_int(NETSNMP_DS_APPLICATION_ID,
+- NETSNMP_DS_AGENT_USERID)) != 0) {
++ NETSNMP_DS_AGENT_USERID)) > 0) {
+ #if HAVE_GETPWNAM && HAVE_PWD_H && HAVE_INITGROUPS
++ struct passwd *info;
++
+ /*
+ * Set supplementary groups before changing UID
+ * (which probably involves giving up privileges)
+@@ -1059,6 +1057,7 @@ main(int argc, char *argv[])
+ }
+ }
+ }
++ endpwent();
+ #endif
+ DEBUGMSGTL(("snmpd/main", "Changing uid to %d.\n", uid));
+ if (setuid(uid) == -1) {
+@@ -1070,6 +1069,7 @@ main(int argc, char *argv[])
+ }
+ }
+ #endif
++ }
+ #endif
+
+ /*
+@@ -1273,7 +1273,7 @@ receive(void)
+ DEBUGMSGTL(("snmpd/select", "select( numfds=%d, ..., tvp=%p)\n",
+ numfds, tvp));
+ if(tvp)
+- DEBUGMSGTL(("timer", "tvp %ld.%ld\n", tvp->tv_sec, tvp->tv_usec));
++ DEBUGMSGTL(("timer", "tvp %ld.%ld\n", tvp->tv_sec, (long)tvp->tv_usec));
+ count = netsnmp_large_fd_set_select(numfds, &readfds, &writefds, &exceptfds,
+ tvp);
+ DEBUGMSGTL(("snmpd/select", "returned, count = %d\n", count));
+diff --git a/apps/Makefile.in b/apps/Makefile.in
+index 43cb007..77404dd 100644
+--- a/apps/Makefile.in
++++ b/apps/Makefile.in
+@@ -84,9 +84,6 @@ USEAGENTLIBS = $(MIBLIB) $(AGENTLIB) $(USELIBS)
+ MYSQL_LIBS = @MYSQL_LIBS@
+ MYSQL_INCLUDES = @MYSQL_INCLUDES@
+
+-#
+-# link path in src dir
+-LOCAL_LIBS = -L../snmplib/.libs -L../snmplib -L../agent/.libs -L../agent
+ VAL_LIBS = @VAL_LIBS@
+ LIBS = $(USELIBS) $(VAL_LIBS) @LIBS@
+ PERLLDOPTS_FOR_APPS = @PERLLDOPTS_FOR_APPS@
+@@ -146,65 +143,65 @@ OTHERUNINSTALL=snmpinformuninstall snmptrapdperluninstall
+ # build rules
+ #
+ snmpwalk$(EXEEXT): snmpwalk.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ snmpwalk.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ snmpwalk.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ snmpbulkwalk$(EXEEXT): snmpbulkwalk.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ snmpbulkwalk.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ snmpbulkwalk.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ snmpbulkget$(EXEEXT): snmpbulkget.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ snmpbulkget.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ snmpbulkget.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ snmptranslate$(EXEEXT): snmptranslate.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ snmptranslate.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ snmptranslate.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ snmpstatus$(EXEEXT): snmpstatus.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ snmpstatus.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ snmpstatus.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ snmpget$(EXEEXT): snmpget.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ snmpget.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ snmpget.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ snmpdelta$(EXEEXT): snmpdelta.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ snmpdelta.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ snmpdelta.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ snmptable$(EXEEXT): snmptable.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ snmptable.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ snmptable.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ snmptest$(EXEEXT): snmptest.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ snmptest.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ snmptest.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ snmptrapd$(EXEEXT): $(TRAPD_OBJECTS) $(USETRAPLIBS) $(INSTALLLIBS)
+- $(LINK) ${CFLAGS} -o $@ $(TRAPD_OBJECTS) $(INSTALLLIBS) $(LOCAL_LIBS) ${LDFLAGS} ${TRAPLIBS}
++ $(LINK) ${CFLAGS} -o $@ $(TRAPD_OBJECTS) $(INSTALLLIBS) ${LDFLAGS} ${TRAPLIBS}
+
+ snmptrap$(EXEEXT): snmptrap.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ snmptrap.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ snmptrap.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ snmpinform$(EXEEXT): snmptrap$(EXEEXT)
+ rm -f snmpinform
+ $(LN_S) snmptrap$(EXEEXT) snmpinform$(EXEEXT)
+
+ snmpset$(EXEEXT): snmpset.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ snmpset.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ snmpset.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ snmpusm$(EXEEXT): snmpusm.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ snmpusm.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ snmpusm.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ snmpvacm$(EXEEXT): snmpvacm.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ snmpvacm.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ snmpvacm.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ snmptls$(EXEEXT): snmptls.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ snmptls.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ snmptls.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ agentxtrap$(EXEEXT): agentxtrap.$(OSUFFIX) $(USEAGENTLIBS)
+- $(LINK) ${CFLAGS} -o $@ agentxtrap.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} $(USEAGENTLIBS) $(PERLLDOPTS_FOR_APPS) ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ agentxtrap.$(OSUFFIX) ${LDFLAGS} $(USEAGENTLIBS) $(PERLLDOPTS_FOR_APPS) ${LIBS}
+
+ snmpgetnext$(EXEEXT): snmpgetnext.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ snmpgetnext.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ snmpgetnext.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ encode_keychange$(EXEEXT): encode_keychange.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ encode_keychange.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ encode_keychange.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ snmpdf$(EXEEXT): snmpdf.$(OSUFFIX) $(USELIBS)
+- $(LINK) ${CFLAGS} -o $@ snmpdf.$(OSUFFIX) $(LOCAL_LIBS) ${LDFLAGS} ${LIBS}
++ $(LINK) ${CFLAGS} -o $@ snmpdf.$(OSUFFIX) ${LDFLAGS} ${LIBS}
+
+ libnetsnmptrapd.$(LIB_EXTENSION)$(LIB_VERSION): $(LLIBTRAPD_OBJS)
+ $(LIB_LD_CMD) $@ ${LLIBTRAPD_OBJS} $(MIBLIB) $(USELIBS) $(PERLLDOPTS_FOR_LIBS) $(LIB_LD_LIBS)
+diff --git a/apps/encode_keychange.c b/apps/encode_keychange.c
+index bae2139..5bf8e4c 100644
+--- a/apps/encode_keychange.c
++++ b/apps/encode_keychange.c
+@@ -108,7 +108,7 @@ int _getch(void);
+ int
+ main(int argc, char **argv)
+ {
+- int rval = SNMPERR_SUCCESS;
++ int rval = 1;
+ size_t oldKu_len = SNMP_MAXBUF_SMALL,
+ newKu_len = SNMP_MAXBUF_SMALL,
+ oldkul_len = SNMP_MAXBUF_SMALL,
+@@ -170,6 +170,7 @@ main(int argc, char **argv)
+ break;
+ case 'h':
+ rval = 0;
++ /* fallthrough */
+ default:
+ usage_to_file(stdout);
+ exit(rval);
+@@ -201,7 +202,7 @@ main(int argc, char **argv)
+ "Unrecognized hash transform: \"%s\".\n",
+ transform_type_input);
+ usage_synopsis(stderr);
+- QUITFUN(rval = SNMPERR_GENERR, main_quit);
++ QUITFUN(SNMPERR_GENERR, main_quit);
+ }
+
+ if (verbose) {
+@@ -254,12 +255,12 @@ main(int argc, char **argv)
+ if (strlen(oldpass) < USM_LENGTH_P_MIN) {
+ fprintf(stderr, "Old passphrase must be greater than %d "
+ "characters in length.\n", USM_LENGTH_P_MIN);
+- QUITFUN(rval = SNMPERR_GENERR, main_quit);
++ QUITFUN(SNMPERR_GENERR, main_quit);
+
+ } else if (strlen(newpass) < USM_LENGTH_P_MIN) {
+ fprintf(stderr, "New passphrase must be greater than %d "
+ "characters in length.\n", USM_LENGTH_P_MIN);
+- QUITFUN(rval = SNMPERR_GENERR, main_quit);
++ QUITFUN(SNMPERR_GENERR, main_quit);
+ }
+
+ if (verbose) {
+@@ -503,13 +504,13 @@ get_user_passphrases(void)
+ */
+ if (stat(path, &statbuf) < 0) {
+ fprintf(stderr, "Cannot access directory \"%s\".\n", path);
+- QUITFUN(rval = SNMPERR_GENERR, get_user_passphrases_quit);
++ QUITFUN(SNMPERR_GENERR, get_user_passphrases_quit);
+ #ifndef WIN32
+ } else if (statbuf.st_mode & (S_IRWXG | S_IRWXO)) {
+ fprintf(stderr,
+ "Directory \"%s\" is accessible by group or world.\n",
+ path);
+- QUITFUN(rval = SNMPERR_GENERR, get_user_passphrases_quit);
++ QUITFUN(SNMPERR_GENERR, get_user_passphrases_quit);
+ #endif /* !WIN32 */
+ }
+
+@@ -520,12 +521,12 @@ get_user_passphrases(void)
+ path[ sizeof(path)-1 ] = 0;
+ if (stat(path, &statbuf) < 0) {
+ fprintf(stderr, "Cannot access file \"%s\".\n", path);
+- QUITFUN(rval = SNMPERR_GENERR, get_user_passphrases_quit);
++ QUITFUN(SNMPERR_GENERR, get_user_passphrases_quit);
+ #ifndef WIN32
+ } else if (statbuf.st_mode & (S_IRWXG | S_IRWXO)) {
+ fprintf(stderr,
+ "File \"%s\" is accessible by group or world.\n", path);
+- QUITFUN(rval = SNMPERR_GENERR, get_user_passphrases_quit);
++ QUITFUN(SNMPERR_GENERR, get_user_passphrases_quit);
+ #endif /* !WIN32 */
+ }
+
+@@ -534,7 +535,7 @@ get_user_passphrases(void)
+ */
+ if ((fp = fopen(path, "r")) == NULL) {
+ fprintf(stderr, "Cannot open \"%s\".", path);
+- QUITFUN(rval = SNMPERR_GENERR, get_user_passphrases_quit);
++ QUITFUN(SNMPERR_GENERR, get_user_passphrases_quit);
+ }
+
+ /*
+diff --git a/apps/snmpbulkwalk.c b/apps/snmpbulkwalk.c
+index 62874fa..379d2ae 100644
+--- a/apps/snmpbulkwalk.c
++++ b/apps/snmpbulkwalk.c
+@@ -184,7 +184,7 @@ main(int argc, char *argv[])
+ size_t rootlen;
+ int count;
+ int running;
+- int status;
++ int status = STAT_ERROR;
+ int check;
+ int exitval = 0;
+
+diff --git a/apps/snmpdelta.c b/apps/snmpdelta.c
+index e334698..08e2ebc 100644
+--- a/apps/snmpdelta.c
++++ b/apps/snmpdelta.c
+@@ -471,7 +471,7 @@ main(int argc, char *argv[])
+ printf("\t%s", vip->descriptor);
+ } else {
+ vip->oidlen = 0;
+- strcpy(vip->descriptor, SumFile);
++ strlcpy(vip->descriptor, SumFile, sizeof(vip->descriptor));
+ }
+ vip->value = 0;
+ zeroU64(&vip->c64value);
+diff --git a/apps/snmpnetstat/inet.c b/apps/snmpnetstat/inet.c
+index 00b14e0..0ae810d 100644
+--- a/apps/snmpnetstat/inet.c
++++ b/apps/snmpnetstat/inet.c
+@@ -249,7 +249,7 @@ tcpprotopr_bulkget(const char *name, oid *root, size_t root_len)
+ /*
+ * setup initial object name
+ */
+- memmove(tcpConnState_oid, root, sizeof(root) * root_len);
++ memmove(tcpConnState_oid, root, sizeof(oid) * root_len);
+ tcpConnState_len = root_len;
+
+ /*
+diff --git a/apps/snmpnetstat/inet6.c b/apps/snmpnetstat/inet6.c
+index bad4db9..d4ad391 100644
+--- a/apps/snmpnetstat/inet6.c
++++ b/apps/snmpnetstat/inet6.c
+@@ -128,7 +128,7 @@ tcp6protopr(const char *name)
+ return;
+
+ for (vp = var; vp ; vp=vp->next_variable) {
+- state = *var->val.integer;
++ state = *vp->val.integer;
+ if (!aflag && state == MIB_TCPCONNSTATE_LISTEN)
+ continue;
+
+@@ -144,12 +144,12 @@ tcp6protopr(const char *name)
+
+ /* Extract the local/remote information from the index values */
+ for (i=0; i<16; i++)
+- localAddr[i] = var->name[ 10+i ];
+- localPort = var->name[ 26 ];
++ localAddr[i] = vp->name[ 10+i ];
++ localPort = vp->name[ 26 ];
+ for (i=0; i<16; i++)
+- remoteAddr[i] = var->name[ 27+i ];
+- remotePort = var->name[ 43 ];
+- ifIndex = var->name[ 44 ];
++ remoteAddr[i] = vp->name[ 27+i ];
++ remotePort = vp->name[ 43 ];
++ ifIndex = vp->name[ 44 ];
+
+ printf("%-5.5s", name);
+ inet6print(localAddr, localPort, name, 1);
+@@ -196,9 +196,9 @@ udp6protopr(const char *name)
+ * the IP address from the varbind value, (which is why
+ * we walked udpLocalAddress rather than udpLocalPort)
+ */
+- localPort = var->name[ var->name_length-2 ];
+- ifIndex = var->name[ var->name_length-1 ];
+- inet6print(var->val.string, localPort, name, 1);
++ localPort = vp->name[ vp->name_length-2 ];
++ ifIndex = vp->name[ vp->name_length-1 ];
++ inet6print(vp->val.string, localPort, name, 1);
+ printf(" %4d\n", ifIndex );
+ }
+ snmp_free_varbind( var );
+@@ -223,20 +223,21 @@ _dump_v6stats( const char *name, oid *oid_buf, size_t buf_len,
+ {
+ netsnmp_variable_list *var, *vp;
+ struct stat_table *sp;
+- oid *stats, stat;
++ long *stats;
++ oid stat;
+ unsigned int max_stat = 0;
+ int active = 0;
+
+ var = NULL;
+ for (sp=stable; sp->entry; sp++) {
+ oid_buf[buf_len-1] = sp->entry;
+- if (sp->entry>max_stat)
++ if (sp->entry > max_stat)
+ max_stat = sp->entry;
+ snmp_varlist_add_variable( &var, oid_buf, buf_len,
+ ASN_NULL, NULL, 0);
+ }
+ oid_buf[buf_len-1] = stable[0].entry;
+- stats = (oid *)calloc(max_stat+1, sizeof(oid));
++ stats = (long *)calloc(max_stat+1, sizeof(long));
+
+ /*
+ * Walk the specified column(s), and total the individual statistics
+@@ -244,12 +245,12 @@ _dump_v6stats( const char *name, oid *oid_buf, size_t buf_len,
+ while (1) {
+ if (netsnmp_query_getnext( var, ss ) != SNMP_ERR_NOERROR)
+ break;
+- if ( snmp_oid_compare( oid_buf, buf_len-1,
+- var->name, buf_len-1) != 0 )
++ if ( snmp_oid_compare( oid_buf, buf_len,
++ var->name, buf_len) != 0 )
+ break; /* End of Table */
+
+ for ( vp=var; vp; vp=vp->next_variable ) {
+- stat = var->name[ buf_len-1 ];
++ stat = vp->name[ buf_len-1 ];
+ stats[stat] += *vp->val.integer;
+ }
+ active=1;
+diff --git a/apps/snmpset.c b/apps/snmpset.c
+index aaacf8c..1b29a6c 100644
+--- a/apps/snmpset.c
++++ b/apps/snmpset.c
+@@ -171,6 +171,7 @@ main(int argc, char *argv[])
+ case '=':
+ case 'i':
+ case 'u':
++ case '3':
+ case 't':
+ case 'a':
+ case 'o':
+diff --git a/apps/snmptls.c b/apps/snmptls.c
+index 7dffcd9..93b648b 100644
+--- a/apps/snmptls.c
++++ b/apps/snmptls.c
+@@ -332,7 +332,7 @@ optProc(int argc, char *const *argv, int opt)
+
+ case 's':
+ if (optind < argc) {
+- if (isdigit(argv[optind][0]))
++ if (isdigit(0xFF & argv[optind][0]))
+ _storage_type = atoi(argv[optind++]);
+ else
+ _storage_type_str = argv[optind++];
+@@ -345,7 +345,7 @@ optProc(int argc, char *const *argv, int opt)
+
+ case 'h':
+ if (optind < argc) {
+- if (isdigit(argv[optind][0]))
++ if (isdigit(0xFF & argv[optind][0]))
+ _hash_type = atoi(argv[optind++]);
+ }
+ else {
+diff --git a/apps/snmptrapd.c b/apps/snmptrapd.c
+index 7742eff..1a52080 100644
+--- a/apps/snmptrapd.c
++++ b/apps/snmptrapd.c
+@@ -217,8 +217,6 @@ LPCTSTR app_name_long = _T("Net-SNMP Trap Handler"); /* Application
+
+ const char *app_name = "snmptrapd";
+
+-struct timeval Now;
+-
+ void trapd_update_config(void);
+
+ #ifdef WIN32SERVICE
+@@ -360,8 +358,8 @@ pre_parse(netsnmp_session * session, netsnmp_transport *transport,
+ if ( tcpudpaddr != 0 ) {
+ char sbuf[64];
+ char *xp;
+- strncpy(sbuf, tcpudpaddr + 1, sizeof(sbuf));
+- sbuf[sizeof(sbuf)-1] = '\0';
++
++ strlcpy(sbuf, tcpudpaddr + 1, sizeof(sbuf));
+ xp = strstr(sbuf, "]");
+ if (xp)
+ *xp = '\0';
+@@ -423,15 +421,20 @@ void
+ parse_trapd_address(const char *token, char *cptr)
+ {
+ char buf[BUFSIZ];
++ char *p;
+ cptr = copy_nword(cptr, buf, sizeof(buf));
+
+ if (default_port == ddefault_port) {
+ default_port = strdup(buf);
+ } else {
+- strcat( buf, "," );
+- strcat( buf, default_port );
++ p = malloc(strlen(buf) + 1 + strlen(default_port) + 1);
++ if (p) {
++ strcat(p, buf);
++ strcat(p, ",");
++ strcat(p, default_port );
++ }
+ free(default_port);
+- default_port = strdup(buf);
++ default_port = p;
+ }
+ }
+
+@@ -469,13 +472,10 @@ parse_config_pidFile(const char *token, char *cptr)
+ void
+ parse_config_agentuser(const char *token, char *cptr)
+ {
+-#if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H)
+- struct passwd *info;
+-#endif
+-
+ if (cptr[0] == '#') {
+ char *ecp;
+ int uid;
++
+ uid = strtoul(cptr + 1, &ecp, 10);
+ if (*ecp != 0) {
+ config_perror("Bad number");
+@@ -483,44 +483,47 @@ parse_config_agentuser(const char *token, char *cptr)
+ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_USERID, uid);
+ }
+- }
+ #if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H)
+- else if ((info = getpwnam(cptr)) != NULL) {
+- netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+- NETSNMP_DS_AGENT_USERID, info->pw_uid);
+ } else {
+- config_perror("User not found in passwd database");
+- }
+- endpwent();
++ struct passwd *info;
++
++ info = getpwnam(cptr);
++ if (info)
++ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
++ NETSNMP_DS_AGENT_USERID, info->pw_uid);
++ else
++ config_perror("User not found in passwd database");
++ endpwent();
+ #endif
++ }
+ }
+
+ void
+ parse_config_agentgroup(const char *token, char *cptr)
+ {
+-#if defined(HAVE_GETGRNAM) && defined(HAVE_GRP_H)
+- struct group *info;
+-#endif
+-
+ if (cptr[0] == '#') {
+ char *ecp;
+ int gid = strtoul(cptr + 1, &ecp, 10);
++
+ if (*ecp != 0) {
+ config_perror("Bad number");
+ } else {
+ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_GROUPID, gid);
+ }
+- }
+ #if defined(HAVE_GETGRNAM) && defined(HAVE_GRP_H)
+- else if ((info = getgrnam(cptr)) != NULL) {
+- netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+- NETSNMP_DS_AGENT_GROUPID, info->gr_gid);
+ } else {
+- config_perror("Group not found in group database");
+- }
+- endpwent();
++ struct group *info;
++
++ info = getgrnam(cptr);
++ if (info)
++ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
++ NETSNMP_DS_AGENT_GROUPID, info->gr_gid);
++ else
++ config_perror("Group not found in group database");
++ endgrent();
+ #endif
++ }
+ }
+ #endif
+
+@@ -550,6 +553,74 @@ parse_config_outputOption(const char *token, char *cptr)
+ }
+ }
+
++static void
++snmptrapd_main_loop(void)
++{
++ int count, numfds, block;
++ fd_set readfds,writefds,exceptfds;
++ struct timeval timeout, *tvp;
++
++ while (netsnmp_running) {
++ if (reconfig) {
++ /*
++ * If we are logging to a file, receipt of SIGHUP also
++ * indicates that the log file should be closed and
++ * re-opened. This is useful for users that want to
++ * rotate logs in a more predictable manner.
++ */
++ netsnmp_logging_restart();
++ snmp_log(LOG_INFO, "NET-SNMP version %s restarted\n",
++ netsnmp_get_version());
++ trapd_update_config();
++ if (trap1_fmt_str_remember) {
++ parse_format( NULL, trap1_fmt_str_remember );
++ }
++ reconfig = 0;
++ }
++ numfds = 0;
++ FD_ZERO(&readfds);
++ FD_ZERO(&writefds);
++ FD_ZERO(&exceptfds);
++ block = 0;
++ tvp = &timeout;
++ timerclear(tvp);
++ tvp->tv_sec = 5;
++ snmp_select_info(&numfds, &readfds, tvp, &block);
++ if (block == 1)
++ tvp = NULL; /* block without timeout */
++#ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER
++ netsnmp_external_event_info(&numfds, &readfds, &writefds, &exceptfds);
++#endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */
++ count = select(numfds, &readfds, &writefds, &exceptfds, tvp);
++ if (count > 0) {
++#ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER
++ netsnmp_dispatch_external_events(&count, &readfds, &writefds,
++ &exceptfds);
++#endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */
++ /* If there are any more events after external events, then
++ * try SNMP events. */
++ if (count > 0) {
++ snmp_read(&readfds);
++ }
++ } else {
++ switch (count) {
++ case 0:
++ snmp_timeout();
++ break;
++ case -1:
++ if (errno == EINTR)
++ continue;
++ snmp_log_perror("select");
++ netsnmp_running = 0;
++ break;
++ default:
++ fprintf(stderr, "select returned %d\n", count);
++ netsnmp_running = 0;
++ }
++ }
++ run_alarms();
++ }
++}
+
+ /*******************************************************************-o-******
+ * main - Non Windows
+@@ -579,9 +650,6 @@ main(int argc, char *argv[])
+ netsnmp_transport *transport = NULL;
+ int arg, i = 0;
+ int uid = 0, gid = 0;
+- int count, numfds, block;
+- fd_set readfds,writefds,exceptfds;
+- struct timeval timeout, *tvp;
+ char *cp, *listen_ports = NULL;
+ #if defined(USING_AGENTX_SUBAGENT_MODULE) && !defined(NETSNMP_SNMPTRAPD_DISABLE_AGENTX)
+ int agentx_subagent = 1;
+@@ -732,7 +800,7 @@ main(int argc, char *argv[])
+ *cp = ' ';
+ } else {
+ /* Old style: implicitly "print=format" */
+- trap1_fmt_str_remember = (char *)malloc(strlen(optarg) + 7);
++ trap1_fmt_str_remember = malloc(strlen(optarg) + 7);
+ sprintf( trap1_fmt_str_remember, "print %s", optarg );
+ }
+ } else {
+@@ -863,19 +931,18 @@ main(int argc, char *argv[])
+ char *ecp;
+
+ uid = strtoul(optarg, &ecp, 10);
+- if (*ecp) {
+ #if HAVE_GETPWNAM && HAVE_PWD_H
++ if (*ecp) {
+ struct passwd *info;
++
+ info = getpwnam(optarg);
+- if (info) {
+- uid = info->pw_uid;
+- } else {
+-#endif
+- fprintf(stderr, "Bad user id: %s\n", optarg);
+- exit(1);
+-#if HAVE_GETPWNAM && HAVE_PWD_H
+- }
++ uid = info ? info->pw_uid : -1;
++ endpwent();
++ }
+ #endif
++ if (uid < 0) {
++ fprintf(stderr, "Bad user id: %s\n", optarg);
++ exit(1);
+ }
+ netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_USERID, uid);
+@@ -916,7 +983,7 @@ main(int argc, char *argv[])
+ for (i = optind; i < argc; i++) {
+ char *astring;
+ if (listen_ports != NULL) {
+- astring = (char *)malloc(strlen(listen_ports) + 2 + strlen(argv[i]));
++ astring = malloc(strlen(listen_ports) + 2 + strlen(argv[i]));
+ if (astring == NULL) {
+ fprintf(stderr, "malloc failure processing argv[%d]\n", i);
+ exit(1);
+@@ -1247,66 +1314,8 @@ main(int argc, char *argv[])
+ #ifdef WIN32SERVICE
+ trapd_status = SNMPTRAPD_RUNNING;
+ #endif
+- while (netsnmp_running) {
+- if (reconfig) {
+- /*
+- * If we are logging to a file, receipt of SIGHUP also
+- * indicates the the log file should be closed and
+- * re-opened. This is useful for users that want to
+- * rotate logs in a more predictable manner.
+- */
+- netsnmp_logging_restart();
+- snmp_log(LOG_INFO, "NET-SNMP version %s restarted\n",
+- netsnmp_get_version());
+- trapd_update_config();
+- if (trap1_fmt_str_remember) {
+- parse_format( NULL, trap1_fmt_str_remember );
+- }
+- reconfig = 0;
+- }
+- numfds = 0;
+- FD_ZERO(&readfds);
+- FD_ZERO(&writefds);
+- FD_ZERO(&exceptfds);
+- block = 0;
+- tvp = &timeout;
+- timerclear(tvp);
+- tvp->tv_sec = 5;
+- snmp_select_info(&numfds, &readfds, tvp, &block);
+- if (block == 1)
+- tvp = NULL; /* block without timeout */
+-#ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER
+- netsnmp_external_event_info(&numfds, &readfds, &writefds, &exceptfds);
+-#endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */
+- count = select(numfds, &readfds, &writefds, &exceptfds, tvp);
+- gettimeofday(&Now, NULL);
+- if (count > 0) {
+-#ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER
+- netsnmp_dispatch_external_events(&count, &readfds, &writefds,
+- &exceptfds);
+-#endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */
+- /* If there are any more events after external events, then
+- * try SNMP events. */
+- if (count > 0) {
+- snmp_read(&readfds);
+- }
+- } else
+- switch (count) {
+- case 0:
+- snmp_timeout();
+- break;
+- case -1:
+- if (errno == EINTR)
+- continue;
+- snmp_log_perror("select");
+- netsnmp_running = 0;
+- break;
+- default:
+- fprintf(stderr, "select returned %d\n", count);
+- netsnmp_running = 0;
+- }
+- run_alarms();
+- }
++
++ snmptrapd_main_loop();
+
+ if (snmp_get_do_logging()) {
+ struct tm *tm;
+diff --git a/apps/snmptrapd_log.c b/apps/snmptrapd_log.c
+index c1742f4..774f797 100644
+--- a/apps/snmptrapd_log.c
++++ b/apps/snmptrapd_log.c
+@@ -1020,6 +1020,8 @@ realloc_handle_auth_fmt(u_char ** buf, size_t * buf_len, size_t * out_len,
+ #if !defined(NETSNMP_DISABLE_SNMPV1) || !defined(NETSNMP_DISABLE_SNMPV2C)
+ while ((*out_len + pdu->community_len + 1) >= *buf_len) {
+ if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
++ if (temp_buf)
++ free(temp_buf);
+ return 0;
+ }
+ }
+diff --git a/apps/snmptrapd_sql.c b/apps/snmptrapd_sql.c
+index c7433dc..ccba258 100644
+--- a/apps/snmptrapd_sql.c
++++ b/apps/snmptrapd_sql.c
+@@ -437,7 +437,11 @@ netsnmp_mysql_init(void)
+ return -1;
+ }
+
++#ifdef HAVE_BROKEN_LIBMYSQLCLIENT
++ my_init();
++#else
+ MY_INIT("snmptrapd");
++#endif
+
+ /** load .my.cnf values */
+ load_defaults ("my", _sql.groups, &not_argc, &not_argv);
+@@ -704,7 +708,7 @@ _sql_save_trap_info(sql_buf *sqlb, netsnmp_pdu *pdu,
+ struct tm *cur_time;
+ size_t tmp_size;
+ size_t buf_host_len_t, buf_oid_len_t, buf_user_len_t;
+- int oid_overflow, rc, trap_oid_len;
++ int oid_overflow, trap_oid_len;
+ netsnmp_variable_list *vars;
+
+ if ((NULL == sqlb) || (NULL == pdu) || (NULL == transport))
+@@ -727,8 +731,8 @@ _sql_save_trap_info(sql_buf *sqlb, netsnmp_pdu *pdu,
+ /** host name */
+ buf_host_len_t = 0;
+ tmp_size = sizeof(sqlb->host);
+- rc = realloc_format_trap((u_char**)&sqlb->host, &tmp_size,
+- &buf_host_len_t, 1, "%B", pdu, transport);
++ realloc_format_trap((u_char**)&sqlb->host, &tmp_size,
++ &buf_host_len_t, 1, "%B", pdu, transport);
+ sqlb->host_len = buf_host_len_t;
+
+ /* snmpTrapOID */
+@@ -782,8 +786,8 @@ _sql_save_trap_info(sql_buf *sqlb, netsnmp_pdu *pdu,
+ /** community string/user name */
+ tmp_size = 0;
+ buf_user_len_t = 0;
+- rc = realloc_format_trap((u_char**)&sqlb->user, &tmp_size,
+- &buf_user_len_t, 1, "%u", pdu, transport);
++ realloc_format_trap((u_char**)&sqlb->user, &tmp_size,
++ &buf_user_len_t, 1, "%u", pdu, transport);
+ sqlb->user_len = buf_user_len_t;
+
+ /** transport */
+diff --git a/apps/snmpwalk.c b/apps/snmpwalk.c
+index 7473b91..2bed0e8 100644
+--- a/apps/snmpwalk.c
++++ b/apps/snmpwalk.c
+@@ -185,7 +185,7 @@ main(int argc, char *argv[])
+ size_t end_len = 0;
+ int count;
+ int running;
+- int status;
++ int status = STAT_ERROR;
+ int check;
+ int exitval = 0;
+ struct timeval tv1, tv2, tv_a, tv_b;
+diff --git a/configure b/configure
+index 8b2a66f..77c0475 100755
+--- a/configure
++++ b/configure
+@@ -3434,6 +3434,10 @@ if test "${with_openssl+set}" = set; then :
+ elif test "x$withval" = "xno"; then
+ tryopenssl=no
+ elif test -d "$withval"; then
++ if test -d "$withval/lib/MinGW"; then
++ LDFLAGS="-L$withval/lib/MinGW $LDFLAGS"
++ CPPFLAGS="-I$withval/include $CPPFLAGS"
++ else
+
+ if test "x$withval" != x -a -d $withval; then
+ if test -d $withval/lib; then
+@@ -3444,6 +3448,7 @@ if test "${with_openssl+set}" = set; then :
+ fi
+ fi
+
++ fi
+ tryopenssl=yes
+ askedopenssl=yes
+ fi
+@@ -16180,8 +16185,29 @@ fi
+ done
+
+
++# Library and Agent:
++for ac_header in nlist.h
++do :
++ ac_fn_c_check_header_compile "$LINENO" "nlist.h" "ac_cv_header_nlist_h" "
++$ac_includes_default
++
++#ifndef LIBBSD_DISABLE_DEPRECATED
++#define LIBBSD_DISABLE_DEPRECATED 1
++#endif
++
++"
++if test "x$ac_cv_header_nlist_h" = xyes; then :
++ cat >>confdefs.h <<_ACEOF
++#define HAVE_NLIST_H 1
++_ACEOF
++
++fi
++
++done
++
++
+ # Library:
+-for ac_header in fcntl.h io.h kstat.h limits.h locale.h nlist.h sys/file.h sys/ioctl.h sys/sockio.h sys/stat.h sys/systemcfg.h sys/systeminfo.h sys/times.h sys/uio.h sys/utsname.h netipx/ipx.h
++for ac_header in fcntl.h io.h kstat.h limits.h locale.h sys/file.h sys/ioctl.h sys/sockio.h sys/stat.h sys/systemcfg.h sys/systeminfo.h sys/times.h sys/uio.h sys/utsname.h netipx/ipx.h
+ do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+@@ -16196,7 +16222,7 @@ done
+
+
+ # Agent:
+-for ac_header in dlfcn.h err.h fcntl.h fstab.h grp.h io.h ioctls.h kstat.h kvm.h limits.h mntent.h mtab.h nlist.h pkglocs.h pwd.h utmpx.h utsname.h
++for ac_header in dlfcn.h err.h fcntl.h fstab.h grp.h io.h ioctls.h kstat.h kvm.h limits.h mntent.h mtab.h pkglocs.h pwd.h utmpx.h utsname.h
+ do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+@@ -18318,7 +18344,7 @@ while test "x$new_transport_list" != "x"; do
+ /* end confdefs.h. */
+
+ #include NETSNMP_SYSTEM_INCLUDE_FILE
+-#define NETSNMP_FEATURE_CHECKING
++#undef NETSNMP_MINIMAL_CODE
+ #define NET_SNMP_CONFIG_H
+ #undef config_require
+ #define config_require(foo) config_checkit_require(foo)
+@@ -19861,6 +19887,99 @@ done
+
+ LIBS="$netsnmp_save_LIBS"
+
++#
++# dynamic module support
++#
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
++$as_echo_n "checking for library containing dlopen... " >&6; }
++if ${netsnmp_cv_func_dlopen_LMIBLIBS+:} false; then :
++ $as_echo_n "(cached) " >&6
++else
++ netsnmp_func_search_save_LIBS="$LIBS"
++ netsnmp_target_val="$LMIBLIBS"
++ netsnmp_temp_LIBS="${netsnmp_target_val} $LAGENTLIBS $LSNMPLIBS ${LIBS}"
++ netsnmp_result=no
++ LIBS="${netsnmp_temp_LIBS}"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++
++/* Override any GCC internal prototype to avoid an error.
++ Use char because int might match the return type of a GCC
++ builtin and then its argument prototype would still apply. */
++#ifdef __cplusplus
++extern "C"
++#endif
++char dlopen ();
++int
++main ()
++{
++return dlopen ();
++ ;
++ return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++ netsnmp_result="none required"
++else
++ for netsnmp_cur_lib in dl ; do
++ LIBS="-l${netsnmp_cur_lib} ${netsnmp_temp_LIBS}"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++
++/* Override any GCC internal prototype to avoid an error.
++ Use char because int might match the return type of a GCC
++ builtin and then its argument prototype would still apply. */
++#ifdef __cplusplus
++extern "C"
++#endif
++char dlopen ();
++int
++main ()
++{
++return dlopen ();
++ ;
++ return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++ netsnmp_result=-l${netsnmp_cur_lib}
++ break
++fi
++rm -f core conftest.err conftest.$ac_objext \
++ conftest$ac_exeext conftest.$ac_ext
++ done
++fi
++rm -f core conftest.err conftest.$ac_objext \
++ conftest$ac_exeext conftest.$ac_ext
++ LIBS="${netsnmp_func_search_save_LIBS}"
++ netsnmp_cv_func_dlopen_LMIBLIBS="${netsnmp_result}"
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $netsnmp_cv_func_dlopen_LMIBLIBS" >&5
++$as_echo "$netsnmp_cv_func_dlopen_LMIBLIBS" >&6; }
++ if test "${netsnmp_cv_func_dlopen_LMIBLIBS}" != "no" ; then
++ if test "${netsnmp_cv_func_dlopen_LMIBLIBS}" != "none required" ; then
++ LMIBLIBS="${netsnmp_result} ${netsnmp_target_val}"
++ fi
++
++
++ fi
++
++netsnmp_save_LIBS="$LIBS"
++LIBS="$LMIBLIBS $LAGENTLIBS $LSNMPLIBS $LIBS"
++for ac_func in dlopen
++do :
++ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
++if test "x$ac_cv_func_dlopen" = xyes; then :
++ cat >>confdefs.h <<_ACEOF
++#define HAVE_DLOPEN 1
++_ACEOF
++
++fi
++done
++
++LIBS="$netsnmp_save_LIBS"
++
+ # -*- autoconf -*-
+ #
+ # generate empty files
+@@ -20087,7 +20206,8 @@ _ACEOF
+ module_type=mib_module
+ if test -f $srcdir/$mibdir/$i.h; then
+
+- module_type=`$MODULECPP module_tmp_header.h | $GREP config_belongs_in | $SED 's@.*config_belongs_in(\([^)]*\)).*@\1@'`
++ module_type=`$MODULECPP module_tmp_header.h | \
++ $SED -n 's@.*config_belongs_in(\([^)]*\)).*@\1@p'`
+
+ fi
+ if test "x$module_type" = "x" ; then
+@@ -20188,7 +20308,8 @@ _ACEOF
+ # check if $i has any conflicts
+ #
+
+- new_list_excl=`$MODULECPP module_tmp_header.h | $GREP config_exclude | $SED 's/.*config_exclude(\(.*\)).*/\1/'`
++ new_list_excl=`$MODULECPP module_tmp_header.h | \
++ $SED -n 's/.*config_exclude(\(.*\)).*/\1/p'`
+ if test "x$new_list_excl" != "x"; then
+
+ if test $module_debug = 1; then
+@@ -20233,7 +20354,8 @@ EOF
+ #
+
+
+- new_list_arch=`$MODULECPP module_tmp_header.h | $GREP config_arch_require | $SED 's/.*config_arch_require( *\([^ ]*\) *, *\([^ ]*\) *).*/\1-xarchx-\2/'`
++ new_list_arch=`$MODULECPP module_tmp_header.h | \
++ $SED -n 's/.*config_arch_require( *\([^ ]*\) *, *\([^ ]*\) *).*/\1-xarchx-\2/p'`
+
+ if test "x$new_list_arch" != "x"; then
+ for j in $new_list_arch
+@@ -20264,11 +20386,7 @@ EOF
+ #
+
+ new_list_alt3=`$MODULECPP module_tmp_header.h | \
+- $GREP config_version_require | \
+- $SED -e 's/ */ /g' \
+- -e 's/.*config_version_require(( *\([^)]*\) *)).*/\1/' \
+- -e 's/ *, */,/g' | \
+- awk '
++ $AWK '
+ BEGIN {
+ if("'"$enable_new_features"'" == "yes")
+ method="max";
+@@ -20280,7 +20398,10 @@ EOF
+ split("'"$with_features_of"'", a);
+ version=sprintf("%03d%03d%03d%03d", a[1], a[2], a[3], a[4]);
+ }
+- {
++ /config_version_require/ {
++ gsub("^.*config_version_require *\\\\(\\\\(", "");
++ gsub("\\\\)\\\\).*$", "");
++ gsub(", *", ",");
+ FS = ",";
+ n = split($0, a);
+ FS = ".";
+@@ -20311,7 +20432,8 @@ EOF
+ # check if $i has any other required modules
+ #
+
+- new_list="$new_list `$MODULECPP module_tmp_header.h | $GREP config_require | $SED 's/.*config_require(\(.*\)).*/\1/'`"
++ new_list="$new_list `$MODULECPP module_tmp_header.h | \
++ $SED -n 's/.*config_require(\(.*\)).*/\1/p'`"
+
+ if test $module_debug = 1; then
+ echo " $i will test: $new_list"
+@@ -20369,7 +20491,8 @@ EOF
+ # check if $i has any mibs to add
+ #
+
+- new_mibs=`$MODULECPP module_tmp_header.h | $GREP config_add_mib | $SED 's/.*config_add_mib(\(.*\)).*/\1/'`
++ new_mibs=`$MODULECPP module_tmp_header.h | \
++ $SED -n 's/.*config_add_mib(\(.*\)).*/\1/p'`
+ if test "x$new_mibs" != "x"; then
+ for j in $new_mibs
+ do
+@@ -20410,7 +20533,7 @@ EOF
+ #-------------------
+ # check for unsupported config_load_mib
+ #
+- if $MODULECPP module_tmp_header.h | $GREP config_load_mib > /dev/null 2>&1; then
++ if $MODULECPP module_tmp_header.h | $GREP -q config_load_mib; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: mib module error" >&5
+ $as_echo "$as_me: WARNING: mib module error" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: mib module \"$i\" uses the \"config_load_mib\" directive, which is no longer supported. It probably won't work." >&5
+@@ -20423,7 +20546,8 @@ $as_echo "$as_me: WARNING: mib module \"$i\" uses the \"config_load_mib\" direct
+ #
+
+
+- $MODULECPP module_tmp_header.h | $GREP config_parse_dot_conf | $SED 's@.*config_parse_dot_conf(\([^)]*\), *\([^),]*\), *\([^),]*\), *\([^),]*\)).*@register_config_handler("snmpd",\1, \2, \3, \4);@' >> $mibdir/mib_module_dot_conf.h
++ $MODULECPP module_tmp_header.h | \
++ $SED -n 's@.*config_parse_dot_conf(\([^)]*\), *\([^),]*\), *\([^),]*\), *\([^),]*\)).*@register_config_handler("snmpd",\1, \2, \3, \4);@p' >> $mibdir/mib_module_dot_conf.h
+
+
+ #---------------------
+@@ -20433,7 +20557,8 @@ $as_echo "$as_me: WARNING: mib module \"$i\" uses the \"config_load_mib\" direct
+ # check if $i has any errors, or warnings
+ #
+
+- error=`$MODULECPP module_tmp_header.h | $GREP config_error | $SED 's/.*config_error(\(.*\)).*/\1/'`
++ error=`$MODULECPP module_tmp_header.h | \
++ $SED -n 's/.*config_error(\(.*\)).*/\1/p'`
+ if test "x$error" != "x"; then
+ echo
+ echo
+@@ -20445,7 +20570,8 @@ $as_echo "$as_me: WARNING: mib module \"$i\" uses the \"config_load_mib\" direct
+ # - used to signal a configuration "warning" to be printed to the user
+ #
+
+- warning=`$MODULECPP module_tmp_header.h | $GREP config_warning | $SED 's/.*config_warning(\(.*\)).*/\1/'`
++ warning=`$MODULECPP module_tmp_header.h | \
++ $SED -n 's/.*config_warning(\(.*\)).*/\1/p'`
+ if test "x$warning" != "x"; then
+ all_warnings="$all_warnings $warning
+ "
+@@ -21653,99 +21779,6 @@ $as_echo "#define HAVE_LIBKSTAT 1" >>confdefs.h
+
+
+
+-# dynamic module support
+-#
+-
+- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
+-$as_echo_n "checking for library containing dlopen... " >&6; }
+-if ${netsnmp_cv_func_dlopen_LMIBLIBS+:} false; then :
+- $as_echo_n "(cached) " >&6
+-else
+- netsnmp_func_search_save_LIBS="$LIBS"
+- netsnmp_target_val="$LMIBLIBS"
+- netsnmp_temp_LIBS="${netsnmp_target_val} ${LIBS}"
+- netsnmp_result=no
+- LIBS="${netsnmp_temp_LIBS}"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h. */
+-
+-/* Override any GCC internal prototype to avoid an error.
+- Use char because int might match the return type of a GCC
+- builtin and then its argument prototype would still apply. */
+-#ifdef __cplusplus
+-extern "C"
+-#endif
+-char dlopen ();
+-int
+-main ()
+-{
+-return dlopen ();
+- ;
+- return 0;
+-}
+-_ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+- netsnmp_result="none required"
+-else
+- for netsnmp_cur_lib in dl ; do
+- LIBS="-l${netsnmp_cur_lib} ${netsnmp_temp_LIBS}"
+- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h. */
+-
+-/* Override any GCC internal prototype to avoid an error.
+- Use char because int might match the return type of a GCC
+- builtin and then its argument prototype would still apply. */
+-#ifdef __cplusplus
+-extern "C"
+-#endif
+-char dlopen ();
+-int
+-main ()
+-{
+-return dlopen ();
+- ;
+- return 0;
+-}
+-_ACEOF
+-if ac_fn_c_try_link "$LINENO"; then :
+- netsnmp_result=-l${netsnmp_cur_lib}
+- break
+-fi
+-rm -f core conftest.err conftest.$ac_objext \
+- conftest$ac_exeext conftest.$ac_ext
+- done
+-fi
+-rm -f core conftest.err conftest.$ac_objext \
+- conftest$ac_exeext conftest.$ac_ext
+- LIBS="${netsnmp_func_search_save_LIBS}"
+- netsnmp_cv_func_dlopen_LMIBLIBS="${netsnmp_result}"
+-fi
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $netsnmp_cv_func_dlopen_LMIBLIBS" >&5
+-$as_echo "$netsnmp_cv_func_dlopen_LMIBLIBS" >&6; }
+- if test "${netsnmp_cv_func_dlopen_LMIBLIBS}" != "no" ; then
+- if test "${netsnmp_cv_func_dlopen_LMIBLIBS}" != "none required" ; then
+- LMIBLIBS="${netsnmp_result} ${netsnmp_target_val}"
+- fi
+-
+-
+- fi
+-
+-netsnmp_save_LIBS="$LIBS"
+-LIBS="$LMIBLIBS $LIBS"
+-for ac_func in dlopen
+-do :
+- ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+-if test "x$ac_cv_func_dlopen" = xyes; then :
+- cat >>confdefs.h <<_ACEOF
+-#define HAVE_DLOPEN 1
+-_ACEOF
+-
+-fi
+-done
+-
+-LIBS="$netsnmp_save_LIBS"
+-
+-
+ ##
+ # MIB-module-specific checks
+ ##
+@@ -22482,6 +22515,54 @@ $as_echo "#define HAVE_AES_CFB128_ENCRYPT 1" >>confdefs.h
+
+ fi
+
++
++ as_ac_Lib=`$as_echo "ac_cv_lib_${CRYPTO}''_EVP_MD_CTX_create" | $as_tr_sh`
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_MD_CTX_create in -l${CRYPTO}" >&5
++$as_echo_n "checking for EVP_MD_CTX_create in -l${CRYPTO}... " >&6; }
++if eval \${$as_ac_Lib+:} false; then :
++ $as_echo_n "(cached) " >&6
++else
++ ac_check_lib_save_LIBS=$LIBS
++LIBS="-l${CRYPTO} $LIBS"
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++
++/* Override any GCC internal prototype to avoid an error.
++ Use char because int might match the return type of a GCC
++ builtin and then its argument prototype would still apply. */
++#ifdef __cplusplus
++extern "C"
++#endif
++char EVP_MD_CTX_create ();
++int
++main ()
++{
++return EVP_MD_CTX_create ();
++ ;
++ return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++ eval "$as_ac_Lib=yes"
++else
++ eval "$as_ac_Lib=no"
++fi
++rm -f core conftest.err conftest.$ac_objext \
++ conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++eval ac_res=\$$as_ac_Lib
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
++$as_echo "$ac_res" >&6; }
++if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :
++
++$as_echo "#define HAVE_EVP_MD_CTX_CREATE /**/" >>confdefs.h
++
++
++$as_echo "#define HAVE_EVP_MD_CTX_DESTROY /**/" >>confdefs.h
++
++fi
++
+ fi
+ if echo " $transport_result_list " | $GREP "DTLS" > /dev/null; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DTLSv1_method in -lssl" >&5
+@@ -22984,6 +23065,38 @@ fi
+ fi
+ MYSQL_LIBS=`$MYSQLCONFIG --libs`
+ MYSQL_INCLUDES=`$MYSQLCONFIG --cflags`
++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether MY_INIT() works" >&5
++$as_echo_n "checking whether MY_INIT() works... " >&6; }
++ _libs="${LIBS}"
++ _cppflags="${CPPFLAGS}"
++ LIBS="${LIBS} ${MYSQL_LIBS}"
++ CPPFLAGS="${CPPFLAGS} ${MYSQL_INCLUDES}"
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++#include <mysql/my_global.h>
++ #include <mysql/my_sys.h>
++int
++main ()
++{
++MY_INIT("my_init_test")
++ ;
++ return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++$as_echo "yes" >&6; }
++else
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++
++$as_echo "#define HAVE_BROKEN_LIBMYSQLCLIENT 1" >>confdefs.h
++
++fi
++rm -f core conftest.err conftest.$ac_objext \
++ conftest$ac_exeext conftest.$ac_ext
++ CPPFLAGS="${_cppflags}"
++ LIBS="${_libs}"
+
+ cat >> configure-summary << EOF
+ MYSQL Trap Logging: enabled
+@@ -24771,7 +24884,7 @@ done
+
+
+ # Library:
+-for ac_func in closedir fork getipnodebyname gettimeofday if_nametoindex mkstemp opendir readdir regcomp setenv setitimer setlocale setsid snprintf strcasestr strdup strerror strncasecmp sysconf times vsnprintf
++for ac_func in closedir fgetc_unlocked flockfile fork funlockfile getipnodebyname gettimeofday if_nametoindex mkstemp opendir readdir regcomp setenv setitimer setlocale setsid snprintf strcasestr strdup strerror strncasecmp sysconf times vsnprintf
+ do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+@@ -24941,6 +25054,19 @@ esac
+
+ fi
+
++ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat"
++if test "x$ac_cv_func_strlcat" = xyes; then :
++ $as_echo "#define HAVE_STRLCAT 1" >>confdefs.h
++
++else
++ case " $LIBOBJS " in
++ *" strlcat.$ac_objext "* ) ;;
++ *) LIBOBJS="$LIBOBJS strlcat.$ac_objext"
++ ;;
++esac
++
++fi
++
+ ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy"
+ if test "x$ac_cv_func_strlcpy" = xyes; then :
+ $as_echo "#define HAVE_STRLCPY 1" >>confdefs.h
+@@ -25651,6 +25777,28 @@ _ACEOF
+ fi
+
+
++# struct ethtool_cmd
++#
++if test "x$ac_cv_header_linux_ethtool_h" = "xyes" ; then
++ac_fn_c_check_member "$LINENO" "struct ethtool_cmd" "speed_hi" "ac_cv_member_struct_ethtool_cmd_speed_hi" "
++ $ac_includes_default
++
++#ifdef HAVE_LINUX_ETHTOOL_H
++#include <linux/ethtool.h>
++#endif
++
++"
++if test "x$ac_cv_member_struct_ethtool_cmd_speed_hi" = xyes; then :
++
++cat >>confdefs.h <<_ACEOF
++#define HAVE_STRUCT_ETHTOOL_CMD_SPEED_HI 1
++_ACEOF
++
++
++fi
++
++fi
++
+ # struct ipstat
+ # Agent:
+ #
+@@ -26526,6 +26674,50 @@ _ACEOF
+ fi
+
+
++# extern timezone
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking extern timezone" >&5
++$as_echo_n "checking extern timezone... " >&6; }
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++
++#if TIME_WITH_SYS_TIME
++# include <sys/time.h>
++# include <time.h>
++#else
++# if HAVE_SYS_TIME_H
++# include <sys/time.h>
++# else
++# include <time.h>
++# endif
++#endif
++
++int
++main ()
++{
++
++ return timezone;
++
++ ;
++ return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++$as_echo "yes" >&6; }
++
++$as_echo "#define HAVE_TIMEZONE_VARIABLE 1" >>confdefs.h
++
++
++else
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++
++fi
++rm -f core conftest.err conftest.$ac_objext \
++ conftest$ac_exeext conftest.$ac_ext
++
+ # struct timezone
+ # Library:
+ #
+diff --git a/configure.d/config_modules_agent b/configure.d/config_modules_agent
+index 87ec3a5..3272679 100644
+--- a/configure.d/config_modules_agent
++++ b/configure.d/config_modules_agent
+@@ -189,7 +189,8 @@ while test "x$new_module_list" != "x"; do
+ module_type=mib_module
+ if test -f $srcdir/$mibdir/$i.h; then
+ changequote(, )
+- module_type=`$MODULECPP module_tmp_header.h | $GREP config_belongs_in | $SED 's@.*config_belongs_in(\([^)]*\)).*@\1@'`
++ module_type=`$MODULECPP module_tmp_header.h | \
++ $SED -n 's@.*config_belongs_in(\([^)]*\)).*@\1@p'`
+ changequote([, ])
+ fi
+ if test "x$module_type" = "x" ; then
+@@ -270,7 +271,8 @@ while test "x$new_module_list" != "x"; do
+ # check if $i has any conflicts
+ #
+ AH_TOP([#define config_exclude(x)])
+- new_list_excl=`$MODULECPP module_tmp_header.h | $GREP config_exclude | $SED 's/.*config_exclude(\(.*\)).*/\1/'`
++ new_list_excl=`$MODULECPP module_tmp_header.h | \
++ $SED -n 's/.*config_exclude(\(.*\)).*/\1/p'`
+ if test "x$new_list_excl" != "x"; then
+ AC_MSG_MODULE_DBG("$i excludes $new_list_excl")
+ for j in $new_list_excl
+@@ -299,7 +301,8 @@ while test "x$new_module_list" != "x"; do
+ #
+ AH_TOP([#define config_arch_require(x,y)])
+ changequote(, )
+- new_list_arch=`$MODULECPP module_tmp_header.h | $GREP config_arch_require | $SED 's/.*config_arch_require( *\([^ ]*\) *, *\([^ ]*\) *).*/\1-xarchx-\2/'`
++ new_list_arch=`$MODULECPP module_tmp_header.h | \
++ $SED -n 's/.*config_arch_require( *\([^ ]*\) *, *\([^ ]*\) *).*/\1-xarchx-\2/p'`
+ changequote([, ])
+ if test "x$new_list_arch" != "x"; then
+ for j in $new_list_arch
+@@ -320,11 +323,7 @@ while test "x$new_module_list" != "x"; do
+ #
+ AH_TOP([#define config_version_require(x)])
+ [new_list_alt3=`$MODULECPP module_tmp_header.h | \
+- $GREP config_version_require | \
+- $SED -e 's/ */ /g' \
+- -e 's/.*config_version_require(( *\([^)]*\) *)).*/\1/' \
+- -e 's/ *, */,/g' | \
+- awk '
++ $AWK '
+ BEGIN {
+ if("'"$enable_new_features"'" == "yes")
+ method="max";
+@@ -336,7 +335,10 @@ while test "x$new_module_list" != "x"; do
+ split("'"$with_features_of"'", a);
+ version=sprintf("%03d%03d%03d%03d", a[1], a[2], a[3], a[4]);
+ }
+- {
++ /config_version_require/ {
++ gsub("^.*config_version_require *\\\\(\\\\(", "");
++ gsub("\\\\)\\\\).*$", "");
++ gsub(", *", ",");
+ FS = ",";
+ n = split($0, a);
+ FS = ".";
+@@ -362,7 +364,8 @@ while test "x$new_module_list" != "x"; do
+ # check if $i has any other required modules
+ #
+ AH_TOP([#define config_require(x)])
+- new_list="$new_list `$MODULECPP module_tmp_header.h | $GREP config_require | $SED 's/.*config_require(\(.*\)).*/\1/'`"
++ new_list="$new_list `$MODULECPP module_tmp_header.h | \
++ $SED -n 's/.*config_require(\(.*\)).*/\1/p'`"
+ AC_MSG_MODULE_DBG(" $i will test: $new_list")
+ if test "x$new_list" != "x"; then
+ for j in $new_list
+@@ -398,7 +401,8 @@ while test "x$new_module_list" != "x"; do
+ # check if $i has any mibs to add
+ #
+ AH_TOP([#define config_add_mib(x)])
+- new_mibs=`$MODULECPP module_tmp_header.h | $GREP config_add_mib | $SED 's/.*config_add_mib(\(.*\)).*/\1/'`
++ new_mibs=`$MODULECPP module_tmp_header.h | \
++ $SED -n 's/.*config_add_mib(\(.*\)).*/\1/p'`
+ if test "x$new_mibs" != "x"; then
+ for j in $new_mibs
+ do
+@@ -434,7 +438,7 @@ while test "x$new_module_list" != "x"; do
+ #-------------------
+ # check for unsupported config_load_mib
+ #
+- if $MODULECPP module_tmp_header.h | $GREP config_load_mib > /dev/null 2>&1; then
++ if $MODULECPP module_tmp_header.h | $GREP -q config_load_mib; then
+ AC_MSG_WARN([mib module error])
+ AC_MSG_WARN([mib module "$i" uses the "config_load_mib" directive, which is no longer supported. It probably won't work.])
+ fi # grep config_load_mib
+@@ -445,7 +449,8 @@ while test "x$new_module_list" != "x"; do
+ #
+ AH_TOP([#define config_parse_dot_conf(w,x,y,z)])
+ changequote(, )
+- $MODULECPP module_tmp_header.h | $GREP config_parse_dot_conf | $SED 's@.*config_parse_dot_conf(\([^)]*\), *\([^),]*\), *\([^),]*\), *\([^),]*\)).*@register_config_handler("snmpd",\1, \2, \3, \4);@' >> $mibdir/mib_module_dot_conf.h
++ $MODULECPP module_tmp_header.h | \
++ $SED -n 's@.*config_parse_dot_conf(\([^)]*\), *\([^),]*\), *\([^),]*\), *\([^),]*\)).*@register_config_handler("snmpd",\1, \2, \3, \4);@p' >> $mibdir/mib_module_dot_conf.h
+ changequote([, ])
+
+ #---------------------
+@@ -455,7 +460,8 @@ while test "x$new_module_list" != "x"; do
+ # check if $i has any errors, or warnings
+ #
+ AH_TOP([#define config_error(x)])
+- error=`$MODULECPP module_tmp_header.h | $GREP config_error | $SED 's/.*config_error(\(.*\)).*/\1/'`
++ error=`$MODULECPP module_tmp_header.h | \
++ $SED -n 's/.*config_error(\(.*\)).*/\1/p'`
+ if test "x$error" != "x"; then
+ echo
+ echo
+@@ -467,7 +473,8 @@ while test "x$new_module_list" != "x"; do
+ # - used to signal a configuration "warning" to be printed to the user
+ #
+ AH_TOP([#define config_warning(x)])
+- warning=`$MODULECPP module_tmp_header.h | $GREP config_warning | $SED 's/.*config_warning(\(.*\)).*/\1/'`
++ warning=`$MODULECPP module_tmp_header.h | \
++ $SED -n 's/.*config_warning(\(.*\)).*/\1/p'`
+ if test "x$warning" != "x"; then
+ all_warnings="$all_warnings $warning
+ "
+diff --git a/configure.d/config_modules_transports b/configure.d/config_modules_transports
+index 2a49da8..b10b960 100644
+--- a/configure.d/config_modules_transports
++++ b/configure.d/config_modules_transports
+@@ -71,7 +71,7 @@ while test "x$new_transport_list" != "x"; do
+ rm -f conftest.$ac_ext module_tmp_header.h
+ AC_LANG_CONFTEST([AC_LANG_SOURCE([[
+ #include NETSNMP_SYSTEM_INCLUDE_FILE
+-#define NETSNMP_FEATURE_CHECKING
++#undef NETSNMP_MINIMAL_CODE
+ #define NET_SNMP_CONFIG_H
+ #undef config_require
+ #define config_require(foo) config_checkit_require(foo)
+diff --git a/configure.d/config_os_functions b/configure.d/config_os_functions
+index 7736994..3c5385b 100644
+--- a/configure.d/config_os_functions
++++ b/configure.d/config_os_functions
+@@ -31,7 +31,8 @@ AC_CHECK_FUNCS([lrand48 rand random ] dnl
+ [signal sigset ] )
+
+ # Library:
+-AC_CHECK_FUNCS([closedir fork getipnodebyname ] dnl
++AC_CHECK_FUNCS([closedir fgetc_unlocked flockfile ] dnl
++ [fork funlockfile getipnodebyname ] dnl
+ [gettimeofday if_nametoindex mkstemp ] dnl
+ [opendir readdir regcomp ] dnl
+ [setenv setitimer setlocale ] dnl
+@@ -82,8 +83,8 @@ esac
+ AC_CONFIG_LIBOBJ_DIR([snmplib])
+
+ AC_REPLACE_FUNCS([getopt inet_ntop inet_pton ] dnl
+- [strlcpy strtok_r strtol ] dnl
+- [strtoul strtoull ] )
++ [strlcat strlcpy strtok_r ] dnl
++ [strtol strtoul strtoull ] )
+
+ # Agent:
+ AC_CHECK_FUNCS([cgetnext chown execv ] dnl
+@@ -133,7 +134,7 @@ fi
+ AC_MSG_CHECKING([[for two-argument statfs with struct fs_data (Ultrix)]])
+ AC_CACHE_VAL(
+ fu_cv_sys_stat_fs_data,
+- [AC_TRY_RUN([
++ [AC_RUN_IFELSE([AC_LANG_SOURCE([[
+ #ifdef HAVE_SYS_PARAM_H
+ #include <sys/param.h>
+ #endif
+@@ -150,10 +151,10 @@ struct fs_data fsd;
+ /* Ultrix's statfs returns 1 for success,
+ 0 for not mounted, -1 for failure. */
+ exit (statfs (".", &fsd) != 1);
+-}],
+- fu_cv_sys_stat_fs_data=yes,
+- fu_cv_sys_stat_fs_data=no,
+- fu_cv_sys_stat_fs_data=no)])
++}]])],
++ [fu_cv_sys_stat_fs_data=yes],
++ [fu_cv_sys_stat_fs_data=no],
++ [fu_cv_sys_stat_fs_data=no])])
+ AC_MSG_RESULT($fu_cv_sys_stat_fs_data)
+ if test $fu_cv_sys_stat_fs_data = yes; then
+ AC_DEFINE(STAT_STATFS_FS_DATA, 1,
+@@ -309,10 +310,11 @@ if echo " $transport_result_list " | $GREP "DTLS" > /dev/null; then
+ [
+ oldLIBS="$LIBS"
+ LIBS="$LIBS -lcrypto"
+- AC_TRY_LINK(
+- [#include <openssl/bio.h>],
+- [BIO_dgram_get_peer(NULL, NULL);],,
+- AC_MSG_ERROR([DTLS support requires a newer version of OpenSSL]))
++ AC_LINK_IFELSE(
++ [AC_LANG_PROGRAM(
++ [[#include <openssl/bio.h>]],
++ [[BIO_dgram_get_peer(NULL, NULL);]])], [],
++ [AC_MSG_ERROR(DTLS support requires a newer version of OpenSSL)])
+
+ LIBS="$oldLIBS"
+ ]
+diff --git a/configure.d/config_os_headers b/configure.d/config_os_headers
+index 23cc38d..d903f58 100644
+--- a/configure.d/config_os_headers
++++ b/configure.d/config_os_headers
+@@ -30,9 +30,18 @@ AC_CHECK_HEADERS([getopt.h pthread.h regex.h ] dnl
+ [sys/timeb.h ] dnl
+ [sys/un.h ])
+
++# Library and Agent:
++AC_CHECK_HEADERS([nlist.h],,,[
++AC_INCLUDES_DEFAULT
++[
++#ifndef LIBBSD_DISABLE_DEPRECATED
++#define LIBBSD_DISABLE_DEPRECATED 1
++#endif
++]])
++
+ # Library:
+ AC_CHECK_HEADERS([fcntl.h io.h kstat.h ] dnl
+- [limits.h locale.h nlist.h ] dnl
++ [limits.h locale.h ] dnl
+ [sys/file.h sys/ioctl.h ] dnl
+ [sys/sockio.h sys/stat.h ] dnl
+ [sys/systemcfg.h sys/systeminfo.h ] dnl
+@@ -45,7 +54,7 @@ AC_CHECK_HEADERS([dlfcn.h err.h fcntl.h fstab.h ] dnl
+ [ grp.h io.h ] dnl
+ [ioctls.h kstat.h kvm.h limits.h ] dnl
+ [ mntent.h mtab.h ] dnl
+- [nlist.h pkglocs.h pwd.h ] dnl
++ [ pkglocs.h pwd.h ] dnl
+ [ utmpx.h utsname.h ])
+
+ AC_CHECK_HEADERS([sys/diskio.h sys/dkio.h ] dnl
+diff --git a/configure.d/config_os_libs1 b/configure.d/config_os_libs1
+index ce33d34..35f052a 100644
+--- a/configure.d/config_os_libs1
++++ b/configure.d/config_os_libs1
+@@ -84,3 +84,12 @@ netsnmp_save_LIBS="$LIBS"
+ LIBS="$LAGENTLIBS $LMIBLIBS $LIBS"
+ AC_CHECK_FUNCS([kvm_openfiles kvm_getprocs kvm_getproc2 kvm_getswapinfo])
+ LIBS="$netsnmp_save_LIBS"
++
++#
++# dynamic module support
++#
++NETSNMP_SEARCH_LIBS([dlopen], [dl],,, [$LAGENTLIBS $LSNMPLIBS], [LMIBLIBS])
++netsnmp_save_LIBS="$LIBS"
++LIBS="$LMIBLIBS $LAGENTLIBS $LSNMPLIBS $LIBS"
++AC_CHECK_FUNCS([dlopen])
++LIBS="$netsnmp_save_LIBS"
+diff --git a/configure.d/config_os_libs2 b/configure.d/config_os_libs2
+index 22ab764..fa846c8 100644
+--- a/configure.d/config_os_libs2
++++ b/configure.d/config_os_libs2
+@@ -158,15 +158,6 @@ NETSNMP_SEARCH_LIBS(kstat_lookup, kstat,
+ LNETSNMPLIBS)
+
+
+-# dynamic module support
+-#
+-NETSNMP_SEARCH_LIBS(dlopen, dl,,,,LMIBLIBS)
+-netsnmp_save_LIBS="$LIBS"
+-LIBS="$LMIBLIBS $LIBS"
+-AC_CHECK_FUNCS([dlopen])
+-LIBS="$netsnmp_save_LIBS"
+-
+-
+ ##
+ # MIB-module-specific checks
+ ##
+@@ -277,6 +268,12 @@ if test "x$tryopenssl" != "xno" -a "x$tryopenssl" != "xinternal"; then
+ AC_CHECK_LIB(${CRYPTO}, AES_cfb128_encrypt,
+ AC_DEFINE(HAVE_AES_CFB128_ENCRYPT, 1,
+ [Define to 1 if you have the `AES_cfb128_encrypt' function.]))
++
++ AC_CHECK_LIB(${CRYPTO}, EVP_MD_CTX_create,
++ AC_DEFINE([HAVE_EVP_MD_CTX_CREATE], [],
++ [Define to 1 if you have the `EVP_MD_CTX_create' function.])
++ AC_DEFINE([HAVE_EVP_MD_CTX_DESTROY], [],
++ [Define to 1 if you have the `EVP_MD_CTX_destroy' function.]))
+ fi
+ if echo " $transport_result_list " | $GREP "DTLS" > /dev/null; then
+ AC_CHECK_LIB(ssl, DTLSv1_method,
+@@ -408,12 +405,11 @@ if test "$with_libwrap" != "no"; then
+ LIBS="$LIBS -lwrap"
+ AC_MSG_CHECKING([for TCP wrappers library -lwrap])
+ # XXX: should check for hosts_ctl
+- AC_TRY_LINK(
+- [#include <sys/types.h>
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
+ #include <tcpd.h>
+ int allow_severity = 0;
+- int deny_severity = 0;],
+- [hosts_access((void *)0)],
++ int deny_severity = 0;]],
++ [[hosts_access((void *)0)]])],
+ [AC_MSG_RESULT([yes])
+ AC_DEFINE(NETSNMP_USE_LIBWRAP)
+ test "$with_libwrap" != no -a "$with_libwrap" != yes && _wraplibs="-L$with_libwrap/lib"
+@@ -423,12 +419,11 @@ if test "$with_libwrap" != "no"; then
+ AC_CHECK_FUNC(yp_get_default_domain, ,
+ AC_CHECK_LIB(nsl, yp_get_default_domain))
+ AC_MSG_CHECKING([for TCP wrappers library -lwrap linked with -lnsl])
+- AC_TRY_LINK(
+- [#include <sys/types.h>
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
+ #include <tcpd.h>
+ int allow_severity = 0;
+- int deny_severity = 0;],
+- [hosts_access((void *)0)],
++ int deny_severity = 0;]],
++ [[hosts_access((void *)0)]])],
+ [AC_MSG_RESULT(yes)
+ AC_DEFINE(NETSNMP_USE_LIBWRAP)
+ test "$with_libwrap" != no -a "$with_libwrap" != yes && _wraplibs="-L$with_libwrap/lib"
+@@ -454,6 +449,17 @@ if test "x$with_mysql" = "xyes" ; then
+ fi
+ MYSQL_LIBS=`$MYSQLCONFIG --libs`
+ MYSQL_INCLUDES=`$MYSQLCONFIG --cflags`
++ AC_MSG_CHECKING([whether MY_INIT() works])
++ _libs="${LIBS}"
++ _cppflags="${CPPFLAGS}"
++ LIBS="${LIBS} ${MYSQL_LIBS}"
++ CPPFLAGS="${CPPFLAGS} ${MYSQL_INCLUDES}"
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <mysql/my_global.h>
++ #include <mysql/my_sys.h>]], [[MY_INIT("my_init_test")]])],[AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)
++ AC_DEFINE([HAVE_BROKEN_LIBMYSQLCLIENT], 1,
++ [Define if using MY_INIT() causes a linker error])])
++ CPPFLAGS="${_cppflags}"
++ LIBS="${_libs}"
+ AC_MSG_CACHE_ADD(MYSQL Trap Logging: enabled)
+ else
+ AC_MSG_CACHE_ADD(MYSQL Trap Logging: unavailable)
+diff --git a/configure.d/config_os_struct_members b/configure.d/config_os_struct_members
+index 17bb489..9f015ac 100644
+--- a/configure.d/config_os_struct_members
++++ b/configure.d/config_os_struct_members
+@@ -57,6 +57,18 @@ AC_CHECK_MEMBERS([struct dirent.d_type],,,[
+ #endif
+ ]])
+
++# struct ethtool_cmd
++#
++if test "x$ac_cv_header_linux_ethtool_h" = "xyes" ; then
++AC_CHECK_MEMBERS([struct ethtool_cmd.speed_hi],,,[
++ AC_INCLUDES_DEFAULT()
++ [
++#ifdef HAVE_LINUX_ETHTOOL_H
++#include <linux/ethtool.h>
++#endif
++ ]])
++fi
++
+ # struct ipstat
+ # Agent:
+ #
+@@ -310,6 +322,28 @@ AC_CHECK_MEMBERS([struct tm.tm_gmtoff],,,[
+ #endif
+ ]])
+
++# extern timezone
++AC_MSG_CHECKING([extern timezone])
++AC_LINK_IFELSE([AC_LANG_PROGRAM([[
++#if TIME_WITH_SYS_TIME
++# include <sys/time.h>
++# include <time.h>
++#else
++# if HAVE_SYS_TIME_H
++# include <sys/time.h>
++# else
++# include <time.h>
++# endif
++#endif
++]], [[
++ return timezone;
++]])], [
++AC_MSG_RESULT([yes])
++AC_DEFINE([HAVE_TIMEZONE_VARIABLE], [1], [Define if a timezone variable is declared in <sys/time.h>])
++], [
++AC_MSG_RESULT([no])
++])
++
+ # struct timezone
+ # Library:
+ #
+diff --git a/configure.d/config_project_with_enable b/configure.d/config_project_with_enable
+index 732742b..2cf7aec 100644
+--- a/configure.d/config_project_with_enable
++++ b/configure.d/config_project_with_enable
+@@ -93,7 +93,12 @@ NETSNMP_ARG_WITH(openssl,
+ elif test "x$withval" = "xno"; then
+ tryopenssl=no
+ elif test -d "$withval"; then
+- AC_ADD_SEARCH_PATH($withval)
++ if test -d "$withval/lib/MinGW"; then
++ LDFLAGS="-L$withval/lib/MinGW $LDFLAGS"
++ CPPFLAGS="-I$withval/include $CPPFLAGS"
++ else
++ AC_ADD_SEARCH_PATH($withval)
++ fi
+ tryopenssl=yes
+ askedopenssl=yes
+ fi,
+diff --git a/dist/extractnews b/dist/extractnews
+index 848909a..bce94c9 100755
+--- a/dist/extractnews
++++ b/dist/extractnews
+@@ -19,12 +19,13 @@ LocalGetOptions(\%opts,
+ "",
+ ['c|changes-file=s','A file to save CHANGES entries to'],
+ ['n|news-file=s','A file to save NEWS entries to'],
++ ['d|debug-line=s', 'Debugging output for lines matching STRING'],
+ "",
+ ['GUI:otherargs_text','Input files to parse'],
+ );
+
+ my $maybecontinue = 0;
+-my $lasttext = 0;
++my $lasttext = "";
+ my $lastfile;
+ my $lastcomponent;
+
+@@ -41,32 +42,51 @@ foreach my $argv (@ARGV) {
+
+ last if ($opts{'e'} && /$opts{e}/o);
+
++ print STDERR "here: $_" if ($opts{'d'} && /$opts{'d'}/o);
++
+ # don't use this:
+ # FILE: BUGS: 123,456: text
+ ($file, $patbug, $nums, $text) =
+ /(NEWS|CHANGES):\s*-*\s*\[*(BUG|PATCH)(?:ES|S|):*\s*([\d,\s*]*)\]*:*\s*-*\s*(.*)/;
+
++ print STDERR " 1:$file, $component, $patbug, $nums, $text\n" if ($opts{'d'} && /$opts{'d'}/o);
++
+ # or this:
+ # FILE: component - text
+ ($file, $component, $text) =
+ /(NEWS|CHANGES):\s*(\w+)\s*-+\s*(.*)/ if (!$file);
+
++ print STDERR " 2:$file, $component, $patbug, $nums, $text\n" if ($opts{'d'} && /$opts{'d'}/o);
++
+ # what you should use:
+- # FILE: component: text
+- # or
+ # FILE: component: BUGS: 123,456: text
+ #
+ # or
+ # FILE: component: PATCH: 123,456: from someone text
+ # FILE: component: PATCH: 123,456: from "someone long" text
+ ($file, $component, $patbug, $nums, $text) =
+- /(NEWS|CHANGES):\s*([^:]+):\s*-*\s*\[*(BUG|PATCH)*(?:ES|S|):*\s*([\d,\s*]*)\]*:*\s*-*\s*(?:from ["'][^"]+["']|from \w+|):*\s*(.*)/ if (!$file);
++ /(NEWS|CHANGES):\s*([^:]+):\s*-*\s*\[*(BUG|PATCH)(?:ES|S):*\s*([\d,\s*]*)\]*:*\s*-*\s*(?:from ["'][^"]+["']|from \w+|):*\s*(.*)/ if (!$file);
++
++ print STDERR " 3:$file, $component, $patbug, $nums, $text\n" if ($opts{'d'} && /$opts{'d'}/o);
++
++ # or at least:
++ # FILE: component: text
++ ($file, $component, $text) =
++ /(NEWS|CHANGES):\s*([^:]+):\s*-*\s*(.*)/ if (!$file);
++
++ print STDERR " 4:$file, $component, $patbug, $nums, $text\n" if ($opts{'d'} && /$opts{'d'}/o);
+
+ # component left out
+ # FILE: [BUGS: 123,456]: text
+ ($file, $patbug, $nums, $text) =
+ /(NEWS|CHANGES):\s*\[*(BUG|PATCH)*(?:ES|S|):*\s*([\d,\s*]*)\]*:*\s*-*\s*(.*)/ if (!$file);
+
++ print STDERR " 5:$file, $component, $patbug, $nums, $text\n" if ($opts{'d'} && /$opts{'d'}/o);
++
++ if ($opts{'d'} && /$opts{'d'}/o) {
++ my $bogus = 1; # breakable point
++ }
++
+ if (!$file && $maybecontinue) {
+ if (/^\s*(.+)$/) {
+ $text = $1;
+@@ -94,7 +114,8 @@ foreach my $argv (@ARGV) {
+ } else {
+ $lasttext .= " $text";
+ }
+- $lasttext =~ s/^ //;
++ $lasttext =~ s/^ //; # get rid of leading spaces
++ $lasttext =~ s/^([a-z])/uc($1)/e; # capitalize the first letter
+ $text = wrap(" - "," ","$lasttext") . "\n";
+
+ #
+@@ -108,6 +129,7 @@ foreach my $argv (@ARGV) {
+ $component =~ s/^snmp/0snmp/;
+ $component =~ s/^agent/0snmpd/; # Merge "agent" into "snmpd"
+ $component =~ s/^([A-Z])/zz\1/;
++ print STDERR " t:$file, $component, $patbug, $nums, $text\n" if ($opts{'d'} && /$opts{'d'}/o);
+ push @{$output{$opts{'c'}}{$component}}, $text;
+ push @{$output{$opts{'n'}}{$component}}, $text if ($file eq 'NEWS');
+ $lastfile = $file;
+diff --git a/dist/makerelease.xml b/dist/makerelease.xml
+index 1d65e2c..758e889 100644
+--- a/dist/makerelease.xml
++++ b/dist/makerelease.xml
+@@ -33,6 +33,15 @@
+ should be labeled ".rcN" like 5.4.1.rc1.
+ </text>
+ </step>
++ <step type="prompt" prompt="Enter the last version number:"
++ title="Enter the last version number"
++ parameter="LASTVERSION">
++ <text>
++ Please enter the last version number that the changelog should be
++ generated from. This should be easy for a new release on a branch,
++ but may be more tricky for a main release.
++ </text>
++ </step>
+ <step type="perl" title="Defining a second internal version string"
+ mandatory="1">
+ <perl>
+@@ -41,6 +50,9 @@
+ $self->{'parameters'}{'VERSIONTAGNAME'} =
+ "v" . $self->{'parameters'}{'VERSION'};
+
++ $self->{'parameters'}{'LASTVERSIONTAGNAME'} =
++ "v" . $self->{'parameters'}{'LASTVERSION'};
++
+ # target version number (without preN/rcN)
+ $self->{'parameters'}{'VERSIONTARGET'} =
+ $self->{'parameters'}{'VERSION'};
+@@ -361,22 +373,19 @@
+ <command>git commit -m "make depend for {VERSION}" `find . -name Makefile.depend`</command>
+ </commands>
+ </step>
+- <step type="system" stepname="changelog:svn2cl" title="changelog:svn2cl">
++ <step type="system" stepname="changelog:create" title="Creating a changelog update">
+ <text>We need to extract the portions of the change logs
+ committed to the repository.</text>
+- <!-- XXX: git2cl needs to be truncated quite a bit rather than searching the whole history -->
+- <!-- XXX: following branches properly may prove to be interesting -->
+ <commands>
+- <command>git2cl | head -10000 &gt; ChangeLog.add</command>
+- <command>perl dist/changelogfix &lt; ChangeLog.add &gt; ChangeLog.reallyadd</command>
++ <command>git log --no-merges {LASTVERSIONTAGNAME}..HEAD &gt; ChangeLog.add</command>
+ </commands>
+ </step>
+ <step type="informational" pause="true" stepname="changelog:manualedit" title="changelog:manualedit">
+ <text>
+ You need to manually insert the *relevent* portions of
+- 'ChangeLog.reallyadd' into the ChangeLog file.
++ 'ChangeLog.add' into the ChangeLog file.
+
+- I also suggest truncating ChangeLog.reallyadd to only contain
++ I also suggest truncating ChangeLog.add to only contain
+ the *relevent* portions for this release, as this will make
+ CHANGES.new2 and NEWS.new2 more accurate later on.
+
+@@ -396,7 +405,7 @@
+ </step>
+ <step type="system" stepname="docs:newnews" title="docs:newnews">
+ <commands>
+- <command>perl dist/extractnews -c CHANGES.new2 -n NEWS.new2 ChangeLog.reallyadd</command>
++ <command>perl dist/extractnews -c CHANGES.new2 -n NEWS.new2 ChangeLog.add</command>
+ </commands>
+ </step>
+ <step type="informational" pause="true" stepname="docs:README-and-NEWS" title="docs:README">
+diff --git a/dist/release b/dist/release
+index 9e02b5c..52b45b1 100644
+--- a/dist/release
++++ b/dist/release
+@@ -4,4 +4,4 @@
+ # a branch name followed by 'rc' when the branch is in rc phase of a release.
+ #
+ #master rc
+-V5-7-patches rc
++#V5-7-patches rc
+diff --git a/doxygen.conf b/doxygen.conf
+index 6b5eb58..20e457d 100644
+--- a/doxygen.conf
++++ b/doxygen.conf
+@@ -280,7 +280,7 @@ WARNINGS = YES
+ # for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+ # automatically be disabled.
+
+-WARN_IF_UNDOCUMENTED = YES
++WARN_IF_UNDOCUMENTED = NO
+
+ # The WARN_FORMAT tag determines the format of the warning messages that
+ # doxygen can produce. The string should contain the $file, $line, and $text
+diff --git a/include/net-snmp/agent/auto_nlist.h b/include/net-snmp/agent/auto_nlist.h
+index c7cd872..21b6b8c 100644
+--- a/include/net-snmp/agent/auto_nlist.h
++++ b/include/net-snmp/agent/auto_nlist.h
+@@ -12,9 +12,9 @@ extern "C" {
+ #endif
+
+ #ifdef NETSNMP_CAN_USE_NLIST
+-int auto_nlist(const char *, char *, int);
++int auto_nlist(const char *, char *, size_t);
+ long auto_nlist_value(const char *);
+-int KNLookup(struct nlist *, int, char *, int);
++int KNLookup(struct nlist *, int, char *, size_t);
+ #else
+ int auto_nlist_noop(void);
+ # define auto_nlist(x,y,z) auto_nlist_noop()
+diff --git a/include/net-snmp/agent/hardware/cpu.h b/include/net-snmp/agent/hardware/cpu.h
+index bc6f75b..f6e43e5 100644
+--- a/include/net-snmp/agent/hardware/cpu.h
++++ b/include/net-snmp/agent/hardware/cpu.h
+@@ -3,18 +3,18 @@ extern int cpu_num;
+
+ /* For rolling averages */
+ struct netsnmp_cpu_history {
+- long user_hist;
+- long sys_hist;
+- long idle_hist;
+- long nice_hist;
+- long total_hist;
++ unsigned long long user_hist;
++ unsigned long long sys_hist;
++ unsigned long long idle_hist;
++ unsigned long long nice_hist;
++ unsigned long long total_hist;
+
+- long ctx_hist;
+- long intr_hist;
+- long swpi_hist;
+- long swpo_hist;
+- long pagei_hist;
+- long pageo_hist;
++ unsigned long long ctx_hist;
++ unsigned long long intr_hist;
++ unsigned long long swpi_hist;
++ unsigned long long swpo_hist;
++ unsigned long long pagei_hist;
++ unsigned long long pageo_hist;
+ };
+
+ struct netsnmp_cpu_info_s {
+@@ -25,30 +25,30 @@ struct netsnmp_cpu_info_s {
+ int status;
+
+ /* For UCD cpu stats */
+- long user_ticks;
+- long nice_ticks;
+- long sys_ticks;
+- long idle_ticks;
+- long wait_ticks;
+- long kern_ticks;
+- long intrpt_ticks;
+- long sirq_ticks;
+- long steal_ticks;
+- long guest_ticks;
+- long guestnice_ticks;
++ unsigned long long user_ticks;
++ unsigned long long nice_ticks;
++ unsigned long long sys_ticks;
++ unsigned long long idle_ticks;
++ unsigned long long wait_ticks;
++ unsigned long long kern_ticks;
++ unsigned long long intrpt_ticks;
++ unsigned long long sirq_ticks;
++ unsigned long long steal_ticks;
++ unsigned long long guest_ticks;
++ unsigned long long guestnice_ticks;
+
+- long total_ticks;
+- long sys2_ticks; /* For non-atomic system counts */
++ unsigned long long total_ticks;
++ unsigned long long sys2_ticks; /* For non-atomic system counts */
+
+ /* For paging-related UCD stats */
+ /* XXX - Do these belong elsewhere ?? */
+ /* XXX - Do Not Use - Subject to Change */
+- long pageIn;
+- long pageOut;
+- long swapIn;
+- long swapOut;
+- long nInterrupts;
+- long nCtxSwitches;
++ unsigned long long pageIn;
++ unsigned long long pageOut;
++ unsigned long long swapIn;
++ unsigned long long swapOut;
++ unsigned long long nInterrupts;
++ unsigned long long nCtxSwitches;
+
+ struct netsnmp_cpu_history *history;
+
+diff --git a/include/net-snmp/agent/snmp_agent.h b/include/net-snmp/agent/snmp_agent.h
+index 240ca94..aad8837 100644
+--- a/include/net-snmp/agent/snmp_agent.h
++++ b/include/net-snmp/agent/snmp_agent.h
+@@ -271,6 +271,7 @@ extern "C" {
+ u_long netsnmp_marker_uptime(marker_t pm);
+ u_long netsnmp_timeval_uptime(struct timeval *tv);
+ const_marker_t netsnmp_get_agent_starttime(void);
++ uint64_t netsnmp_get_agent_runtime(void);
+ void netsnmp_set_agent_starttime(marker_t s);
+ u_long netsnmp_get_agent_uptime(void);
+ void netsnmp_set_agent_uptime(u_long hsec);
+diff --git a/include/net-snmp/library/default_store.h b/include/net-snmp/library/default_store.h
+index e1b2e24..3c3c519 100644
+--- a/include/net-snmp/library/default_store.h
++++ b/include/net-snmp/library/default_store.h
+@@ -37,7 +37,8 @@ extern "C" {
+ * begin storage definitions
+ */
+ /**
+- * @def NETSNMP_DS_LIBRARY_ID These definitions correspond with the "storid" argument to the API
++ * @def NETSNMP_DS_LIBRARY_ID
++ * These definitions correspond with the "storid" argument to the API.
+ */
+ #define NETSNMP_DS_LIBRARY_ID 0
+ #define NETSNMP_DS_APPLICATION_ID 1
+diff --git a/include/net-snmp/library/large_fd_set.h b/include/net-snmp/library/large_fd_set.h
+index 67a473c..9b547cd 100644
+--- a/include/net-snmp/library/large_fd_set.h
++++ b/include/net-snmp/library/large_fd_set.h
+@@ -16,7 +16,7 @@
+ #include <sys/select.h>
+ #endif
+
+-#if defined(HAVE_WINSOCK_H) && ! defined(_WINSOCKAPI_) && ! defined(_WINSOCK_H)
++#if defined(HAVE_WINSOCK_H) && !defined(_WINSOCKAPI_) && !defined(_WINSOCK_H)
+ #error <winsock.h> or <winsock2.h> must have been included before this file.
+ #endif
+
+@@ -44,15 +44,19 @@ extern "C" {
+
+ /**
+ * Test whether set *fdset contains socket fd.
+- * Do nothing if fd >= fdset->lfs_setsize.
++ * Evaluates to zero (false) if fd >= fdset->lfs_setsize.
+ */
+ #define NETSNMP_LARGE_FD_ISSET(fd, fdset) \
+ netsnmp_large_fd_is_set(fd, fdset)
+
+-#if ! defined(cygwin) && defined(HAVE_WINSOCK_H)
++#if !defined(cygwin) && defined(HAVE_WINSOCK_H)
+
+-/** Number of bytes needed to store setsize file descriptors. */
+-#define NETSNMP_FD_SET_BYTES(setsize) (sizeof(fd_set) + sizeof(SOCKET) * (setsize - FD_SETSIZE))
++/**
++ * Number of bytes needed to store a number of file descriptors as a
++ * struct fd_set.
++ */
++#define NETSNMP_FD_SET_BYTES(setsize) \
++ (sizeof(fd_set) + ((setsize) - FD_SETSIZE) * sizeof(SOCKET))
+
+ /** Remove all sockets from the set *fdset. */
+ #define NETSNMP_LARGE_FD_ZERO(fdset) \
+@@ -74,28 +78,29 @@ int netsnmp_large_fd_is_set(SOCKET fd, netsnmp_large_fd_set *fdset);
+ * According to SUSv2, this array must have the name fds_bits. See also
+ * <a href="http://www.opengroup.org/onlinepubs/007908775/xsh/systime.h.html">The Single UNIX Specification, Version 2, &lt;sys/time.h&gt;</a>.
+ */
+-#define NETSNMP_FD_MASK_SIZE sizeof(((fd_set*)0)->fds_bits)
++#define NETSNMP_FD_MASK_SIZE sizeof(((fd_set*)0)->fds_bits[0])
+
+-/** Number of bits in one element of the fd_set::fds_bits array. */
++/** Number of bits in one element of the fd_set.fds_bits array. */
+ #define NETSNMP_BITS_PER_FD_MASK (8 * NETSNMP_FD_MASK_SIZE)
+
+ /** Number of elements needed for the fds_bits array. */
+ #define NETSNMP_FD_SET_ELEM_COUNT(setsize) \
+ (setsize + NETSNMP_BITS_PER_FD_MASK - 1) / NETSNMP_BITS_PER_FD_MASK
+
+-/** Number of bytes needed to store setsize file descriptors. */
+-#define NETSNMP_FD_SET_BYTES(setsize) \
+- (NETSNMP_FD_SET_ELEM_COUNT(setsize) * NETSNMP_FD_MASK_SIZE)
++/**
++ * Number of bytes needed to store a number of file descriptors as a
++ * struct fd_set.
++ */
++#define NETSNMP_FD_SET_BYTES(setsize) \
++ (sizeof(fd_set) + NETSNMP_FD_SET_ELEM_COUNT((setsize) - FD_SETSIZE) \
++ * NETSNMP_FD_MASK_SIZE)
+
+ /** Remove all file descriptors from the set *fdset. */
+-#define NETSNMP_LARGE_FD_ZERO(fdset) \
+- do { \
+- int __i; \
+- fd_set *__arr = &(fdset)->lfs_set; \
+- __i = NETSNMP_FD_SET_ELEM_COUNT((fdset)->lfs_setsize); \
+- for ( ; __i > 0; __i--) \
+- __arr->fds_bits[__i - 1] = 0; \
+- } while (0)
++#define NETSNMP_LARGE_FD_ZERO(fdset) \
++ do { \
++ memset((fdset)->lfs_setptr, 0, \
++ NETSNMP_FD_SET_BYTES((fdset)->lfs_setsize)); \
++ } while (0)
+
+
+ void netsnmp_large_fd_setfd( int fd, netsnmp_large_fd_set *fdset);
+@@ -118,8 +123,10 @@ void netsnmp_large_fd_set_init( netsnmp_large_fd_set *fdset, int setsize);
+ /**
+ * Modify the size of a file descriptor set and preserve the first
+ * min(fdset->lfs_setsize, setsize) file descriptors.
++ *
++ * Returns 1 upon success or 0 if memory allocation failed.
+ */
+-void netsnmp_large_fd_set_resize( netsnmp_large_fd_set *fdset, int setsize);
++int netsnmp_large_fd_set_resize( netsnmp_large_fd_set *fdset, int setsize);
+
+ /**
+ * Synchronous I/O multiplexing for large file descriptor sets.
+diff --git a/include/net-snmp/library/oid.h b/include/net-snmp/library/oid.h
+index 5468713..e7adf41 100644
+--- a/include/net-snmp/library/oid.h
++++ b/include/net-snmp/library/oid.h
+@@ -7,7 +7,7 @@
+
+ #ifndef EIGHTBIT_SUBIDS
+ typedef u_long oid;
+-#define MAX_SUBID 0xFFFFFFFF
++#define MAX_SUBID 0xFFFFFFFFUL
+ #define NETSNMP_PRIo "l"
+ #else
+ typedef uint8_t oid;
+diff --git a/include/net-snmp/library/snmp_alarm.h b/include/net-snmp/library/snmp_alarm.h
+index 0fe2cf1..8437c1d 100644
+--- a/include/net-snmp/library/snmp_alarm.h
++++ b/include/net-snmp/library/snmp_alarm.h
+@@ -55,6 +55,8 @@ extern "C" {
+ NETSNMP_IMPORT void run_alarms(void);
+ RETSIGTYPE alarm_handler(int a);
+ void set_an_alarm(void);
++ int netsnmp_get_next_alarm_time(struct timeval *alarm_tm,
++ const struct timeval *now);
+ int get_next_alarm_delay_time(struct timeval *delta);
+
+
+diff --git a/include/net-snmp/library/snmp_api.h b/include/net-snmp/library/snmp_api.h
+index e32d62b..f57b678 100644
+--- a/include/net-snmp/library/snmp_api.h
++++ b/include/net-snmp/library/snmp_api.h
+@@ -418,7 +418,6 @@ typedef struct request_list {
+ #endif
+
+ int create_user_from_session(netsnmp_session * session);
+- int snmp_get_fd_for_session(struct snmp_session *sessp);
+ int snmpv3_probe_contextEngineID_rfc5343(void *slp,
+ netsnmp_session *session);
+
+diff --git a/include/net-snmp/library/snmp_enum.h b/include/net-snmp/library/snmp_enum.h
+index 3ab470e..237891d 100644
+--- a/include/net-snmp/library/snmp_enum.h
++++ b/include/net-snmp/library/snmp_enum.h
+@@ -94,10 +94,11 @@ extern "C" {
+ * Persistent enumeration lists
+ */
+ void se_store_enum_list(struct snmp_enum_list *new_list,
+- const char *token, char *type);
+- void se_store_list(unsigned int major, unsigned int minor, char *type);
++ const char *token, const char *type);
++ void se_store_list(unsigned int major, unsigned int minor,
++ const char *type);
+ void se_clear_slist(const char *listname);
+- void se_store_slist(const char *listname, char *type);
++ void se_store_slist(const char *listname, const char *type);
+ int se_store_slist_callback(int majorID, int minorID,
+ void *serverargs, void *clientargs);
+ void se_read_conf(const char *word, char *cptr);
+diff --git a/include/net-snmp/library/snmp_parse_args.h b/include/net-snmp/library/snmp_parse_args.h
+index 384aff0..1ad63e0 100644
+--- a/include/net-snmp/library/snmp_parse_args.h
++++ b/include/net-snmp/library/snmp_parse_args.h
+@@ -1,8 +1,5 @@
+ #ifndef SNMP_PARSE_ARGS_H
+ #define SNMP_PARSE_ARGS_H
+-#ifdef __cplusplus
+-extern "C" {
+-#endif
+
+ /**
+ * @file snmp_parse_args.h
+@@ -11,6 +8,10 @@ extern "C" {
+ * line arguments
+ */
+
++#ifdef __cplusplus
++extern "C" {
++#endif
++
+ /** Don't enable any logging even if there is no -L argument */
+ #define NETSNMP_PARSE_ARGS_NOLOGGING 0x0001
+ /** Don't zero out sensitive arguments as they are not on the command line
+@@ -47,11 +48,12 @@ extern "C" {
+ * from it.
+ * @param argc Number of elements in argv
+ * @param argv string array of at least argc elements
++ * @param session
+ * @param localOpts Additional option characters to accept
+ * @param proc function pointer used to process any unhandled arguments
+ * @param flags flags directing how to handle the string
+ *
+- * @reval 0 (= #NETSNMP_PARSE_ARGS_SUCCESS) on success
++ * @retval 0 (= #NETSNMP_PARSE_ARGS_SUCCESS) on success
+ * @retval #NETSNMP_PARSE_ARGS_SUCCESS_EXIT when the application is expected
+ * to exit with zero exit code (e.g. '-V' option was found)
+ * @retval #NETSNMP_PARSE_ARGS_ERROR_USAGE when the function failed to parse
+diff --git a/include/net-snmp/library/system.h b/include/net-snmp/library/system.h
+index 9ae1067..5c58e4a 100644
+--- a/include/net-snmp/library/system.h
++++ b/include/net-snmp/library/system.h
+@@ -194,6 +194,11 @@ SOFTWARE.
+ NETSNMP_IMPORT
+ size_t strlcpy(char *, const char *, size_t);
+ #endif
++#ifndef HAVE_STRLCAT
++ NETSNMP_IMPORT
++ size_t strlcat(char * __restrict, const char * __restrict,
++ size_t);
++#endif
+
+ int netsnmp_os_prematch(const char *ospmname,
+ const char *ospmrelprefix);
+diff --git a/include/net-snmp/library/testing.h b/include/net-snmp/library/testing.h
+index aabe52f..ec6135a 100644
+--- a/include/net-snmp/library/testing.h
++++ b/include/net-snmp/library/testing.h
+@@ -7,10 +7,10 @@
+ static int __test_counter = 0;
+ static int __did_plan = 0;
+
+-#define OK(isok, description) { printf("%s %d - %s\n", ((isok) ? "ok" : "not ok"), ++__test_counter, description); }
++#define OK(isok, description) do { printf("%s %d - %s\n", ((isok) ? "ok" : "not ok"), ++__test_counter, description); } while (0)
+
+-#define OKF(isok, description) { printf("%s %d - \n", ((isok) ? "ok" : "not ok"), ++__test_counter); printf description; printf("\n"); }
++#define OKF(isok, description) do { printf("%s %d - ", ((isok) ? "ok" : "not ok"), ++__test_counter); printf description; printf("\n"); } while (0)
+
+-#define PLAN(number) { printf("1..%d\n", number); __did_plan = 1;}
++#define PLAN(number) do { printf("1..%d\n", number); __did_plan = 1; } while (0)
+
+ #endif /* NETSNMP_LIBRARY_TESTING_H */
+diff --git a/include/net-snmp/library/tools.h b/include/net-snmp/library/tools.h
+index d3514b7..66415da 100644
+--- a/include/net-snmp/library/tools.h
++++ b/include/net-snmp/library/tools.h
+@@ -113,7 +113,7 @@ extern "C" {
+ * Expands to string with value of the s.
+ * If s is macro, the resulting string is value of the macro.
+ * Example:
+- * #define TEST 1234
++ * \#define TEST 1234
+ * SNMP_MACRO_VAL_TO_STR(TEST) expands to "1234"
+ * SNMP_MACRO_VAL_TO_STR(TEST+1) expands to "1234+1"
+ */
+@@ -286,8 +286,8 @@ extern "C" {
+ NETSNMP_IMPORT
+ u_long uatime_hdiff(const_marker_t first, const_marker_t second); /* 1/100th sec */
+ NETSNMP_IMPORT
+- int atime_ready(const_marker_t pm, int deltaT);
+- int uatime_ready(const_marker_t pm, unsigned int deltaT);
++ int atime_ready(const_marker_t pm, int delta_ms);
++ int uatime_ready(const_marker_t pm, unsigned int delta_ms);
+
+ int marker_tticks(const_marker_t pm);
+ int timeval_tticks(const struct timeval *tv);
+diff --git a/include/net-snmp/net-snmp-config.h.in b/include/net-snmp/net-snmp-config.h.in
+index d9b9d15..d6ef3ab 100644
+--- a/include/net-snmp/net-snmp-config.h.in
++++ b/include/net-snmp/net-snmp-config.h.in
+@@ -96,6 +96,9 @@
+ /* Define to 1 if you have the <asm/types.h> header file. */
+ #undef HAVE_ASM_TYPES_H
+
++/* Define if using MY_INIT() causes a linker error */
++#undef HAVE_BROKEN_LIBMYSQLCLIENT
++
+ /* Define to 1 if you have the `cgetnext' function. */
+ #undef HAVE_CGETNEXT
+
+@@ -140,6 +143,12 @@
+ /* Define to 1 if you have the `eval_pv' function. */
+ #undef HAVE_EVAL_PV
+
++/* Define to 1 if you have the `EVP_MD_CTX_create' function. */
++#undef HAVE_EVP_MD_CTX_CREATE
++
++/* Define to 1 if you have the `EVP_MD_CTX_destroy' function. */
++#undef HAVE_EVP_MD_CTX_DESTROY
++
+ /* Define if you have EVP_sha224/256 in openssl */
+ #undef HAVE_EVP_SHA224
+
+@@ -152,12 +161,21 @@
+ /* Define to 1 if you have the <fcntl.h> header file. */
+ #undef HAVE_FCNTL_H
+
++/* Define to 1 if you have the `fgetc_unlocked' function. */
++#undef HAVE_FGETC_UNLOCKED
++
++/* Define to 1 if you have the `flockfile' function. */
++#undef HAVE_FLOCKFILE
++
+ /* Define to 1 if you have the `fork' function. */
+ #undef HAVE_FORK
+
+ /* Define to 1 if you have the <fstab.h> header file. */
+ #undef HAVE_FSTAB_H
+
++/* Define to 1 if you have the `funlockfile' function. */
++#undef HAVE_FUNLOCKFILE
++
+ /* Define to 1 if you have the `gai_strerror' function. */
+ #undef HAVE_GAI_STRERROR
+
+@@ -746,6 +764,9 @@
+ /* Define to 1 if you have the <string.h> header file. */
+ #undef HAVE_STRING_H
+
++/* Define to 1 if you have the `strlcat' function. */
++#undef HAVE_STRLCAT
++
+ /* Define to 1 if you have the `strlcpy' function. */
+ #undef HAVE_STRLCPY
+
+@@ -773,6 +794,9 @@
+ /* Define to 1 if `d_type' is a member of `struct dirent'. */
+ #undef HAVE_STRUCT_DIRENT_D_TYPE
+
++/* Define to 1 if `speed_hi' is a member of `struct ethtool_cmd'. */
++#undef HAVE_STRUCT_ETHTOOL_CMD_SPEED_HI
++
+ /* Define to 1 if `ifa_next' is a member of `struct ifaddr'. */
+ #undef HAVE_STRUCT_IFADDR_IFA_NEXT
+
+@@ -1166,6 +1190,9 @@
+ /* Define to 1 if you have the `times' function. */
+ #undef HAVE_TIMES
+
++/* Define if a timezone variable is declared in <sys/time.h> */
++#undef HAVE_TIMEZONE_VARIABLE
++
+ /* Define to 1 if you have the <ufs/ffs/fs.h> header file. */
+ #undef HAVE_UFS_FFS_FS_H
+
+diff --git a/include/net-snmp/session_api.h b/include/net-snmp/session_api.h
+index 9721fc4..88dbc41 100644
+--- a/include/net-snmp/session_api.h
++++ b/include/net-snmp/session_api.h
+@@ -147,12 +147,6 @@ extern "C" {
+ int snmp_select_info2(int *, netsnmp_large_fd_set *,
+ struct timeval *, int *);
+
+- /*
+- * snmp_sess_select_info_flags() and
+- * snmp_sess_select_info2_flags() is similar to
+- * snmp_sess_select_info() and snmp_sess_select_info2(), but
+- * accepts a list of flags to control aspects of its behavior.
+- */
+ #define NETSNMP_SELECT_NOFLAGS 0x00
+ #define NETSNMP_SELECT_NOALARMS 0x01
+ NETSNMP_IMPORT
+diff --git a/include/net-snmp/system/netbsd.h b/include/net-snmp/system/netbsd.h
+index c67260d..1f22a44 100644
+--- a/include/net-snmp/system/netbsd.h
++++ b/include/net-snmp/system/netbsd.h
+@@ -34,8 +34,36 @@
+
+ #define UDP_ADDRESSES_IN_HOST_ORDER 1
+
++#ifdef netbsdelf6
++#define netbsd6
++#define netbsdelf5
++#endif
++#ifdef netbsdelf5
++#define netbsd5
++#define netbsdelf4
++#endif
++#ifdef netbsdelf4
++#define netbsd4
++#define netbsdelf3
++#endif
++#ifdef netbsdelf3
++#define netbsd3
++#endif
++
++#if defined(netbsd6) && !defined(netbsd5)
++#define netbsd5 netbsd5
++#endif
++#if defined(netbsd5) && !defined(netbsd4)
++#define netbsd4 netbsd4
++#endif
++#if defined(netbsd4) && !defined(netbsd3)
++#define netbsd3 netbsd3
++#endif
++#if defined(netbsd3) && !defined(netbsd2)
++#define netbsd2 netbsd2
++#endif
+ #ifndef netbsd1
+-# define netbsd1 netbsd1
++#define netbsd1 netbsd1
+ #endif
+
+ #if __NetBSD_Version__ >= 499005800
+diff --git a/local/mib2c.container.conf b/local/mib2c.container.conf
+index c051b4c..e76621f 100644
+--- a/local/mib2c.container.conf
++++ b/local/mib2c.container.conf
+@@ -174,6 +174,7 @@ initialize_table_$i(void)
+ */
+ if (SNMPERR_SUCCESS != netsnmp_register_table(reg, table_info)) {
+ snmp_log(LOG_ERR,"error registering table handler for $i\n");
++ reg = NULL; /* it was freed inside netsnmp_register_table */
+ goto bail;
+ }
+
+diff --git a/local/mib2c.notify.conf b/local/mib2c.notify.conf
+index a8ee7e3..77f3330 100644
+--- a/local/mib2c.notify.conf
++++ b/local/mib2c.notify.conf
+@@ -30,7 +30,7 @@ int send_${i}_trap(void);
+ #include <net-snmp/agent/net-snmp-agent-includes.h>
+ #include "${name}.h"
+
+-extern const oid snmptrap_oid;
++extern const oid snmptrap_oid[];
+ extern const size_t snmptrap_oid_len;
+
+ @foreach $i notifications@
+diff --git a/local/mib2c.table_data.conf b/local/mib2c.table_data.conf
+index d263914..2cc665c 100644
+--- a/local/mib2c.table_data.conf
++++ b/local/mib2c.table_data.conf
+@@ -348,6 +348,9 @@ ${i}_handler(
+ */
+ case MODE_GET:
+ for (request=requests; request; request=request->next) {
++ if (request->processed)
++ continue;
++
+ table_entry = (struct ${i}_entry *)
+ netsnmp_tdata_extract_entry(request);
+ table_info = netsnmp_extract_table_info( request);
+@@ -386,6 +389,9 @@ ${i}_handler(
+ */
+ case MODE_SET_RESERVE1:
+ for (request=requests; request; request=request->next) {
++ if (request->processed)
++ continue;
++
+ table_entry = (struct ${i}_entry *)
+ netsnmp_tdata_extract_entry(request);
+ table_info = netsnmp_extract_table_info( request);
+@@ -425,6 +431,9 @@ ${i}_handler(
+ case MODE_SET_RESERVE2:
+ @if $i.creatable@
+ for (request=requests; request; request=request->next) {
++ if (request->processed)
++ continue;
++
+ table_row = netsnmp_tdata_extract_row( request);
+ table_data = netsnmp_tdata_extract_table(request);
+ table_info = netsnmp_extract_table_info( request);
+@@ -492,6 +501,9 @@ ${i}_handler(
+ case MODE_SET_FREE:
+ @if $i.creatable@
+ for (request=requests; request; request=request->next) {
++ if (request->processed)
++ continue;
++
+ table_entry = (struct ${i}_entry *)
+ netsnmp_tdata_extract_entry(request);
+ table_row = netsnmp_tdata_extract_row( request);
+@@ -530,6 +542,9 @@ ${i}_handler(
+
+ case MODE_SET_ACTION:
+ for (request=requests; request; request=request->next) {
++ if (request->processed)
++ continue;
++
+ table_entry = (struct ${i}_entry *)
+ netsnmp_tdata_extract_entry(request);
+ table_info = netsnmp_extract_table_info( request);
+@@ -591,6 +606,9 @@ ${i}_handler(
+
+ case MODE_SET_UNDO:
+ for (request=requests; request; request=request->next) {
++ if (request->processed)
++ continue;
++
+ table_entry = (struct ${i}_entry *)
+ netsnmp_tdata_extract_entry(request);
+ table_row = netsnmp_tdata_extract_row( request);
+@@ -667,6 +685,9 @@ ${i}_handler(
+ case MODE_SET_COMMIT:
+ @if $i.creatable@
+ for (request=requests; request; request=request->next) {
++ if (request->processed)
++ continue;
++
+ table_entry = (struct ${i}_entry *)
+ netsnmp_tdata_extract_entry(request);
+ @if $i.rowstatus@
+diff --git a/local/pass_persisttest b/local/pass_persisttest
+index 4f37c11..f4045cc 100755
+--- a/local/pass_persisttest
++++ b/local/pass_persisttest
+@@ -5,17 +5,23 @@
+ # put the following in your snmpd.conf file to call this script:
+ #
+ # Unix systems and Cygwin:
+-# pass_persist .1.3.6.1.4.1.2021.255 /path/to/pass_persisttest
++# pass_persist .1.3.6.1.4.1.8072.2.255 /path/to/pass_persisttest
+ # Windows systems except Cygwin:
+-# pass_persist .1.3.6.1.4.1.2021.255 perl /path/to/pass_persisttest
++# pass_persist .1.3.6.1.4.1.8072.2.255 perl /path/to/pass_persisttest
+
+ # Forces a buffer flush after every print
+ $|=1;
+
++# Save my PID, to help kill this instance.
++$PIDFILE=$ENV{'PASS_PERSIST_PIDFILE'} || "/tmp/pass_persist.pid";
++open(PIDFILE, ">$PIDFILE");
++print PIDFILE "$$\n";
++close(PIDFILE);
++
+ use strict;
+
+ my $counter = 0;
+-my $place = ".1.3.6.1.4.1.2021.255";
++my $place = ".1.3.6.1.4.1.8072.2.255";
+
+ while (<>){
+ if (m!^PING!){
+@@ -30,21 +36,33 @@ while (<>){
+ chomp($req);
+
+ if ( $cmd eq "getnext" ) {
+- if ($req eq $place) {
+- $ret = "$place.1";
+- } elsif ($req eq "$place.1") {
+- $ret = "$place.2.1";
+- } elsif ($req eq "$place.2.1") {
+- $ret = "$place.2.2";
+- } elsif ($req eq "$place.2.2") {
+- $ret = "$place.3";
+- } elsif ($req eq "$place.3") {
+- $ret = "$place.4";
+- } elsif ($req eq "$place.4") {
+- $ret = "$place.5";
+- } elsif ($req eq "$place.5") {
+- $ret = "$place.6";
+- } else {
++ if (($req eq "$place") ||
++ ($req eq "$place.0") ||
++ ($req =~ m/$place\.0\..*/) ||
++ ($req eq "$place.1")) { $ret = "$place.1.0";} # netSnmpPassString.0
++ elsif (($req =~ m/$place\.1\..*/) ||
++ ($req eq "$place.2") ||
++ ($req eq "$place.2.0") ||
++ ($req =~ m/$place\.2\.0\..*/) ||
++ ($req eq "$place.2.1") ||
++ ($req eq "$place.2.1.0") ||
++ ($req =~ m/$place\.2\.1\.0\..*/) ||
++ ($req eq "$place.2.1.1") ||
++ ($req =~ m/$place\.2\.1\.1\..*/) ||
++ ($req eq "$place.2.1.2") ||
++ ($req eq "$place.2.1.2.0")) { $ret = "$place.2.1.2.1";} # netSnmpPassInteger.1
++ elsif (($req =~ m/$place\.2\.1\.2\..*/) ||
++ ($req eq "$place.2.1.3") ||
++ ($req eq "$place.2.1.3.0")) { $ret = "$place.2.1.3.1";} # netSnmpPassOID.1
++ elsif (($req =~ m/$place\.2\..*/) ||
++ ($req eq "$place.3")) { $ret = "$place.3.0";} # netSnmpPassTimeTicks.0
++ elsif (($req =~ m/$place\.3\..*/) ||
++ ($req eq "$place.4")) { $ret = "$place.4.0";} # netSnmpPassIpAddress.0
++ elsif (($req =~ m/$place\.4\..*/) ||
++ ($req eq "$place.5")) { $ret = "$place.5.0";} # netSnmpPassCounter.0
++ elsif (($req =~ m/$place\.5\..*/) ||
++ ($req eq "$place.6")) { $ret = "$place.6.0";} # netSnmpPassGauge.0
++ else {
+ print "NONE\n";
+ next;
+ }
+@@ -59,20 +77,20 @@ while (<>){
+
+ print "$ret\n";
+
+- if ($ret eq "$place.1") {
+- print "string\nlife the universe and everything\n";
+- } elsif ($ret eq "$place.2.1") {
+- print "integer\n423\n";
+- } elsif ($ret eq "$place.2.2") {
+- print "objectid\n.1.3.6.1.4.42.42.42\n";
+- } elsif ($ret eq "$place.3") {
++ if ($ret eq "$place.1.0") {
++ print "string\nLife, the Universe, and Everything\n";
++ } elsif ($ret eq "$place.2.1.2.1") {
++ print "integer\n42\n";
++ } elsif ($ret eq "$place.2.1.3.1") {
++ print "objectid\n$place.99\n";
++ } elsif ($ret eq "$place.3.0") {
+ print "timeticks\n363136200\n";
+- } elsif ($ret eq "$place.4") {
++ } elsif ($ret eq "$place.4.0") {
+ print "ipaddress\n127.0.0.1\n";
+- } elsif ($ret eq "$place.5") {
++ } elsif ($ret eq "$place.5.0") {
+ $counter++;
+ print "counter\n$counter\n";
+- } elsif ($ret eq "$place.6") {
++ } elsif ($ret eq "$place.6.0") {
+ print "gauge\n42\n";
+ } else {
+ print "string\nack... $ret $req\n";
+diff --git a/local/passtest b/local/passtest
+index dc5735c..40209c9 100755
+--- a/local/passtest
++++ b/local/passtest
+@@ -1,7 +1,5 @@
+ #!/bin/sh -f
+
+-PATH=$path:/bin:/usr/bin:/usr/ucb
+-
+ PLACE=".1.3.6.1.4.1.8072.2.255" # NET-SNMP-PASS-MIB::netSnmpPassExamples
+ REQ="$2" # Requested OID
+
+@@ -20,34 +18,34 @@ fi
+ #
+ if [ "$1" = "-n" ]; then
+ case "$REQ" in
+- $PLACE|
+- $PLACE.0|
+- $PLACE.0.*|
++ $PLACE| \
++ $PLACE.0| \
++ $PLACE.0.*| \
+ $PLACE.1) RET=$PLACE.1.0 ;; # netSnmpPassString.0
+
+- $PLACE.1.*|
+- $PLACE.2|
+- $PLACE.2.0|
+- $PLACE.2.0.*|
+- $PLACE.2.1|
+- $PLACE.2.1.0|
+- $PLACE.2.1.0.*|
+- $PLACE.2.1.1|
+- $PLACE.2.1.1.*|
+- $PLACE.2.1.2|
++ $PLACE.1.*| \
++ $PLACE.2| \
++ $PLACE.2.0| \
++ $PLACE.2.0.*| \
++ $PLACE.2.1| \
++ $PLACE.2.1.0| \
++ $PLACE.2.1.0.*| \
++ $PLACE.2.1.1| \
++ $PLACE.2.1.1.*| \
++ $PLACE.2.1.2| \
+ $PLACE.2.1.2.0) RET=$PLACE.2.1.2.1 ;; # netSnmpPassInteger.1
+
+- $PLACE.2.1.2.*|
+- $PLACE.2.1.3|
++ $PLACE.2.1.2.*| \
++ $PLACE.2.1.3| \
+ $PLACE.2.1.3.0) RET=$PLACE.2.1.3.1 ;; # netSnmpPassOID.1
+
+- $PLACE.2.*|
++ $PLACE.2.*| \
+ $PLACE.3) RET=$PLACE.3.0 ;; # netSnmpPassTimeTicks.0
+- $PLACE.3.*|
++ $PLACE.3.*| \
+ $PLACE.4) RET=$PLACE.4.0 ;; # netSnmpPassIpAddress.0
+- $PLACE.4.*|
++ $PLACE.4.*| \
+ $PLACE.5) RET=$PLACE.5.0 ;; # netSnmpPassCounter.0
+- $PLACE.5.*|
++ $PLACE.5.*| \
+ $PLACE.6) RET=$PLACE.6.0 ;; # netSnmpPassGauge.0
+
+ *) exit 0 ;;
+@@ -57,12 +55,12 @@ else
+ # GET requests - check for valid instance
+ #
+ case "$REQ" in
+- $PLACE.1.0|
+- $PLACE.2.1.2.1|
+- $PLACE.2.1.3.1|
+- $PLACE.3.0|
+- $PLACE.4.0|
+- $PLACE.5.0|
++ $PLACE.1.0| \
++ $PLACE.2.1.2.1| \
++ $PLACE.2.1.3.1| \
++ $PLACE.3.0| \
++ $PLACE.4.0| \
++ $PLACE.5.0| \
+ $PLACE.6.0) RET=$REQ ;;
+ *) exit 0 ;;
+ esac
+diff --git a/local/passtest.pl b/local/passtest.pl
+index 049cf45..c87fe18 100755
+--- a/local/passtest.pl
++++ b/local/passtest.pl
+@@ -66,7 +66,7 @@ else {
+ print "$ret\n";
+ if ($ret eq "$place.1.0") { print "string\nLife, the Universe, and Everything\n"; exit 0;}
+ elsif ($ret eq "$place.2.1.2.1") { print "integer\n42\n"; exit 0;}
+-elsif ($ret eq "$place.2.1.3.1") { print "objectid\n.1.3.6.1.4.42.42.42\n"; exit 0;}
++elsif ($ret eq "$place.2.1.3.1") { print "objectid\n$place.99\n"; exit 0;}
+ elsif ($ret eq "$place.3.0") { print "timeticks\n363136200\n"; exit 0;}
+ elsif ($ret eq "$place.4.0") { print "ipaddress\n127.0.0.1\n"; exit 0;}
+ elsif ($ret eq "$place.5.0") { print "counter\n42\n"; exit 0;}
+diff --git a/local/snmp-bridge-mib b/local/snmp-bridge-mib
+index a4c2c80..4a9415e 100644
+--- a/local/snmp-bridge-mib
++++ b/local/snmp-bridge-mib
+@@ -1004,7 +1004,7 @@ sub readindexes()
+ next if $if eq "..";
+
+ my $port=hex(readfile($brifdir.$if."/port_no", 0));
+- my $index=readfile($netdir.$if."/ifindex", STP_PROP_HEX);
++ my $index=readfile($netdir.$if."/ifindex", 0);
+
+ $indexes{$bridge}{$port}=$index;
+ $interfaces{$bridge}{$port}=$if;
+@@ -1063,17 +1063,16 @@ sub tracevlan{
+ my $pif=$1;
+ $brifdir=$netdir.$pif."/brport/bridge/brif/";
+ $port=hex(readfile($brifdir.$pif."/port_no", 0));
+- $index=readfile($netdir.$pif."/ifindex", STP_PROP_HEX);
++ $index=readfile($netdir.$pif."/ifindex", 0);
+ #$indexes{$bridge}{$port}=$index;
+ #$interfaces{$bridge}{$port}=$if;
+ $tagged{$vlan}{$port}=1;
+ }else{
+- my $brid=readfile($netdir.$if."/brport/bridge/ifindex",
+- STP_PROP_HEX);
++ my $brid=readfile($netdir.$if."/brport/bridge/ifindex", 0);
+ $brifdir=$netdir.$if."/brport/bridge/brif/";
+ $port=hex(readfile($brifdir.$if."/port_no", 0));
+ $port=$brid*1000+$port; #create a unique port number
+- $index=readfile($netdir.$if."/ifindex", STP_PROP_HEX);
++ $index=readfile($netdir.$if."/ifindex", 0);
+ $indexes{$bridge}{$port}=$index;
+ $interfaces{$bridge}{$port}=$if;
+ $tagged{$vlan}{$port}=0;
+@@ -1083,8 +1082,7 @@ sub tracevlan{
+ }
+ close(DIR);
+
+- my $brid=readfile($netdir.$interface."/brport/bridge/ifindex",
+- STP_PROP_HEX);
++ my $brid=readfile($netdir.$interface."/brport/bridge/ifindex", 0);
+ my $fdb=$netdir.$interface."/brport/bridge/brforward";
+
+ my $vbridge=$bridge."_vlan".$vlan;
+diff --git a/man/Makefile.in b/man/Makefile.in
+index bfe8279..5627cc0 100644
+--- a/man/Makefile.in
++++ b/man/Makefile.in
+@@ -26,6 +26,8 @@ MAN1G = $(AGENTXTRAP) snmpbulkget.1 snmpcmd.1 snmpget.1 snmpset.1 snmpwalk.1 \
+ net-snmp-config.1 mib2c-update.1 tkmib.1 traptoemail.1 \
+ net-snmp-create-v3-user.1
+
++# If MAN3 is populated again, then remember to re-enable the corresponding
++# action line within the 'maninstall' target
+ MAN3 =
+ MAN3_API = netsnmp_mib_api.3 netsnmp_config_api.3 snmp_alarm.3 \
+ netsnmp_session_api.3 netsnmp_sess_api.3 netsnmp_trap_api.3 netsnmp_varbind_api.3 netsnmp_pdu_api.3
+@@ -241,7 +243,7 @@ maninstall: maninstalldirs $(MAN1) $(MAN1G) $(MAN3) $(MAN5G) $(MAN8) $(MANALIAS
+ @for i in $(MAN1) ; do $(INSTALL_DATA) $(srcdir)/$$i $(INSTALL_PREFIX)$(man1dir) ; echo "install: installed $$i in $(INSTALL_PREFIX)$(man1dir)" ; done
+ @$(INSTALL_DATA) $(MAN1G) $(INSTALL_PREFIX)$(man1dir)
+ @for i in $(MAN1G) ; do echo "install: installed $$i in $(INSTALL_PREFIX)$(man1dir)" ; done
+- @for i in $(MAN3) ; do $(INSTALL_DATA) $(srcdir)/$$i $(INSTALL_PREFIX)$(man3dir) ; echo "install: installed $$i in $(INSTALL_PREFIX)$(man3dir)" ; done
++ #EMPTY LIST#@for i in $(MAN3) ; do $(INSTALL_DATA) $(srcdir)/$$i $(INSTALL_PREFIX)$(man3dir) ; echo "install: installed $$i in $(INSTALL_PREFIX)$(man3dir)" ; done
+ @$(INSTALL_DATA) $(MAN3G) $(INSTALL_PREFIX)$(man3dir)
+ @for i in $(MAN3G) ; do echo "install: installed $$i in $(INSTALL_PREFIX)$(man3dir)" ; done
+ @$(INSTALL_DATA) $(MANALIASES) $(INSTALL_PREFIX)$(man3dir)
+diff --git a/mibs/IANA-RTPROTO-MIB.txt b/mibs/IANA-RTPROTO-MIB.txt
+index 6f04143..f50992e 100644
+--- a/mibs/IANA-RTPROTO-MIB.txt
++++ b/mibs/IANA-RTPROTO-MIB.txt
+@@ -5,7 +5,7 @@ IMPORTS
+ TEXTUAL-CONVENTION FROM SNMPv2-TC;
+
+ ianaRtProtoMIB MODULE-IDENTITY
+- LAST-UPDATED "200009260000Z" -- September 26, 2000
++ LAST-UPDATED "201107220000Z" -- July 22, 2011
+ ORGANIZATION "IANA"
+ CONTACT-INFO
+ " Internet Assigned Numbers Authority
+@@ -28,6 +28,9 @@ ianaRtProtoMIB MODULE-IDENTITY
+ will be selected by the IESG Area Director(s) of the Routing
+ Area."
+
++ REVISION "201107220000Z" -- July 22, 2011
++ DESCRIPTION "Added rpl(18) ."
++
+ REVISION "200009260000Z" -- September 26, 2000
+ DESCRIPTION "Original version, published in coordination
+ with RFC 2932."
+@@ -60,7 +63,8 @@ IANAipRouteProtocol ::= TEXTUAL-CONVENTION
+ bgp (14), -- Border Gateway Protocol
+ idpr (15), -- InterDomain Policy Routing
+ ciscoEigrp (16), -- Cisco EIGRP
+- dvmrp (17) -- DVMRP
++ dvmrp (17), -- DVMRP
++ rpl (18) -- RPL [RFC-ietf-roll-rpl-19]
+ }
+
+ IANAipMRouteProtocol ::= TEXTUAL-CONVENTION
+diff --git a/mibs/IANAifType-MIB.txt b/mibs/IANAifType-MIB.txt
+index 856156a..896adc8 100644
+--- a/mibs/IANAifType-MIB.txt
++++ b/mibs/IANAifType-MIB.txt
+@@ -5,7 +5,7 @@
+ TEXTUAL-CONVENTION FROM SNMPv2-TC;
+
+ ianaifType MODULE-IDENTITY
+- LAST-UPDATED "201002110000Z" -- February 11, 2010
++ LAST-UPDATED "201110260000Z" -- October 26, 2011
+ ORGANIZATION "IANA"
+ CONTACT-INFO " Internet Assigned Numbers Authority
+
+@@ -19,6 +19,24 @@
+ Convention, and thus the enumerated values of
+ the ifType object defined in MIB-II's ifTable."
+
++ REVISION "201110260000Z" -- October 26, 2011
++ DESCRIPTION "Registration of new IANAifType 262."
++
++ REVISION "201109070000Z" -- September 7, 2011
++ DESCRIPTION "Registration of new IANAifTypes 260 and 261."
++
++ REVISION "201107220000Z" -- July 22, 2011
++ DESCRIPTION "Registration of new IANAifType 259."
++
++ REVISION "201106030000Z" -- June 03, 2011
++ DESCRIPTION "Registration of new IANAifType 258."
++
++ REVISION "201009210000Z" -- September 21, 2010
++ DESCRIPTION "Registration of new IANAifTypes 256 and 257."
++
++ REVISION "201007210000Z" -- July 21, 2010
++ DESCRIPTION "Registration of new IANAifType 255."
++
+ REVISION "201002110000Z" -- February 11, 2010
+ DESCRIPTION "Registration of new IANAifType 254."
+
+@@ -334,7 +352,7 @@
+ ieee80212(55), -- 100BaseVG
+ fibreChannel(56), -- Fibre Channel
+ hippiInterface(57), -- HIPPI interfaces
+- frameRelayInterconnect(58), -- Obsolete use either
++ frameRelayInterconnect(58), -- Obsolete, use either
+ -- frameRelay(32) or
+ -- frameRelayService(44).
+ aflane8023(59), -- ATM Emulated LAN for 802.3
+@@ -541,7 +559,15 @@
+ vdsl2 (251), -- Very high speed digital subscriber line Version 2 (as per ITU-T Recommendation G.993.2)
+ capwapDot11Profile (252), -- WLAN Profile Interface
+ capwapDot11Bss (253), -- WLAN BSS Interface
+- capwapWtpVirtualRadio (254) -- WTP Virtual Radio Interface
++ capwapWtpVirtualRadio (254), -- WTP Virtual Radio Interface
++ bits (255), -- bitsport
++ docsCableUpstreamRfPort (256), -- DOCSIS CATV Upstream RF Port
++ cableDownstreamRfPort (257), -- CATV downstream RF port
++ vmwareVirtualNic (258), -- VMware Virtual Network Interface
++ ieee802154 (259), -- IEEE 802.15.4 WPAN interface
++ otnOdu (260), -- OTN Optical Data Unit
++ otnOtu (261), -- OTN Optical channel Transport Unit
++ ifVfiType (262) -- VPLS Forwarding Instance Interface Type
+ }
+
+ IANAtunnelType ::= TEXTUAL-CONVENTION
+diff --git a/mibs/rfclist b/mibs/rfclist
+index 7f84150..35f301e 100644
+--- a/mibs/rfclist
++++ b/mibs/rfclist
+@@ -1,4 +1,4 @@
+-# updated 2011-03-14
++# updated 2011-11-16
+ 1155 RFC1155-SMI
+ 1213 RFC1213-MIB
+ 1227 SMUX-MIB
+@@ -254,6 +254,9 @@
+ 5833 CAPWAP-BASE-MIB
+ 5834 CAPWAP-DOT11-MIB
+ 5907 NTPv4-MIB
+-5953 SNMP-TLS-TM-MIB
+ 6065 SNMP-VACM-AAA-MIB
+ 6173 IFCP-MGMT-MIB
++6240 PW-CEP-STD-MIB
++6340 FLOAT-TC-MIB
++6353 SNMP-TLS-TM-MIB
++6445 MPLS-FRR-GENERAL-STD-MIB:MPLS-FRR-ONE2ONE-STD-MIB:MPLS-FRR-FACILITY-STD-MIB
+diff --git a/net-snmp-config.in b/net-snmp-config.in
+index 303cdda..3ba60e3 100644
+--- a/net-snmp-config.in
++++ b/net-snmp-config.in
+@@ -194,7 +194,7 @@ else
+ echo $NSC_LIBDIR $NSC_BASE_SNMP_LIBS
+ ;;
+ --external-libs)
+- echo $NSC_LDFLAGS $NSC_LNETSNMPLIBS $NSC_LIBS
++ echo $NSC_LDFLAGS $NSC_LNETSNMPLIBS $NSC_LIBS @PERLLDOPTS_FOR_APPS@
+ ;;
+ #################################################### agent lib
+ --base-agent-libs)
+diff --git a/perl/ASN/ASN.pm b/perl/ASN/ASN.pm
+index 3961bd5..4195573 100644
+--- a/perl/ASN/ASN.pm
++++ b/perl/ASN/ASN.pm
+@@ -77,7 +77,7 @@ sub AUTOLOAD {
+ ($constname = $AUTOLOAD) =~ s/.*:://;
+ croak "& not defined" if $constname eq 'constant';
+ my $val;
+- ($!, $val) = constant($constname, @_ ? $_[0] : 0);
++ ($!, $val) = constant($constname);
+ if ($! != 0) {
+ if ($! =~ /Invalid/ || $!{EINVAL}) {
+ $AutoLoader::AUTOLOAD = $AUTOLOAD;
+diff --git a/perl/ASN/ASN.xs b/perl/ASN/ASN.xs
+index bbfa69b..e3f6181 100644
+--- a/perl/ASN/ASN.xs
++++ b/perl/ASN/ASN.xs
+@@ -78,9 +78,11 @@ static int constant_ASN_U(double *value, const char *name, const int len)
+ case '\0':
+ TEST_CONSTANT(value, name, ASN_UNSIGNED);
+ break;
++#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
+ case '6':
+ TEST_CONSTANT(value, name, ASN_UNSIGNED64);
+ break;
++#endif
+ }
+ return EINVAL;
+ }
+@@ -91,9 +93,11 @@ static int constant_ASN_IN(double *value, const char *name, const int len)
+ case '\0':
+ TEST_CONSTANT(value, name, ASN_INTEGER);
+ break;
++#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
+ case '6':
+ TEST_CONSTANT(value, name, ASN_INTEGER64);
+ break;
++#endif
+ }
+ return EINVAL;
+ }
+@@ -123,12 +127,14 @@ static int constant(double *value, const char *const name, const int len)
+ return constant_ASN_B(value, name, len);
+ case 'C':
+ return constant_ASN_C(value, name, len);
++#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
+ case 'D':
+ TEST_CONSTANT(value, name, ASN_DOUBLE);
+ break;
+ case 'F':
+ TEST_CONSTANT(value, name, ASN_FLOAT);
+ break;
++#endif
+ case 'G':
+ TEST_CONSTANT(value, name, ASN_GAUGE);
+ break;
+@@ -155,13 +161,12 @@ MODULE = NetSNMP::ASN PACKAGE = NetSNMP::ASN
+
+
+ void
+-constant(sv,arg)
++constant(sv)
+ PREINIT:
+ STRLEN len;
+ INPUT:
+ SV * sv
+ char * s = SvPV(sv, len);
+- int arg
+ INIT:
+ int status;
+ double value;
+diff --git a/perl/OID/OID.pm b/perl/OID/OID.pm
+index 3ab12aa..a9d9369 100644
+--- a/perl/OID/OID.pm
++++ b/perl/OID/OID.pm
+@@ -153,7 +153,7 @@ sub AUTOLOAD {
+ ($constname = $AUTOLOAD) =~ s/.*:://;
+ croak "& not defined" if $constname eq 'constant';
+ my $val;
+- ($!, $val) = constant($constname, @_ ? $_[0] : 0);
++ ($!, $val) = constant($constname);
+ if ($! != 0) {
+ if ($! =~ /Invalid/ || $!{EINVAL}) {
+ $AutoLoader::AUTOLOAD = $AUTOLOAD;
+diff --git a/perl/OID/OID.xs b/perl/OID/OID.xs
+index ff3693e..10485f9 100644
+--- a/perl/OID/OID.xs
++++ b/perl/OID/OID.xs
+@@ -125,7 +125,7 @@ int flag;
+ break;
+
+ case ASN_BIT_STR:
+- snprint_bitstring(buf, sizeof(buf), var, NULL, NULL, NULL);
++ snprint_bitstring(buf, buf_len, var, NULL, NULL, NULL);
+ len = strlen(buf);
+ break;
+
+@@ -173,13 +173,12 @@ nso_newptr(initstring)
+ RETVAL
+
+ void
+-constant(sv,arg)
++constant(sv)
+ PREINIT:
+ STRLEN len;
+ INPUT:
+ SV * sv
+ char * s = SvPV(sv, len);
+- int arg
+ INIT:
+ int status;
+ double value;
+diff --git a/perl/SNMP/SNMP.pm b/perl/SNMP/SNMP.pm
+index d1b39c3..a7f6faa 100644
+--- a/perl/SNMP/SNMP.pm
++++ b/perl/SNMP/SNMP.pm
+@@ -135,6 +135,12 @@ $replace_newer = 0; # determine whether or not to tell the parser to replace
+ # older MIB modules with newer ones when loading MIBs.
+ # WARNING: This can cause an incorrect hierarchy.
+
++sub register_debug_tokens {
++ my $tokens = shift;
++
++ SNMP::_register_debug_tokens($tokens);
++}
++
+ sub getenv {
+ my $name = shift;
+
+@@ -161,10 +167,10 @@ sub setMib {
+ }
+
+ sub initMib {
+-# eqivalent to calling the snmp library init_mib if Mib is NULL
++# equivalent to calling the snmp library init_mib if Mib is NULL
+ # if Mib is already loaded this function does nothing
+-# Pass a zero valued argument to get minimal mib tree initialzation
+-# If non zero agrgument or no argument then full mib initialization
++# Pass a zero valued argument to get minimal mib tree initialization
++# If non zero argument or no argument then full mib initialization
+
+ SNMP::init_snmp("perl");
+ return;
+@@ -1529,7 +1535,7 @@ init_snmp properly, which means it will read configuration files and
+ use those defaults where appropriate automatically parse MIB files,
+ etc. This will likely affect your perl applications if you have, for
+ instance, default values set up in your snmp.conf file (as the perl
+-module will now make use of those defaults). The docmuentation,
++module will now make use of those defaults). The documentation,
+ however, has sadly not been updated yet (aside from this note), nor is
+ the read_config default usage implementation fully complete.
+
+@@ -1540,7 +1546,7 @@ aspects of a connection between the management application and the
+ managed agent. Internally the class is implemented as a blessed hash
+ reference. This class supplies 'get', 'getnext', 'set', 'fget', and
+ 'fgetnext' method calls. The methods take a variety of input argument
+-formats and support both syncronous and asyncronous operation through
++formats and support both synchronous and asynchronous operation through
+ a polymorphic API (i.e., method behaviour varies dependent on args
+ passed - see below).
+
+@@ -1835,7 +1841,7 @@ do SNMP GET, multiple <vars> formats accepted.
+ for syncronous operation <vars> will be updated
+ with value(s) and type(s) and will also return
+ retrieved value(s). If <callback> supplied method
+-will operate asyncronously
++will operate asynchronously
+
+ =item $sess->fget(E<lt>varsE<gt> [,E<lt>callbackE<gt>])
+
+@@ -1852,7 +1858,7 @@ and <type>
+
+ Note: simple string <vars>,(e.g., 'sysDescr.0')
+ form is not updated. If <callback> supplied method
+-will operate asyncronously
++will operate asynchronously
+
+ =item $sess->fgetnext(E<lt>varsE<gt> [,E<lt>callbackE<gt>])
+
+@@ -1868,7 +1874,7 @@ format (i.e., well known format) to ensure unambiguous
+ translation to SNMP MIB data value (see discussion of
+ canonical value format <vars> description section),
+ returns snmp_errno. If <callback> supplied method
+-will operate asyncronously
++will operate asynchronously
+
+ =item $sess->getbulk(E<lt>non-repeatersE<gt>, E<lt>max-repeatersE<gt>, E<lt>varsE<gt>)
+
+@@ -1985,7 +1991,7 @@ collect all the columns defined in the MIB table.
+ Specifies a GETBULK repeat I<COUNT>. IE, it will request this many
+ varbinds back per column when using the GETBULK operation. Shortening
+ this will mean smaller packets which may help going through some
+-systems. By default, this value is calculated and attepmts to guess
++systems. By default, this value is calculated and attempts to guess
+ at what will fit all the results into 1000 bytes. This calculation is
+ fairly safe, hopefully, but you can either raise or lower the number
+ using this option if desired. In lossy networks, you want to make
+@@ -1997,7 +2003,7 @@ one way to help that.
+ Force the use of GETNEXT rather than GETBULK. (always true for
+ SNMPv1, as it doesn't have GETBULK anyway). Some agents are great
+ implementers of GETBULK and this allows you to force the use of
+-GETNEXT oprations instead.
++GETNEXT operations instead.
+
+ =item callback => \&subroutine
+
+@@ -2023,7 +2029,7 @@ versions prior to 5.04 and 5.04 and up, the following should work:
+ $no_mainloop = 1;
+ }
+
+-Deciding on whether to use SNMP::MainLoop is left as an excersize to
++Deciding on whether to use SNMP::MainLoop is left as an exercise to
+ the reader since it depends on whether your code uses other callbacks
+ as well.
+
+@@ -2238,9 +2244,9 @@ will be undef.
+ to be used with async SNMP::Session
+ calls. MainLoop must be called after initial async calls
+ so return packets from the agent will not be processed.
+-If no args suplied this function enters an infinite loop
++If no args supplied this function enters an infinite loop
+ so program must be exited in a callback or externally
+-interupted. If <timeout(sic)
++interrupted. If <timeout(sic)
+
+ =item &SNMP::finish()
+
+@@ -2322,7 +2328,7 @@ initialization
+
+ =item $SNMP::debugging
+
+-default '0', controlls debugging output level
++default '0', controls debugging output level
+ within SNMP module and libsnmp
+
+ =over
+@@ -2346,6 +2352,12 @@ level 2 plus snmp_set_dump_packet(1)
+ default '0', set [non-]zero to independently set
+ snmp_set_dump_packet()
+
++=item SNMP::register_debug_tokens()
++
++Allows to register one or more debug tokens, just like the -D option of snmpd.
++Each debug token enables a group of debug statements. An example:
++SNMP::register_debug_tokens("tdomain,netsnmp_unix");
++
+ =back
+
+ =head1 %SNMP::MIB
+@@ -2459,7 +2471,7 @@ returns true if the last object in the INDEX is IMPLIED
+ =item &SNMP::setMib(<file>)
+
+ allows dynamic parsing of the mib and explicit
+-specification of mib file independent of enviroment
++specification of mib file independent of environment
+ variables. called with no args acts like initMib,
+ loading MIBs indicated by environment variables (see
+ Net-SNMP mib_api docs). passing non-zero second arg
+diff --git a/perl/SNMP/SNMP.xs b/perl/SNMP/SNMP.xs
+index a0cfe69..ff84919 100644
+--- a/perl/SNMP/SNMP.xs
++++ b/perl/SNMP/SNMP.xs
+@@ -1,4 +1,4 @@
+-/* -*- C -*-
++/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*-
+ SNMP.xs -- Perl 5 interface to the Net-SNMP toolkit
+
+ written by G. S. Marzot (marz@users.sourceforge.net)
+@@ -221,7 +221,15 @@ __snprint_oid(const oid *objid, size_t objidlen) {
+ #else /* DEBUGGING */
+ #define DBDCL(x)
+ #define DBOUT
+-#define DBPRT(severity, otherargs) /* Ignore */
++/* Do nothing but in such a way that the compiler sees "otherargs". */
++#define DBPRT(severity, otherargs) \
++ do { if (0) printf otherargs; } while(0)
++
++static char *
++__snprint_oid(const oid *objid, size_t objidlen)
++{
++ return "(debugging is disabled)";
++}
+
+ #endif /* DEBUGGING */
+
+@@ -451,8 +459,7 @@ int flag;
+ if (flag == USE_ENUMS) {
+ for(ep = tp->enums; ep; ep = ep->next) {
+ if (ep->value == *var->val.integer) {
+- strncpy(buf, ep->label, buf_len);
+- buf[buf_len-1] = '\0';
++ strlcpy(buf, ep->label, buf_len);
+ len = strlen(buf);
+ break;
+ }
+@@ -929,19 +936,22 @@ oid *doid_arr;
+ size_t *doid_arr_len;
+ char * soid_str;
+ {
+- char soid_buf[STR_BUF_SIZE];
++ char *soid_buf;
+ char *cp;
+ char *st;
+
+ if (!soid_str || !*soid_str) return SUCCESS;/* successfully added nothing */
+ if (*soid_str == '.') soid_str++;
+- strcpy(soid_buf, soid_str);
++ soid_buf = strdup(soid_str);
++ if (!soid_buf)
++ return FAILURE;
+ cp = strtok_r(soid_buf,".",&st);
+ while (cp) {
+ sscanf(cp, "%" NETSNMP_PRIo "u", &(doid_arr[(*doid_arr_len)++]));
+ /* doid_arr[(*doid_arr_len)++] = atoi(cp); */
+ cp = strtok_r(NULL,".",&st);
+ }
++ free(soid_buf);
+ return(SUCCESS);
+ }
+
+@@ -1040,7 +1050,7 @@ OCT:
+ vars->type = ASN_IPADDRESS;
+ vars->val.integer = netsnmp_malloc(sizeof(in_addr_t));
+ if (val)
+- *(vars->val.integer) = inet_addr(val);
++ *((in_addr_t *)vars->val.integer) = inet_addr(val);
+ else {
+ ret = FAILURE;
+ *(vars->val.integer) = 0;
+@@ -1584,7 +1594,7 @@ _bulkwalk_done(walk_context *context)
+ ** walks still in progress.
+ */
+ DBPRT(1, (DBOUT "Ignoring %s request oid %s\n",
+- bt_entry->norepeat? "nonrepeater" : "completed",
++ bt_entry->norepeat ? "nonrepeater" : "completed",
+ __snprint_oid(bt_entry->req_oid, bt_entry->req_len)));
+
+ /* Ignore this OID in any further packets. */
+@@ -1894,7 +1904,7 @@ _bulkwalk_recv_pdu(walk_context *context, netsnmp_pdu *pdu)
+ int i;
+ AV *varbind;
+ SV *rv;
+- DBDCL(SV**sess_ptr_sv=hv_fetch((HV*)SvRV(context->sess_ref),"SessPtr",7,1);)
++ SV **sess_ptr_sv = hv_fetch((HV*)SvRV(context->sess_ref), "SessPtr", 7, 1);
+ SV **err_str_svp = hv_fetch((HV*)SvRV(context->sess_ref), "ErrorStr", 8, 1);
+ SV **err_num_svp = hv_fetch((HV*)SvRV(context->sess_ref), "ErrorNum", 8, 1);
+ SV **err_ind_svp = hv_fetch((HV*)SvRV(context->sess_ref), "ErrorInd", 8, 1);
+@@ -2930,6 +2940,8 @@ snmp_add_mib_dir(mib_dir,force=0)
+ int result = 0; /* Avoid use of uninitialized variable below. */
+ int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));
+
++ DBPRT(999, (DBOUT "force=%d\n", force));
++
+ if (mib_dir && *mib_dir) {
+ result = add_mibdir(mib_dir);
+ }
+@@ -2979,6 +2991,8 @@ snmp_read_mib(mib_file, force=0)
+ {
+ int verbose = SvIV(perl_get_sv("SNMP::verbose", 0x01 | 0x04));
+
++ DBPRT(999, (DBOUT "force=%d\n", force));
++
+ if ((mib_file == NULL) || (*mib_file == '\0')) {
+ if (get_tree_head() == NULL) {
+ if (verbose) warn("snmp_read_mib: initializing MIB\n");
+@@ -3541,11 +3555,11 @@ snmp_getnext(sess_ref, varlist_ref, perl_callback)
+ varbind = (AV*) SvRV(*varbind_ref);
+
+ /* If the varbind includes the module prefix, capture it for use later */
+- strncpy(tmp_buf_prefix, __av_elem_pv(varbind, VARBIND_TAG_F, ".0"), STR_BUF_SIZE);
++ strlcpy(tmp_buf_prefix, __av_elem_pv(varbind, VARBIND_TAG_F, ".0"), STR_BUF_SIZE);
+ tmp_prefix_ptr = strstr(tmp_buf_prefix,"::");
+ if (tmp_prefix_ptr) {
+ tmp_prefix_ptr = strtok_r(tmp_buf_prefix, "::", &st);
+- strncpy(str_buf_prefix, tmp_prefix_ptr, STR_BUF_SIZE);
++ strlcpy(str_buf_prefix, tmp_prefix_ptr, STR_BUF_SIZE);
+ }
+ else {
+ *str_buf_prefix = '\0';
+@@ -3657,9 +3671,9 @@ snmp_getnext(sess_ref, varlist_ref, perl_callback)
+
+ /* Prepend the module prefix to the next OID if needed */
+ if (*str_buf_prefix) {
+- strncat(str_buf_prefix, "::", STR_BUF_SIZE - strlen(str_buf_prefix) - 2);
+- strncat(str_buf_prefix, str_buf, STR_BUF_SIZE - strlen(str_buf_prefix));
+- strncpy(str_buf, str_buf_prefix, STR_BUF_SIZE);
++ strlcat(str_buf_prefix, "::", STR_BUF_SIZE);
++ strlcat(str_buf_prefix, str_buf, STR_BUF_SIZE);
++ strlcpy(str_buf, str_buf_prefix, STR_BUF_SIZE);
+ }
+
+ if (__is_leaf(tp)) {
+@@ -4242,15 +4256,16 @@ snmp_bulkwalk(sess_ref, nonrepeaters, maxrepetitions, varlist_ref,perl_callback)
+
+ /* Handle error cases and clean up after ourselves. */
+ err:
+- if (context->req_oids && context->nreq_oids) {
+- bt_entry = context->req_oids;
+- for (i = 0; i < context->nreq_oids; i++, bt_entry++)
+- av_clear(bt_entry->vars);
+- }
+- if (context->req_oids)
+- Safefree(context->req_oids);
+- if (context)
++ if (context) {
++ if (context->req_oids && context->nreq_oids) {
++ bt_entry = context->req_oids;
++ for (i = 0; i < context->nreq_oids; i++, bt_entry++)
++ av_clear(bt_entry->vars);
++ }
++ if (context->req_oids)
++ Safefree(context->req_oids);
+ Safefree(context);
++ }
+ if (pdu)
+ snmp_free_pdu(pdu);
+
+@@ -4437,7 +4452,7 @@ snmp_trapV2(sess_ref,uptime,trap_oid,varlist_ref)
+
+ New (0, oid_arr, MAX_OID_LEN, oid);
+
+- if (oid_arr && SvROK(sess_ref) && SvROK(varlist_ref)) {
++ if (oid_arr && SvROK(sess_ref)) {
+
+ sess_ptr_sv = hv_fetch((HV*)SvRV(sess_ref), "SessPtr", 7, 1);
+ ss = (SnmpSession *)SvIV((SV*)SvRV(*sess_ptr_sv));
+@@ -4451,8 +4466,13 @@ snmp_trapV2(sess_ref,uptime,trap_oid,varlist_ref)
+
+ pdu = snmp_pdu_create(SNMP_MSG_TRAP2);
+
+- varlist = (AV*) SvRV(varlist_ref);
+- varlist_len = av_len(varlist);
++ if (SvROK(varlist_ref)) {
++ varlist = (AV*) SvRV(varlist_ref);
++ varlist_len = av_len(varlist);
++ } else {
++ varlist = NULL;
++ varlist_len = -1;
++ }
+ /************************************************/
+ res = __add_var_val_str(pdu, sysUpTime, SYS_UPTIME_OID_LEN,
+ uptime, strlen(uptime), TYPE_TIMETICKS);
+@@ -4838,10 +4858,10 @@ snmp_translate_obj(var,mode,use_long,auto_init,best_guess,include_module_name)
+ if (((status=__get_label_iid(str_buf_temp,
+ &label, &iid, NO_FLAGS)) == SUCCESS)
+ && label) {
+- strcpy(str_buf_temp, label);
++ strlcpy(str_buf_temp, label, sizeof(str_buf_temp));
+ if (iid && *iid) {
+- strcat(str_buf_temp, ".");
+- strcat(str_buf_temp, iid);
++ strlcat(str_buf_temp, ".", sizeof(str_buf_temp));
++ strlcat(str_buf_temp, iid, sizeof(str_buf_temp));
+ }
+ }
+ }
+@@ -4902,6 +4922,15 @@ snmp_set_debugging(val)
+ }
+
+ void
++snmp_register_debug_tokens(tokens)
++ char *tokens
++ CODE:
++ {
++ debug_register_tokens(tokens);
++ snmp_set_do_debugging(1);
++ }
++
++void
+ snmp_debug_internals(val)
+ int val
+ CODE:
+diff --git a/perl/SNMP/examples/pingmib.pl b/perl/SNMP/examples/pingmib.pl
+old mode 100644
+new mode 100755
+index 22dbe69..e6aa792
+--- a/perl/SNMP/examples/pingmib.pl
++++ b/perl/SNMP/examples/pingmib.pl
+@@ -1,3 +1,9 @@
++#!/usr/bin/env perl
++
++# Ping a host via the CISCO-PING-MIB. For more information about the
++# CISCO-PING-MIB, see also
++# http://tools.cisco.com/Support/SNMP/do/BrowseMIB.do?local=en&mibName=CISCO-PING-MIB.
++
+ use strict;
+ use SNMP;
+
+@@ -13,8 +19,9 @@ my $community = shift || 'private';
+ my $dec = pack("C*",split /\./, $target);
+ my $oid = ".1.3.6.1.4.1.9.9.16.1.1.1";
+ my $row = "300";
++ my $res;
+
+- $sess->set([
++ $res = $sess->set([
+ ["$oid.16", $row, 6, "INTEGER"],
+ ["$oid.16", $row, 5, "INTEGER"],
+ ["$oid.15", $row, "MoNDS", "OCTETSTR"],
+@@ -22,8 +29,11 @@ my $community = shift || 'private';
+ ["$oid.4", $row, 20, "INTEGER"],
+ ["$oid.5", $row, 150, "INTEGER"],
+ ["$oid.3", $row, $dec, "OCTETSTR"]]);
++ defined($res) || die "row creation failed";
++
++ $res = $sess->set([["$oid.16", $row, 1, "INTEGER"]]);
++ defined($res) || die "row activation failed";
+
+- $sess->set([["$oid.16", $row, 1, "INTEGER"]]);
+ sleep 30;
+ my ($sent, $received, $low, $avg, $high, $completed) = $sess->get([
+ ["$oid.9", $row], ["$oid.10", $row], ["$oid.11", $row],
+diff --git a/perl/SNMP/t/async.t b/perl/SNMP/t/async.t
+index b1c86c6..f3fb38d 100644
+--- a/perl/SNMP/t/async.t
++++ b/perl/SNMP/t/async.t
+@@ -17,7 +17,7 @@ use SNMP;
+ use vars qw($agent_port $comm $agent_host);
+
+ if ($^O =~ /win32/i) {
+- warn "Win32 detected - skipping async calls\n";
++ warn "Win32/Win64 detected - skipping async calls\n";
+ exit;
+ }
+
+diff --git a/perl/SNMP/t/bulkwalk.t b/perl/SNMP/t/bulkwalk.t
+index 60f10b5..2d13e7b 100644
+--- a/perl/SNMP/t/bulkwalk.t
++++ b/perl/SNMP/t/bulkwalk.t
+@@ -326,7 +326,7 @@ $vars = new SNMP::VarList ( ['sysUpTime'], ['ifNumber'], # NON-repeaters
+ ['ifSpeed'], ['ifDescr']); # Repeated variables.
+
+ if ($^O =~ /win32/i) {
+- warn "Win32 detected - skipping async calls\n";
++ warn "Win32/Win64 detected - skipping async calls\n";
+ }
+ else {
+ @list = $s1->bulkwalk(2, 16, $vars, [ \&async_cb1, $vars ] );
+diff --git a/perl/SNMP/t/notify.t b/perl/SNMP/t/notify.t
+index 434237f..72600fa 100644
+--- a/perl/SNMP/t/notify.t
++++ b/perl/SNMP/t/notify.t
+@@ -10,7 +10,7 @@ BEGIN {
+ $ENV{'MIBDIRS'} = '+' . abs_path("../../mibs");
+ }
+ use Test;
+-BEGIN { $n = 10; plan tests => $n }
++BEGIN { $n = 11; plan tests => $n }
+ use SNMP;
+ use vars qw($agent_port $comm $comm2 $trap_port $agent_host $sec_name $priv_pass $auth_pass $bad_name);
+ require 't/startagent.pl';
+@@ -21,20 +21,20 @@ my $enterprise = '.1.3.6.1.2.1.1.1.0';
+ my $generic = 'specific';
+
+ # V1 trap testing
+-###################### 1 #############################
++######################## 1 ############################
+ # Fire up a trap session.
+ my $s1 =
+ new SNMP::Session (DestHost=>$agent_host,Version=>1,Community=>$comm,RemotePort=>$trap_port);
+ ok(defined($s1));
+
+-########################## 2 ####################################
++######################## 2 ############################
+ # test v1 trap
+ if (defined($s1)) {
+ $res = $s1->trap(enterprise => $enterprise, agent=>$agent_host, generic=>$generic,[[sysContact, 0, 'root@localhost'], [sysLocation, 0, 'here']] );
+ }
+ ok($res =~ /^0 but true/);
+
+-########################### 3 #############################
++######################## 3 ############################
+ # test with wrong varbind
+ undef $res;
+ if (defined($s1)) {
+@@ -45,12 +45,12 @@ ok(!defined($res));
+ #########################################################
+
+ # V2 testing
+-########################## 4 ############################
++######################## 4 ############################
+ # Fire up a v2 trap session.
+ my $s2 =
+ new SNMP::Session (Version=>2, DestHost=>$agent_host,Community=>$comm2,RemotePort=>$trap_port);
+ ok(defined($s2));
+-######################### 5 ###########################
++######################## 5 ############################
+ # test v2 trap
+ undef $res;
+ if (defined($s2)) {
+@@ -58,7 +58,7 @@ if (defined($s2)) {
+ #print("res is $res\n");
+ }
+ ok($res =~ /^0 but true/);
+-########################## 6 ##########################
++######################## 6 ############################
+ # no trapoid and uptime given. Should take defaults...
+ my $ret;
+ if (defined($s2)) {
+@@ -66,27 +66,35 @@ if (defined($s2)) {
+ #print("res is $ret\n");
+ }
+ ok(defined($ret));
++######################## 7 ############################
++# no varbind list given.
++undef $res;
++if (defined($s2)) {
++ $res = $s2->trap(trapoid=>'coldStart');
++ #print("res is $res\n");
++}
++ok(defined($res) && $res =~ /^0 but true/);
+
+ #########################################################
+
+ # v3 testing
+-######################## 7 ############################
++######################## 8 ############################
+ # Fire up a v3 trap session.
+ my $s3 = new SNMP::Session(Version=>3, DestHost=> $agent_host, RemotePort=>$trap_port, SecName => $sec_name);
+ ok(defined($s3));
+
+-######################## 8 ###########################
++######################## 9 ############################
+ if (defined($s3)) {
+ $res = $s3->inform(uptime=>111, trapoid=>'coldStart', [[sysContact, 0, 'root@localhost'], [sysLocation, 0, 'here']] );
+ }
+ ok($res =~ /^0 but true/);
+
+-#################### 9 #####################
++######################## 10 ############################
+ # Fire up a v3 trap session.
+ $s3 = new SNMP::Session(Version=>3, DestHost=> $agent_host, RemotePort=>$trap_port, SecName => $sec_name, SecLevel => authPriv, AuthPass => $auth_pass, PrivPass => $priv_pass);
+ ok(defined($s3));
+
+-######################## 10 ###########################
++######################## 11 ############################
+ undef $res;
+ if (defined($s3)) {
+ $res = $s3->inform(uptime=>111, trapoid=>'coldStart', [[sysContact, 0, 'root@localhost'], [sysLocation, 0, 'here']] );
+diff --git a/perl/agent/agent.pm b/perl/agent/agent.pm
+index 7a71a17..78421cb 100644
+--- a/perl/agent/agent.pm
++++ b/perl/agent/agent.pm
+@@ -98,7 +98,7 @@ sub AUTOLOAD {
+ ($constname = $AUTOLOAD) =~ s/.*:://;
+ croak "& not defined" if $constname eq 'constant';
+ my $val;
+- ($!, $val) = constant($constname, @_ ? $_[0] : 0);
++ ($!, $val) = constant($constname);
+ if ($! != 0) {
+ if ($! =~ /Invalid/ || $!{EINVAL}) {
+ $AutoLoader::AUTOLOAD = $AUTOLOAD;
+@@ -199,6 +199,12 @@ sub agent_check_and_process {
+ __agent_check_and_process($blocking || 0);
+ }
+
++sub uptime {
++ my $self = shift;
++ $self->maybe_init_lib();
++ return _uptime();
++}
++
+ bootstrap NetSNMP::agent $VERSION;
+
+ # Preloaded methods go here.
+diff --git a/perl/agent/agent.xs b/perl/agent/agent.xs
+index ee77d50..c7b5d9a 100644
+--- a/perl/agent/agent.xs
++++ b/perl/agent/agent.xs
+@@ -215,13 +215,12 @@ handler_wrapper(netsnmp_mib_handler *handler,
+ MODULE = NetSNMP::agent PACKAGE = NetSNMP::agent
+
+ void
+-constant(sv,arg)
++constant(sv)
+ PREINIT:
+ STRLEN len;
+ INPUT:
+ SV * sv
+ char * s = SvPV(sv, len);
+- int arg
+ INIT:
+ int status;
+ double value;
+@@ -239,6 +238,13 @@ __agent_check_and_process(block = 1)
+ OUTPUT:
+ RETVAL
+
++int
++_uptime()
++ CODE:
++ RETVAL = netsnmp_get_agent_uptime();
++ OUTPUT:
++ RETVAL
++
+ void
+ init_mib()
+ CODE:
+@@ -272,6 +278,8 @@ na_shutdown(me)
+ SV *me;
+ CODE:
+ {
++ if (0)
++ printf("me = %p\n", me);
+ snmp_shutdown("perl");
+ }
+
+@@ -284,6 +292,8 @@ na_errlog(me,value)
+ char * stringptr;
+ CODE:
+ {
++ if (0)
++ printf("me = %p\n", me);
+ stringptr = SvPV(value, stringlen);
+ snmp_log(LOG_ERR, "%s", stringptr );
+ }
+@@ -340,13 +350,27 @@ nsahr_register(me)
+ SV *me;
+ PREINIT:
+ netsnmp_handler_registration *reginfo;
++ handler_cb_data *cb_data = NULL;
+ CODE:
+ {
+ reginfo = (netsnmp_handler_registration *) SvIV(SvRV(me));
++ if (reginfo && reginfo->handler && reginfo->handler->myvoid)
++ cb_data = (handler_cb_data *) (reginfo->handler->myvoid);
+ RETVAL = netsnmp_register_handler(reginfo);
+ if (!RETVAL) {
+ /* the agent now has a "reference" to this reg pointer */
+ SvREFCNT_inc(me);
++ } else {
++ /*
++ * The reginfo was freed by netsnmp_register_handler,
++ * don't touch it in nsahr_DESTROY!
++ */
++ sv_setiv(SvRV(me), 0);
++ if (cb_data) {
++ /* And just free the callback. */
++ SvREFCNT_dec(cb_data->perl_cb);
++ free(cb_data);
++ }
+ }
+ }
+ OUTPUT:
+diff --git a/perl/agent/default_store/default_store.xs b/perl/agent/default_store/default_store.xs
+index 815f9fd..bff1485 100644
+--- a/perl/agent/default_store/default_store.xs
++++ b/perl/agent/default_store/default_store.xs
+@@ -622,7 +622,7 @@ constant(sv)
+ #endif
+ STRLEN len;
+ int type;
+- IV iv;
++ IV iv = 0;
+ /* NV nv; Uncomment this if you need to return NVs */
+ /* const char *pv; Uncomment this if you need to return PVs */
+ INPUT:
+diff --git a/perl/agent/test.pl b/perl/agent/test.pl
+index a7ac8f9..88cba56 100644
+--- a/perl/agent/test.pl
++++ b/perl/agent/test.pl
+@@ -9,7 +9,7 @@
+ BEGIN { $| = 1;
+ $ENV{'SNMPCONFPATH'} = 'nopath';
+ $ENV{'MIBS'} = '';
+- print "1..5\n";
++ print "1..6\n";
+ }
+ END {print "not ok 1\n" unless $loaded;}
+ use NetSNMP::agent (':all');
+@@ -76,6 +76,12 @@ $regitem = $agent->register("test_reg", ".1.3.6.1.8888", \&testsub);
+ print it($regitem, 4);
+ #print STDERR $regitem,":",ref($regitem),"\n";
+ print it(ref($regitem) eq "NetSNMP::agent::netsnmp_handler_registration", 5);
++
++my $uptime1 = $agent->uptime();
++my $uptime2 = $agent->uptime(666);
++my $uptime3 = $agent->uptime(555, 444);
++print it($uptime1 <= $uptime2 && $uptime2 <= $uptime3, 6);
++
+ exit;
+
+ while(1) {
+diff --git a/perl/default_store/default_store.xs b/perl/default_store/default_store.xs
+index e2b8a34..ca252fb 100644
+--- a/perl/default_store/default_store.xs
++++ b/perl/default_store/default_store.xs
+@@ -1261,7 +1261,7 @@ constant(sv)
+ #endif
+ STRLEN len;
+ int type;
+- IV iv;
++ IV iv = 0;
+ /* NV nv; Uncomment this if you need to return NVs */
+ /* const char *pv; Uncomment this if you need to return PVs */
+ INPUT:
+diff --git a/python/netsnmp/client_intf.c b/python/netsnmp/client_intf.c
+index f2abf0b..559a9c0 100644
+--- a/python/netsnmp/client_intf.c
++++ b/python/netsnmp/client_intf.c
+@@ -1,5 +1,11 @@
+ #include <Python.h>
+
++#if PY_VERSION_HEX < 0x02050000
++typedef int Py_ssize_t;
++#define PY_SSIZE_T_MAX INT_MAX
++#define PY_SSIZE_T_MIN INT_MIN
++#endif
++
+ #include <net-snmp/net-snmp-config.h>
+ #include <net-snmp/net-snmp-includes.h>
+ #include <sys/types.h>
+@@ -67,8 +73,6 @@
+
+ typedef netsnmp_session SnmpSession;
+ typedef struct tree SnmpMibNode;
+-static void __recalc_timeout (struct timeval*,struct timeval*,
+- struct timeval*,struct timeval*, int* );
+ static int __is_numeric_oid (char*);
+ static int __is_leaf (struct tree*);
+ static int __translate_appl_type (char*);
+@@ -80,10 +84,6 @@ static int __sprint_num_objid (char *, oid *, int);
+ static int __scan_num_objid (char *, oid *, size_t *);
+ static int __get_type_str (int, char *);
+ static int __get_label_iid (char *, char **, char **, int);
+-static int __oid_cmp (oid *, int, oid *, int);
+-static int __tp_sprint_num_objid (char*,SnmpMibNode *);
+-static SnmpMibNode * __get_next_mib_node (SnmpMibNode *);
+-static struct tree * __oid2tp (oid*, int, struct tree *, int*);
+ static struct tree * __tag2oid (char *, char *, oid *, int *, int *, int);
+ static int __concat_oid_str (oid *, int *, char *);
+ static int __add_var_val_str (netsnmp_pdu *, oid *, int, char *,
+@@ -129,46 +129,6 @@ __libraries_init(char *appname)
+ NETSNMP_OID_OUTPUT_SUFFIX);
+ }
+
+-static void
+-__recalc_timeout (tvp, ctvp, ltvp, itvp, block)
+-struct timeval* tvp;
+-struct timeval* ctvp;
+-struct timeval* ltvp;
+-struct timeval* itvp;
+-int *block;
+-{
+- struct timeval now;
+-
+- if (!timerisset(itvp)) return; /* interval zero means loop forever */
+- *block = 0;
+- gettimeofday(&now,(struct timezone *)0);
+-
+- if (ctvp->tv_sec < 0) { /* first time or callback just fired */
+- timersub(&now,ltvp,ctvp);
+- timersub(ctvp,itvp,ctvp);
+- timersub(itvp,ctvp,ctvp);
+- timeradd(ltvp,itvp,ltvp);
+- } else {
+- timersub(&now,ltvp,ctvp);
+- timersub(itvp,ctvp,ctvp);
+- }
+-
+- /* flag is set for callback but still hasnt fired so set to something
+- * small and we will service packets first if there are any ready
+- * (also guard against negative timeout - should never happen?)
+- */
+- if (!timerisset(ctvp) || ctvp->tv_sec < 0 || ctvp->tv_usec < 0) {
+- ctvp->tv_sec = 0;
+- ctvp->tv_usec = 10;
+- }
+-
+- /* if snmp timeout > callback timeout or no more requests to process */
+- if (timercmp(tvp, ctvp, >) || !timerisset(tvp)) {
+- *tvp = *ctvp; /* use the smaller non-zero timeout */
+- timerclear(ctvp); /* used as a flag to let callback fire on timeout */
+- }
+-}
+-
+ static int
+ __is_numeric_oid (oidstr)
+ char* oidstr;
+@@ -189,21 +149,6 @@ struct tree* tp;
+ (tp->parent && __get_type_str(tp->parent->type,buf) )));
+ }
+
+-static SnmpMibNode*
+-__get_next_mib_node (tp)
+-SnmpMibNode* tp;
+-{
+- /* printf("tp = %lX, parent = %lX, peer = %lX, child = %lX\n",
+- tp, tp->parent, tp->next_peer, tp->child_list); */
+- if (tp->child_list) return(tp->child_list);
+- if (tp->next_peer) return(tp->next_peer);
+- if (!tp->parent) return(NULL);
+- for (tp = tp->parent; !tp->next_peer; tp = tp->parent) {
+- if (!tp->parent) return(NULL);
+- }
+- return(tp->next_peer);
+-}
+-
+ static int
+ __translate_appl_type(typestr)
+ char* typestr;
+@@ -261,50 +206,36 @@ int type;
+ switch (type) {
+ case ASN_INTEGER:
+ return(TYPE_INTEGER);
+- break;
+ case ASN_OCTET_STR:
+ return(TYPE_OCTETSTR);
+- break;
+ case ASN_OPAQUE:
+ return(TYPE_OPAQUE);
+- break;
+ case ASN_OBJECT_ID:
+ return(TYPE_OBJID);
+- break;
+ case ASN_TIMETICKS:
+ return(TYPE_TIMETICKS);
+- break;
+ case ASN_GAUGE:
+ return(TYPE_GAUGE);
+- break;
+ case ASN_COUNTER:
+ return(TYPE_COUNTER);
+- break;
+ case ASN_IPADDRESS:
+ return(TYPE_IPADDR);
+- break;
+ case ASN_BIT_STR:
+ return(TYPE_BITSTRING);
+- break;
+ case ASN_NULL:
+ return(TYPE_NULL);
+- break;
+ /* no translation for these exception type values */
+ case SNMP_ENDOFMIBVIEW:
+ case SNMP_NOSUCHOBJECT:
+ case SNMP_NOSUCHINSTANCE:
+ return(type);
+- break;
+ case ASN_UINTEGER:
+ return(TYPE_UINTEGER);
+- break;
+ case ASN_COUNTER64:
+ return(TYPE_COUNTER64);
+- break;
+ default:
+- return(TYPE_OTHER);
+ fprintf(stderr, "translate_asn_type: unhandled asn type (%d)\n",type);
+- break;
++ return(TYPE_OTHER);
+ }
+ }
+
+@@ -335,8 +266,7 @@ int flag;
+ if (flag == USE_ENUMS) {
+ for(ep = tp->enums; ep; ep = ep->next) {
+ if (ep->value == *var->val.integer) {
+- strncpy(buf, ep->label, buf_len);
+- buf[buf_len -1] = 0;
++ strlcpy(buf, ep->label, buf_len);
+ len = STRLEN(buf);
+ break;
+ }
+@@ -445,21 +375,6 @@ int len;
+ }
+
+ static int
+-__tp_sprint_num_objid (buf, tp)
+-char *buf;
+-SnmpMibNode *tp;
+-{
+- oid newname[MAX_OID_LEN], *op;
+- /* code taken from get_node in snmp_client.c */
+- for (op = newname + MAX_OID_LEN - 1; op >= newname; op--) {
+- *op = tp->subid;
+- tp = tp->parent;
+- if (tp == NULL) break;
+- }
+- return __sprint_num_objid(buf, op, newname + MAX_OID_LEN - op);
+-}
+-
+-static int
+ __scan_num_objid (buf, objid, len)
+ char *buf;
+ oid *objid;
+@@ -674,24 +589,6 @@ int flag;
+ return(SUCCESS);
+ }
+
+-
+-static int
+-__oid_cmp(oida_arr, oida_arr_len, oidb_arr, oidb_arr_len)
+-oid *oida_arr;
+-int oida_arr_len;
+-oid *oidb_arr;
+-int oidb_arr_len;
+-{
+- for (;oida_arr_len && oidb_arr_len;
+- oida_arr++, oida_arr_len--, oidb_arr++, oidb_arr_len--) {
+- if (*oida_arr == *oidb_arr) continue;
+- return(*oida_arr > *oidb_arr ? 1 : -1);
+- }
+- if (oida_arr_len == oidb_arr_len) return(0);
+- return(oida_arr_len > oidb_arr_len ? 1 : -1);
+-}
+-
+-
+ /* Convert a tag (string) to an OID array */
+ /* Tag can be either a symbolic name, or an OID string */
+ static struct tree *
+@@ -708,9 +605,6 @@ int best_guess;
+ oid newname[MAX_OID_LEN], *op;
+ size_t newname_len = 0;
+
+- char str_buf[STR_BUF_SIZE];
+- str_buf[0] = '\0';
+-
+ if (type) *type = TYPE_UNKNOWN;
+ if (oid_arr_len) *oid_arr_len = 0;
+ if (!tag) goto done;
+@@ -796,43 +690,10 @@ int best_guess;
+ }
+ }
+ done:
+- if (iid && *iid) __concat_oid_str(oid_arr, oid_arr_len, iid);
++ if (iid && *iid && oid_arr_len)
++ __concat_oid_str(oid_arr, oid_arr_len, iid);
+ return(rtp);
+ }
+-/* searches down the mib tree for the given oid
+- returns the last found tp and its index in lastind
+- */
+-static struct tree *
+-__oid2tp (oidp, len, subtree, lastind)
+-oid* oidp;
+-int len;
+-struct tree * subtree;
+-int* lastind;
+-{
+- struct tree *return_tree = NULL;
+-
+-
+- for (; subtree; subtree = subtree->next_peer) {
+- if (*oidp == subtree->subid){
+- goto found;
+- }
+- }
+- *lastind=0;
+- return NULL;
+-
+-found:
+- if (len > 1){
+- return_tree =
+- __oid2tp(oidp + 1, len - 1, subtree->child_list, lastind);
+- (*lastind)++;
+- } else {
+- *lastind=1;
+- }
+- if (return_tree)
+- return return_tree;
+- else
+- return subtree;
+-}
+
+ /* function: __concat_oid_str
+ *
+@@ -848,19 +709,22 @@ oid *doid_arr;
+ int *doid_arr_len;
+ char * soid_str;
+ {
+- char soid_buf[STR_BUF_SIZE];
++ char *soid_buf;
+ char *cp;
+ char *st;
+
+ if (!soid_str || !*soid_str) return SUCCESS;/* successfully added nothing */
+ if (*soid_str == '.') soid_str++;
+- strcpy(soid_buf, soid_str);
++ soid_buf = strdup(soid_str);
++ if (!soid_buf)
++ return FAILURE;
+ cp = strtok_r(soid_buf,".",&st);
+ while (cp) {
+ sscanf(cp, "%lu", &(doid_arr[(*doid_arr_len)++]));
+ /* doid_arr[(*doid_arr_len)++] = atoi(cp); */
+ cp = strtok_r(NULL,".",&st);
+ }
++ free(soid_buf);
+ return(SUCCESS);
+ }
+
+@@ -1004,7 +868,7 @@ char *err_str;
+ int *err_num;
+ int *err_ind;
+ {
+- int status;
++ int status = 0;
+ long command = pdu->command;
+ char *tmp_err_str;
+
+@@ -1017,7 +881,7 @@ int *err_ind;
+ if (ss == NULL) {
+ *err_num = 0;
+ *err_ind = SNMPERR_BAD_SESSION;
+- strncpy(err_str, snmp_api_errstring(*err_ind), STR_BUF_SIZE - 1);
++ strlcpy(err_str, snmp_api_errstring(*err_ind), STR_BUF_SIZE);
+ goto done;
+ }
+
+@@ -1025,7 +889,7 @@ int *err_ind;
+ if (tmp_err_str == NULL) {
+ *err_num = errno;
+ *err_ind = SNMPERR_MALLOC;
+- strncpy(err_str, snmp_api_errstring(*err_ind), STR_BUF_SIZE - 1);
++ strlcpy(err_str, snmp_api_errstring(*err_ind), STR_BUF_SIZE);
+ goto done;
+ }
+
+@@ -1070,8 +934,8 @@ retry:
+ /* in SNMPv2c, SNMPv2u, SNMPv2*, and SNMPv3 PDUs */
+ case SNMP_ERR_INCONSISTENTNAME:
+ default:
+- strncpy(err_str, (char*)snmp_errstring((*response)->errstat),
+- STR_BUF_SIZE - 1);
++ strlcpy(err_str, (char*)snmp_errstring((*response)->errstat),
++ STR_BUF_SIZE);
+ *err_num = (int)(*response)->errstat;
+ *err_ind = (*response)->errindex;
+ status = (*response)->errstat;
+@@ -1082,8 +946,7 @@ retry:
+ case STAT_TIMEOUT:
+ case STAT_ERROR:
+ snmp_sess_error(ss, err_num, err_ind, &tmp_err_str);
+- strncpy(err_str, tmp_err_str, STR_BUF_SIZE - 1);
+- err_str[STR_BUF_SIZE - 1] = '\0';
++ strlcpy(err_str, tmp_err_str, STR_BUF_SIZE);
+ break;
+
+ default:
+@@ -1368,8 +1231,9 @@ netsnmp_create_session_v3(PyObject *self, PyObject *args)
+ USM_AUTH_PROTO_SHA_LEN);
+ session.securityAuthProtoLen = USM_AUTH_PROTO_SHA_LEN;
+ } else if (!strcmp(auth_proto, "DEFAULT")) {
+- session.securityAuthProto =
+- get_default_authtype(&session.securityAuthProtoLen);
++ const oid* a = get_default_authtype(&session.securityAuthProtoLen);
++ session.securityAuthProto
++ = snmp_duplicate_objid(a, session.securityAuthProtoLen);
+ } else {
+ if (verbose)
+ printf("error:snmp_new_v3_session:Unsupported authentication protocol(%s)\n", auth_proto);
+@@ -1403,8 +1267,9 @@ netsnmp_create_session_v3(PyObject *self, PyObject *args)
+ USM_PRIV_PROTO_AES_LEN);
+ session.securityPrivProtoLen = USM_PRIV_PROTO_AES_LEN;
+ } else if (!strcmp(priv_proto, "DEFAULT")) {
+- session.securityPrivProto =
+- get_default_privtype(&session.securityPrivProtoLen);
++ const oid *p = get_default_privtype(&session.securityPrivProtoLen);
++ session.securityPrivProto
++ = snmp_duplicate_objid(p, session.securityPrivProtoLen);
+ } else {
+ if (verbose)
+ printf("error:snmp_new_v3_session:Unsupported privacy protocol(%s)\n", priv_proto);
+@@ -1448,7 +1313,6 @@ netsnmp_create_session_tunneled(PyObject *self, PyObject *args)
+ int timeout;
+ char * sec_name;
+ int sec_level;
+- char * sec_eng_id;
+ char * context_eng_id;
+ char * context;
+ char * our_identity;
+@@ -1525,7 +1389,11 @@ netsnmp_create_session_tunneled(PyObject *self, PyObject *args)
+
+ if (!ss)
+ return NULL;
+- return Py_BuildValue("i", (int)ss);
++ /*
++ * Note: on a 64-bit system the statement below discards the upper 32 bits of
++ * "ss", which is most likely a bug.
++ */
++ return Py_BuildValue("i", (int)(uintptr_t)ss);
+ }
+
+ static PyObject *
+@@ -1563,7 +1431,6 @@ netsnmp_get(PyObject *self, PyObject *args)
+ int oid_arr_len = MAX_OID_LEN;
+ int type;
+ char type_str[MAX_TYPE_NAME_LEN];
+- int status;
+ u_char str_buf[STR_BUF_SIZE], *str_bufp = str_buf;
+ size_t str_buf_len = sizeof(str_buf);
+ size_t out_len = 0;
+@@ -1646,8 +1513,8 @@ netsnmp_get(PyObject *self, PyObject *args)
+ }
+ }
+
+- status = __send_sync_pdu(ss, pdu, &response, retry_nosuch,
+- err_str, &err_num, &err_ind);
++ __send_sync_pdu(ss, pdu, &response, retry_nosuch, err_str, &err_num,
++ &err_ind);
+ __py_netsnmp_update_session_errors(session, err_str, err_num, err_ind);
+
+ /*
+@@ -1698,8 +1565,8 @@ netsnmp_get(PyObject *self, PyObject *args)
+ &out_len, 0, &buf_over,
+ vars->name,vars->name_length);
+ if (_debug_level)
+- printf("netsnmp_get:str_bufp:%s:%d:%d\n",
+- str_bufp,str_buf_len,out_len);
++ printf("netsnmp_get:str_bufp:%s:%d:%d\n", str_bufp,
++ (int)str_buf_len, (int)out_len);
+
+ str_buf[sizeof(str_buf)-1] = '\0';
+
+@@ -1715,20 +1582,19 @@ netsnmp_get(PyObject *self, PyObject *args)
+
+ if (_debug_level) printf("netsnmp_get:str_buf:%s\n",str_buf);
+
+- __get_label_iid(str_buf, &tag, &iid, getlabel_flag);
++ __get_label_iid((char *) str_buf, &tag, &iid, getlabel_flag);
+
+ py_netsnmp_attr_set_string(varbind, "tag", tag, STRLEN(tag));
+ py_netsnmp_attr_set_string(varbind, "iid", iid, STRLEN(iid));
+
+ __get_type_str(type, type_str);
+
+- py_netsnmp_attr_set_string(varbind, "type", type_str,
+- STRLEN(type_str));
++ py_netsnmp_attr_set_string(varbind, "type", type_str, strlen(type_str));
+
+- len = __snprint_value(str_buf,sizeof(str_buf),
+- vars,tp,type,sprintval_flag);
++ len = __snprint_value((char *) str_buf, sizeof(str_buf),
++ vars, tp, type, sprintval_flag);
+ str_buf[len] = '\0';
+- py_netsnmp_attr_set_string(varbind, "val", str_buf, len);
++ py_netsnmp_attr_set_string(varbind, "val", (char *) str_buf, len);
+
+ /* save in return tuple as well */
+ PyTuple_SetItem(val_tuple, varlist_ind,
+@@ -1772,13 +1638,12 @@ netsnmp_getnext(PyObject *self, PyObject *args)
+ int oid_arr_len = MAX_OID_LEN;
+ int type;
+ char type_str[MAX_TYPE_NAME_LEN];
+- int status;
+ u_char str_buf[STR_BUF_SIZE], *str_bufp = str_buf;
+ size_t str_buf_len = sizeof(str_buf);
+ size_t out_len = 0;
+ int buf_over = 0;
+ char *tag;
+- char *iid;
++ char *iid = NULL;
+ int getlabel_flag = NO_FLAGS;
+ int sprintval_flag = USE_BASIC;
+ int verbose = py_netsnmp_verbose();
+@@ -1862,8 +1727,8 @@ netsnmp_getnext(PyObject *self, PyObject *args)
+ }
+ }
+
+- status = __send_sync_pdu(ss, pdu, &response, retry_nosuch,
+- err_str, &err_num, &err_ind);
++ __send_sync_pdu(ss, pdu, &response, retry_nosuch, err_str, &err_num,
++ &err_ind);
+ __py_netsnmp_update_session_errors(session, err_str, err_num, err_ind);
+
+ /*
+@@ -1924,7 +1789,7 @@ netsnmp_getnext(PyObject *self, PyObject *args)
+ type = __translate_asn_type(vars->type);
+ }
+
+- __get_label_iid(str_buf, &tag, &iid, getlabel_flag);
++ __get_label_iid((char *) str_buf, &tag, &iid, getlabel_flag);
+
+ if (_debug_level)
+ printf("netsnmp_getnext: filling response: %s:%s\n", tag, iid);
+@@ -1935,13 +1800,13 @@ netsnmp_getnext(PyObject *self, PyObject *args)
+ __get_type_str(type, type_str);
+
+ py_netsnmp_attr_set_string(varbind, "type", type_str,
+- STRLEN(type_str));
++ strlen(type_str));
+
+- len = __snprint_value(str_buf,sizeof(str_buf),
+- vars,tp,type,sprintval_flag);
++ len = __snprint_value((char *) str_buf, sizeof(str_buf),
++ vars, tp, type, sprintval_flag);
+ str_buf[len] = '\0';
+
+- py_netsnmp_attr_set_string(varbind, "val", str_buf, len);
++ py_netsnmp_attr_set_string(varbind, "val", (char *) str_buf, len);
+
+ /* save in return tuple as well */
+ PyTuple_SetItem(val_tuple, varlist_ind,
+@@ -1984,10 +1849,10 @@ netsnmp_walk(PyObject *self, PyObject *args)
+ netsnmp_variable_list *vars, *oldvars;
+ struct tree *tp;
+ int len;
+- oid **oid_arr;
+- int *oid_arr_len;
+- oid **oid_arr_broken_check;
+- int *oid_arr_broken_check_len;
++ oid **oid_arr = NULL;
++ int *oid_arr_len = NULL;
++ oid **oid_arr_broken_check = NULL;
++ int *oid_arr_broken_check_len = NULL;
+ int type;
+ char type_str[MAX_TYPE_NAME_LEN];
+ int status;
+@@ -1996,7 +1861,7 @@ netsnmp_walk(PyObject *self, PyObject *args)
+ size_t out_len = 0;
+ int buf_over = 0;
+ char *tag;
+- char *iid;
++ char *iid = NULL;
+ int getlabel_flag = NO_FLAGS;
+ int sprintval_flag = USE_BASIC;
+ int verbose = py_netsnmp_verbose();
+@@ -2102,7 +1967,8 @@ netsnmp_walk(PyObject *self, PyObject *args)
+ varlist_ind++;
+ }
+
+- Py_DECREF(varlist_iter);
++ if (varlist_iter)
++ Py_DECREF(varlist_iter);
+
+ if (PyErr_Occurred()) {
+ /* propagate error */
+@@ -2246,7 +2112,7 @@ netsnmp_walk(PyObject *self, PyObject *args)
+ type = __translate_asn_type(vars->type);
+ }
+
+- __get_label_iid(str_buf, &tag, &iid, getlabel_flag);
++ __get_label_iid((char *) str_buf, &tag, &iid, getlabel_flag);
+
+ if (_debug_level) printf("netsnmp_walk: filling response: %s:%s\n", tag, iid);
+
+@@ -2256,13 +2122,14 @@ netsnmp_walk(PyObject *self, PyObject *args)
+ __get_type_str(type, type_str);
+
+ py_netsnmp_attr_set_string(varbind, "type", type_str,
+- STRLEN(type_str));
++ strlen(type_str));
+
+- len = __snprint_value(str_buf,sizeof(str_buf),
++ len = __snprint_value((char *) str_buf,sizeof(str_buf),
+ vars,tp,type,sprintval_flag);
+ str_buf[len] = '\0';
+
+- py_netsnmp_attr_set_string(varbind, "val", str_buf, len);
++ py_netsnmp_attr_set_string(varbind, "val", (char *) str_buf,
++ len);
+
+ /* push the varbind onto the return varbinds */
+ PyList_Append(varbinds, varbind);
+@@ -2345,7 +2212,6 @@ netsnmp_getbulk(PyObject *self, PyObject *args)
+ int oid_arr_len = MAX_OID_LEN;
+ int type;
+ char type_str[MAX_TYPE_NAME_LEN];
+- int status;
+ u_char str_buf[STR_BUF_SIZE], *str_bufp = str_buf;
+ size_t str_buf_len = sizeof(str_buf);
+ size_t out_len = 0;
+@@ -2434,8 +2300,8 @@ netsnmp_getbulk(PyObject *self, PyObject *args)
+ goto done;
+ }
+
+- status = __send_sync_pdu(ss, pdu, &response, retry_nosuch,
+- err_str, &err_num, &err_ind);
++ __send_sync_pdu(ss, pdu, &response, retry_nosuch, err_str, &err_num,
++ &err_ind);
+ __py_netsnmp_update_session_errors(session, err_str, err_num, err_ind);
+
+ /*
+@@ -2505,7 +2371,7 @@ netsnmp_getbulk(PyObject *self, PyObject *args)
+ type = __translate_asn_type(vars->type);
+ }
+
+- __get_label_iid(str_buf, &tag, &iid, getlabel_flag);
++ __get_label_iid((char *) str_buf, &tag, &iid, getlabel_flag);
+
+ py_netsnmp_attr_set_string(varbind, "tag", tag, STRLEN(tag));
+ py_netsnmp_attr_set_string(varbind, "iid", iid, STRLEN(iid));
+@@ -2513,13 +2379,13 @@ netsnmp_getbulk(PyObject *self, PyObject *args)
+ __get_type_str(type, type_str);
+
+ py_netsnmp_attr_set_string(varbind, "type", type_str,
+- STRLEN(type_str));
++ strlen(type_str));
+
+- len = __snprint_value(str_buf,sizeof(str_buf),
+- vars,tp,type,sprintval_flag);
++ len = __snprint_value((char *) str_buf, sizeof(str_buf),
++ vars, tp, type, sprintval_flag);
+ str_buf[len] = '\0';
+
+- py_netsnmp_attr_set_string(varbind, "val", str_buf, len);
++ py_netsnmp_attr_set_string(varbind, "val", (char *) str_buf, len);
+
+ /* push varbind onto varbinds */
+ PyList_Append(varbinds, varbind);
+@@ -2556,7 +2422,8 @@ netsnmp_getbulk(PyObject *self, PyObject *args)
+ /* propagate error */
+ if (verbose)
+ printf("error: getbulk response processing: unknown python error");
+- Py_DECREF(val_tuple);
++ if (val_tuple)
++ Py_DECREF(val_tuple);
+ val_tuple = NULL;
+ }
+ }
+@@ -2663,14 +2530,15 @@ netsnmp_set(PyObject *self, PyObject *args)
+ if (type==TYPE_INTEGER && use_enums && tp && tp->enums) {
+ for(ep = tp->enums; ep; ep = ep->next) {
+ if (val && !strcmp(ep->label, val)) {
+- strcpy(tmp_val_str, ep->value);
++ snprintf((char *) tmp_val_str, sizeof(tmp_val_str), "%d",
++ ep->value);
+ break;
+ }
+ }
+ }
+ len = (int)tmplen;
+ status = __add_var_val_str(pdu, oid_arr, oid_arr_len,
+- tmp_val_str, len, type);
++ (char *) tmp_val_str, len, type);
+
+ if (verbose && status == FAILURE)
+ printf("error: set: adding variable/value to PDU");
+diff --git a/snmplib/Makefile.in b/snmplib/Makefile.in
+index 48beb38..506b8d4 100644
+--- a/snmplib/Makefile.in
++++ b/snmplib/Makefile.in
+@@ -243,7 +243,3 @@ libsnmp.$(LIB_EXTENSION)$(LIB_VERSION): $(TOBJS)
+ parse: mib.o parse.c
+ $(CC) $(CFLAGS) -DTEST parse.c -o $@ \
+ `$(top_srcdir)/net-snmp-config --libs`
+-
+-test_binary_array: test_binary_array.c
+- $(CC) $(CFLAGS) test_binary_array.c -o $@ \
+- `$(top_srcdir)/net-snmp-config --libs`
+diff --git a/snmplib/asn1.c b/snmplib/asn1.c
+index 030fa63..e4da6be 100644
+--- a/snmplib/asn1.c
++++ b/snmplib/asn1.c
+@@ -1371,7 +1371,7 @@ asn_parse_objid(u_char * data,
+ }
+ }
+ #if defined(EIGHTBIT_SUBIDS) || (SIZEOF_LONG != 4)
+- if (subidentifier > (u_long) MAX_SUBID) {
++ if (subidentifier > MAX_SUBID) {
+ ERROR_MSG("subidentifier too large");
+ return NULL;
+ }
+@@ -1540,13 +1540,8 @@ asn_build_objid(u_char * data,
+ */
+ for (i = 1, objid_val = first_objid_val, op = objid + 2;
+ i < (int) objidlength; i++) {
+- if (i != 1) {
+- objid_val = *op++;
+-#if SIZEOF_LONG != 4
+- if (objid_val > 0xffffffff) /* already logged warning above */
+- objid_val &= 0xffffffff;
+-#endif
+- }
++ if (i != 1)
++ objid_val = (uint32_t)(*op++); /* already logged warning above */
+ switch (objid_size[i]) {
+ case 1:
+ *data++ = (u_char) objid_val;
+diff --git a/snmplib/callback.c b/snmplib/callback.c
+index 16026e9..dfe537a 100644
+--- a/snmplib/callback.c
++++ b/snmplib/callback.c
+@@ -249,7 +249,7 @@ snmp_register_callback(int major, int minor, SNMPCallback * new_callback,
+ * @param minor Minor callback event type.
+ * @param new_callback Callback function being registered.
+ * @param arg Argument that will be passed to the callback function.
+- * @priority Handler invocation priority. When multiple handlers have
++ * @param priority Handler invocation priority. When multiple handlers have
+ * been registered for the same (major, minor) callback event type, handlers
+ * with the numerically lowest priority will be invoked first. Handlers with
+ * identical priority are invoked in the order they have been registered.
+diff --git a/snmplib/cert_util.c b/snmplib/cert_util.c
+index 6d9efe5..246a6c9 100644
+--- a/snmplib/cert_util.c
++++ b/snmplib/cert_util.c
+@@ -751,7 +751,6 @@ _certindex_add( const char *dirname, int i )
+ if (SE_OK != rc) {
+ snmp_log(LOG_ERR, "adding certindex dirname failed; "
+ "%d (%s) not added\n", i, dirname);
+- free(dirname_copy);
+ return -1;
+ }
+
+@@ -791,7 +790,7 @@ _certindexes_load( void )
+ * Create a list of which directory each file refers to
+ */
+ while ((file = readdir( dir ))) {
+- if ( !isdigit(file->d_name[0]))
++ if ( !isdigit(0xFF & file->d_name[0]))
+ continue;
+ i = atoi( file->d_name );
+
+@@ -801,7 +800,6 @@ _certindexes_load( void )
+ fp = fopen( filename, "r" );
+ if ( !fp ) {
+ DEBUGMSGT(("cert:index:load", "error opening index (%d)\n", i));
+- fclose(fp);
+ continue;
+ }
+ cp = fgets( line, sizeof(line), fp );
+@@ -1179,12 +1177,6 @@ _find_partner(netsnmp_cert *cert, netsnmp_key *key)
+ return;
+ }
+
+- snprintf(filename, sizeof(filename), "%s", key->info.filename);
+- pos = strrchr(filename, '.');
+- if (NULL == pos)
+- return;
+- *pos = 0;
+-
+ if(key) {
+ if (key->cert) {
+ DEBUGMSGT(("cert:partner", "key already has partner\n"));
+@@ -1192,6 +1184,11 @@ _find_partner(netsnmp_cert *cert, netsnmp_key *key)
+ }
+ DEBUGMSGT(("9:cert:partner", "%s looking for partner near %s\n",
+ key->info.filename, key->info.dir));
++ snprintf(filename, sizeof(filename), "%s", key->info.filename);
++ pos = strrchr(filename, '.');
++ if (NULL == pos)
++ return;
++ *pos = 0;
+
+ matching = _cert_find_subset_fn( filename, key->info.dir );
+ if (!matching)
+@@ -1220,6 +1217,11 @@ _find_partner(netsnmp_cert *cert, netsnmp_key *key)
+ }
+ DEBUGMSGT(("9:cert:partner", "%s looking for partner\n",
+ cert->info.filename));
++ snprintf(filename, sizeof(filename), "%s", cert->info.filename);
++ pos = strrchr(filename, '.');
++ if (NULL == pos)
++ return;
++ *pos = 0;
+
+ matching = _key_find_subset(filename);
+ if (!matching)
+@@ -1714,7 +1716,7 @@ netsnmp_fp_lowercase_and_strip_colon(char *fp)
+ break;
+ }
+ else
+- *pos = isalpha(*pos) ? tolower(*pos) : *pos;
++ *pos = isalpha(0xFF & *pos) ? tolower(0xFF & *pos) : *pos;
+ }
+ if (!*pos)
+ return;
+@@ -1723,7 +1725,7 @@ netsnmp_fp_lowercase_and_strip_colon(char *fp)
+ for (++pos; *pos; ++pos) {
+ if (':' == *pos)
+ continue;
+- *dest++ = isalpha(*pos) ? tolower(*pos) : *pos;
++ *dest++ = isalpha(0xFF & *pos) ? tolower(0xFF & *pos) : *pos;
+ }
+ *dest = *pos; /* nul termination */
+ }
+@@ -2011,7 +2013,8 @@ netsnmp_cert_trust(SSL_CTX *ctx, netsnmp_cert *thiscert)
+ {
+ X509_STORE *certstore;
+ X509 *cert;
+-
++ char *fingerprint;
++
+ /* ensure all needed pieces are present */
+ netsnmp_assert_or_msgreturn(NULL != thiscert, "NULL certificate passed in",
+ SNMPERR_GENERR);
+@@ -2033,10 +2036,11 @@ netsnmp_cert_trust(SSL_CTX *ctx, netsnmp_cert *thiscert)
+ SNMPERR_GENERR);
+
+ /* Put the certificate into the store */
++ fingerprint = netsnmp_openssl_cert_get_fingerprint(cert, -1);
+ DEBUGMSGTL(("cert:trust",
+ "putting trusted cert %p = %s in certstore %p\n", cert,
+- netsnmp_openssl_cert_get_fingerprint(cert, -1),
+- certstore));
++ fingerprint, certstore));
++ SNMP_FREE(fingerprint);
+ X509_STORE_add_cert(certstore, cert);
+
+ return SNMPERR_SUCCESS;
+@@ -2132,7 +2136,7 @@ _cert_find_fp(const char *fingerprint)
+ if (NULL == fingerprint)
+ return NULL;
+
+- strncpy(fp, fingerprint, sizeof(fp));
++ strlcpy(fp, fingerprint, sizeof(fp));
+ netsnmp_fp_lowercase_and_strip_colon(fp);
+
+ /** clear search key */
+@@ -2222,7 +2226,7 @@ _reduce_subset_dir(netsnmp_void_array *matching, const char *directory)
+ *
+ * so we want to backup up on directory for compares..
+ */
+- strncpy(dir,directory,sizeof(dir));
++ strlcpy(dir, directory, sizeof(dir));
+ pos = strrchr(dir, '/');
+ if (NULL == pos) {
+ DEBUGMSGTL(("cert:subset:dir", "no '/' in directory %s\n", directory));
+@@ -2690,7 +2694,7 @@ netsnmp_certToTSN_parse_common(char **line)
+ tmp = buf;
+ *line = read_config_read_octet_string(*line, (u_char **)&tmp, &len);
+ tmp[len] = 0;
+- if (!isdigit(tmp[0])) {
++ if (!isdigit(0xFF & tmp[0])) {
+ netsnmp_config_error("could not parse priority");
+ return NULL;
+ }
+@@ -3050,8 +3054,8 @@ netsnmp_tlstmParams_add(snmpTlstmParams *stp)
+ stp->name));
+
+ if (CONTAINER_INSERT(_tlstmParams, stp) != 0) {
+- netsnmp_tlstmParams_free(stp);
+ snmp_log(LOG_ERR, "error inserting tlstmParams %s", stp->name);
++ netsnmp_tlstmParams_free(stp);
+ return -1;
+ }
+
+@@ -3260,8 +3264,8 @@ netsnmp_tlstmAddr_add(snmpTlstmAddr *entry)
+ DEBUGMSGTL(("tlstmAddr:add", "adding entry 0x%lx %s %s\n",
+ (u_long)entry, entry->name, entry->fingerprint));
+ if (CONTAINER_INSERT(_tlstmAddr, entry) != 0) {
+- netsnmp_tlstmAddr_free(entry);
+ snmp_log(LOG_ERR, "could not insert addr %s", entry->name);
++ netsnmp_tlstmAddr_free(entry);
+ return -1;
+ }
+
+@@ -3314,10 +3318,7 @@ _parse_addr(const char *token, char *line)
+ if (id_len)
+ entry->identity = strdup(id);
+
+- if (netsnmp_tlstmAddr_add(entry) != 0)
+- netsnmp_tlstmAddr_free(entry);
+-
+- return;
++ netsnmp_tlstmAddr_add(entry);
+ }
+
+ static char *
+diff --git a/snmplib/container_binary_array.c b/snmplib/container_binary_array.c
+index 41f1d24..249a3a9 100644
+--- a/snmplib/container_binary_array.c
++++ b/snmplib/container_binary_array.c
+@@ -487,7 +487,7 @@ binary_search_for_start(netsnmp_index *val, netsnmp_container *c)
+ void **
+ netsnmp_binary_array_get_subset(netsnmp_container *c, void *key, int *len)
+ {
+- binary_array_table *t = (binary_array_table*)c->container_data;
++ binary_array_table *t;
+ void **subset;
+ int start, end;
+ size_t i;
+diff --git a/snmplib/data_list.c b/snmplib/data_list.c
+index 15f2de2..505d4fc 100644
+--- a/snmplib/data_list.c
++++ b/snmplib/data_list.c
+@@ -240,9 +240,14 @@ netsnmp_register_save_list(netsnmp_data_list **datalist,
+ const char *type, const char *token,
+ Netsnmp_Save_List_Data *data_list_save_ptr,
+ Netsnmp_Read_List_Data *data_list_read_ptr,
+- Netsnmp_Free_List_Data *data_list_free_ptr) {
+- netsnmp_data_list_saveinfo *info =
+- SNMP_MALLOC_TYPEDEF(netsnmp_data_list_saveinfo);
++ Netsnmp_Free_List_Data *data_list_free_ptr)
++{
++ netsnmp_data_list_saveinfo *info;
++
++ if (!data_list_save_ptr && !data_list_read_ptr)
++ return;
++
++ info = SNMP_MALLOC_TYPEDEF(netsnmp_data_list_saveinfo);
+
+ if (!info) {
+ snmp_log(LOG_ERR, "couldn't malloc a netsnmp_data_list_saveinfo typedef");
+diff --git a/snmplib/dir_utils.c b/snmplib/dir_utils.c
+index 89bba6b..cbb6d00 100644
+--- a/snmplib/dir_utils.c
++++ b/snmplib/dir_utils.c
+@@ -122,7 +122,7 @@ netsnmp_directory_container_read_some(netsnmp_container *user_container,
+ dirname_len = 0;
+ else {
+ dirname_len = strlen(dirname);
+- strncpy(path, dirname, sizeof(path));
++ strlcpy(path, dirname, sizeof(path));
+ if ((dirname_len + 2) > sizeof(path)) {
+ /** not enough room for files */
+ closedir(dir);
+@@ -131,7 +131,7 @@ netsnmp_directory_container_read_some(netsnmp_container *user_container,
+ return NULL;
+ }
+ path[dirname_len] = '/';
+- path[++dirname_len] = 0;
++ path[++dirname_len] = '\0';
+ }
+
+ /** iterate over dir */
+@@ -146,7 +146,7 @@ netsnmp_directory_container_read_some(netsnmp_container *user_container,
+ ((file->d_name[1] == '.') && ((file->d_name[2] == 0)))))
+ continue;
+
+- strncpy(&path[dirname_len], file->d_name, sizeof(path) - dirname_len);
++ strlcpy(&path[dirname_len], file->d_name, sizeof(path) - dirname_len);
+ if (NULL != filter) {
+ if (flags & NETSNMP_DIR_NSFILE_STATS) {
+ /** use local vars for now */
+diff --git a/snmplib/int64.c b/snmplib/int64.c
+index 5db2375..2c71b17 100644
+--- a/snmplib/int64.c
++++ b/snmplib/int64.c
+@@ -1,9 +1,10 @@
+-/** file: test.c - test of 64-bit integer stuff
+-*
+-*
+-* 21-jan-1998: David Perkins <dperkins@dsperkins.com>
+-*
+-*/
++/**
++ * @file int64.c
++ *
++ * @brief Functions for 64-bit integer computations.
++ *
++ * 21-jan-1998: David Perkins <dperkins@dsperkins.com>
++ */
+
+ #include <net-snmp/net-snmp-config.h>
+ #include <sys/types.h>
+@@ -24,17 +25,13 @@
+
+ #include <net-snmp/net-snmp-features.h>
+
+-#define TRUE 1
+-#define FALSE 0
+-
+-/** divBy10 - divide an unsigned 64-bit integer by 10
+-*
+-* call with:
+-* u64 - number to be divided
+-* pu64Q - location to store quotient
+-* puR - location to store remainder
+-*
+-*/
++/**
++ * Divide an unsigned 64-bit integer by 10.
++ *
++ * @param[in] u64 Number to be divided.
++ * @param[out] pu64Q Quotient.
++ * @param[out] puR Remainder.
++ */
+ void
+ divBy10(U64 u64, U64 * pu64Q, unsigned int *puR)
+ {
+@@ -42,7 +39,6 @@ divBy10(U64 u64, U64 * pu64Q, unsigned int *puR)
+ unsigned long ulQ;
+ unsigned long ulR;
+
+-
+ /*
+ * top 16 bits
+ */
+@@ -78,18 +74,14 @@ divBy10(U64 u64, U64 * pu64Q, unsigned int *puR)
+ pu64Q->low = pu64Q->low | ulQ;
+
+ *puR = (unsigned int) (ulR);
++}
+
+-
+-} /* divBy10 */
+-
+-
+-/** multBy10 - multiply an unsigned 64-bit integer by 10
+-*
+-* call with:
+-* u64 - number to be multiplied
+-* pu64P - location to store product
+-*
+-*/
++/**
++ * Multiply an unsigned 64-bit integer by 10.
++ *
++ * @param[in] u64 Number to be multiplied.
++ * @param[out] pu64P Product.
++ */
+ void
+ multBy10(U64 u64, U64 * pu64P)
+ {
+@@ -97,7 +89,6 @@ multBy10(U64 u64, U64 * pu64P)
+ unsigned long ulP;
+ unsigned long ulK;
+
+-
+ /*
+ * lower 16 bits
+ */
+@@ -129,159 +120,122 @@ multBy10(U64 u64, U64 * pu64P)
+ ulP = (ulT * 10) + ulK;
+ ulK = ulP >> 16;
+ pu64P->high = (ulP & 0x0ffff) << 16 | pu64P->high;
++}
+
+-
+-} /* multBy10 */
+-
+-
+-/** incrByU16 - add an unsigned 16-bit int to an unsigned 64-bit integer
+-*
+-* call with:
+-* pu64 - number to be incremented
+-* u16 - amount to add
+-*
+-*/
++/**
++ * Add an unsigned 16-bit int to an unsigned 64-bit integer.
++ *
++ * @param[in,out] pu64 Number to be incremented.
++ * @param[in] u16 Amount to add.
++ *
++ */
+ void
+ incrByU16(U64 * pu64, unsigned int u16)
+ {
+- unsigned long ulT1;
+- unsigned long ulT2;
+- unsigned long ulR;
+- unsigned long ulK;
+-
+-
+- /*
+- * lower 16 bits
+- */
+- ulT1 = pu64->low;
+- ulT2 = ulT1 & 0x0ffff;
+- ulR = ulT2 + u16;
+- ulK = ulR >> 16;
+- if (ulK == 0) {
+- pu64->low = ulT1 + u16;
+- return;
+- }
+-
+- /*
+- * next 16 bits
+- */
+- ulT2 = (ulT1 >> 16) & 0x0ffff;
+- ulR = ulT2 + 1;
+- ulK = ulR >> 16;
+- if (ulK == 0) {
+- pu64->low = ulT1 + u16;
+- return;
+- }
+-
+- /*
+- * next 32 - ignore any overflow
+- */
+- pu64->low = (ulT1 + u16) & 0x0FFFFFFFFL;
+- pu64->high++;
+-#if SIZEOF_LONG != 4
+- pu64->high &= 0xffffffff;
+-#endif
+-} /* incrByV16 */
++ incrByU32(pu64, u16);
++}
+
++/**
++ * Add an unsigned 32-bit int to an unsigned 64-bit integer.
++ *
++ * @param[in,out] pu64 Number to be incremented.
++ * @param[in] u32 Amount to add.
++ *
++ */
+ void
+ incrByU32(U64 * pu64, unsigned int u32)
+ {
+- unsigned int tmp;
++ uint32_t tmp;
++
+ tmp = pu64->low;
+- pu64->low += u32;
+-#if SIZEOF_LONG != 4
+- pu64->low &= 0xffffffff;
+-#endif
+- if (pu64->low < tmp) {
+- pu64->high++;
+-#if SIZEOF_LONG != 4
+- pu64->high &= 0xffffffff;
+-#endif
+- }
++ pu64->low = (uint32_t)(tmp + u32);
++ if (pu64->low < tmp)
++ pu64->high = (uint32_t)(pu64->high + 1);
+ }
+
+ /**
+- * pu64out = pu64one - pu64two
++ * Subtract two 64-bit numbers.
++ *
++ * @param[in] pu64one Number to start from.
++ * @param[in] pu64two Amount to subtract.
++ * @param[out] pu64out pu64one - pu64two.
+ */
+ void
+ u64Subtract(const U64 * pu64one, const U64 * pu64two, U64 * pu64out)
+ {
+- if (pu64one->low < pu64two->low) {
+- pu64out->low = 0xffffffff - pu64two->low + pu64one->low + 1;
+- pu64out->high = pu64one->high - pu64two->high - 1;
+- } else {
+- pu64out->low = pu64one->low - pu64two->low;
+- pu64out->high = pu64one->high - pu64two->high;
+- }
++ int carry;
++
++ carry = pu64one->low < pu64two->low;
++ pu64out->low = (uint32_t)(pu64one->low - pu64two->low);
++ pu64out->high = (uint32_t)(pu64one->high - pu64two->high - carry);
+ }
+
+ /**
+- * pu64out += pu64one
++ * Add two 64-bit numbers.
++ *
++ * @param[in] pu64one Amount to add.
++ * @param[in,out] pu64out pu64out += pu64one.
+ */
+ void
+ u64Incr(U64 * pu64out, const U64 * pu64one)
+ {
+- pu64out->high += pu64one->high;
+-#if SIZEOF_LONG != 4
+- pu64out->high &= 0xffffffff;
+-#endif
++ pu64out->high = (uint32_t)(pu64out->high + pu64one->high);
+ incrByU32(pu64out, pu64one->low);
+ }
+
+ /**
+- * pu64out += (pu64one - pu64two)
++ * Add the difference of two 64-bit numbers to a 64-bit counter.
++ *
++ * @param[in] pu64one
++ * @param[in] pu64two
++ * @param[out] pu64out pu64out += (pu64one - pu64two)
+ */
+ void
+ u64UpdateCounter(U64 * pu64out, const U64 * pu64one, const U64 * pu64two)
+ {
+ U64 tmp;
++
+ u64Subtract(pu64one, pu64two, &tmp);
+ u64Incr(pu64out, &tmp);
+ }
+
+-/**
+- * pu64one = pu64two
+- */
+ netsnmp_feature_child_of(u64copy, netsnmp_unused)
+ #ifndef NETSNMP_FEATURE_REMOVE_U64COPY
++/**
++ * Copy a 64-bit number.
++ *
++ * @param[in] pu64two Number to be copied.
++ * @param[out] pu64one Where to store the copy - *pu64one = *pu64two.
++ */
+ void
+ u64Copy(U64 * pu64one, const U64 * pu64two)
+ {
+- pu64one->high = pu64two->high;
+- pu64one->low = pu64two->low;
++ *pu64one = *pu64two;
+ }
+ #endif /* NETSNMP_FEATURE_REMOVE_U64COPY */
+
+-/** zeroU64 - set an unsigned 64-bit number to zero
+-*
+-* call with:
+-* pu64 - number to be zero'ed
+-*
+-*/
++/**
++ * Set an unsigned 64-bit number to zero.
++ *
++ * @param[in] pu64 Number to be zeroed.
++ */
+ void
+ zeroU64(U64 * pu64)
+ {
+ pu64->low = 0;
+ pu64->high = 0;
+-} /* zeroU64 */
+-
++}
+
+-/** isZeroU64 - check if an unsigned 64-bit number is
+-*
+-* call with:
+-* pu64 - number to be zero'ed
+-*
+-*/
++/**
++ * Check if an unsigned 64-bit number is zero.
++ *
++ * @param[in] pu64 Number to be checked.
++ */
+ int
+ isZeroU64(const U64 * pu64)
+ {
+-
+- if ((pu64->low == 0) && (pu64->high == 0))
+- return (TRUE);
+- else
+- return (FALSE);
+-
+-} /* isZeroU64 */
++ return pu64->low == 0 && pu64->high == 0;
++}
+
+ /**
+ * check the old and new values of a counter64 for 32bit wrapping
+@@ -292,7 +246,7 @@ isZeroU64(const U64 * pu64)
+ * @param old_val
+ * @param new_val
+ *
+- *@Note:
++ * @note
+ * The old and new values must be be from within a time period
+ * which would only allow the 32bit portion of the counter to
+ * wrap once. i.e. if the 32bit portion of the counter could
+@@ -331,16 +285,11 @@ netsnmp_c64_check_for_32bit_wrap(struct counter64 *old_val,
+ */
+ if (new_val->high == old_val->high) {
+ DEBUGMSGTL(("c64:check_wrap", "32 bit wrap\n"));
+- if (adjust) {
+- ++new_val->high;
+-#if SIZEOF_LONG != 4
+- new_val->high &= 0xffffffff;
+-#endif
+- }
++ if (adjust)
++ new_val->high = (uint32_t)(new_val->high + 1);
+ return 32;
+ }
+- else if ((new_val->high == (old_val->high + 1)) ||
+- ((0 == new_val->high) && (0xffffffff == old_val->high))) {
++ else if (new_val->high == (uint32_t)(old_val->high + 1)) {
+ DEBUGMSGTL(("c64:check_wrap", "64 bit wrap\n"));
+ return 64;
+ }
+@@ -357,7 +306,7 @@ netsnmp_c64_check_for_32bit_wrap(struct counter64 *old_val,
+ * @param need_wrap_check: pointer to integer indicating if wrap check is needed
+ * flag may be cleared if 64 bit counter is detected
+ *
+- *@Note:
++ * @note
+ * The old_prev_val and new_val values must be be from within a time
+ * period which would only allow the 32bit portion of the counter to
+ * wrap once. i.e. if the 32bit portion of the counter could
+@@ -438,9 +387,11 @@ netsnmp_c64_check32_and_update(struct counter64 *prev_val, struct counter64 *new
+ return 0;
+ }
+
++/** Convert an unsigned 64-bit number to ASCII. */
+ void
+-printU64(char *buf, /* char [I64CHARSZ+1]; */
+- const U64 * pu64) {
++printU64(char *buf, /* char [I64CHARSZ+1]; */
++ const U64 * pu64)
++{
+ U64 u64a;
+ U64 u64b;
+
+@@ -448,57 +399,37 @@ printU64(char *buf, /* char [I64CHARSZ+1]; */
+ unsigned int u;
+ int j;
+
+- u64a.high = pu64->high;
+- u64a.low = pu64->low;
++ u64a = *pu64;
+ aRes[I64CHARSZ] = 0;
+ for (j = 0; j < I64CHARSZ; j++) {
+ divBy10(u64a, &u64b, &u);
+ aRes[(I64CHARSZ - 1) - j] = (char) ('0' + u);
+- u64a.high = u64b.high;
+- u64a.low = u64b.low;
++ u64a = u64b;
+ if (isZeroU64(&u64a))
+ break;
+ }
+ strcpy(buf, &aRes[(I64CHARSZ - 1) - j]);
+ }
+
++/** Convert a signed 64-bit number to ASCII. */
+ void
+-printI64(char *buf, /* char [I64CHARSZ+1]; */
+- const U64 * pu64) {
++printI64(char *buf, /* char [I64CHARSZ+1]; */
++ const U64 * pu64)
++{
+ U64 u64a;
+- U64 u64b;
+-
+- char aRes[I64CHARSZ + 1];
+- unsigned int u;
+- int j, sign = 0;
+
+ if (pu64->high & 0x80000000) {
+- u64a.high = ~pu64->high;
+- u64a.low = ~pu64->low;
+- sign = 1;
++ u64a.high = (uint32_t) ~pu64->high;
++ u64a.low = (uint32_t) ~pu64->low;
+ incrByU32(&u64a, 1); /* bit invert and incr by 1 to print 2s complement */
++ buf[0] = '-';
++ printU64(buf + 1, &u64a);
+ } else {
+- u64a.high = pu64->high;
+- u64a.low = pu64->low;
+- }
+-
+- aRes[I64CHARSZ] = 0;
+- for (j = 0; j < I64CHARSZ; j++) {
+- divBy10(u64a, &u64b, &u);
+- aRes[(I64CHARSZ - 1) - j] = (char) ('0' + u);
+- u64a.high = u64b.high;
+- u64a.low = u64b.low;
+- if (isZeroU64(&u64a))
+- break;
+- }
+- if (sign == 1) {
+- aRes[(I64CHARSZ - 1) - j - 1] = '-';
+- strcpy(buf, &aRes[(I64CHARSZ - 1) - j - 1]);
+- return;
++ printU64(buf, pu64);
+ }
+- strcpy(buf, &aRes[(I64CHARSZ - 1) - j]);
+ }
+
++/** Convert a signed 64-bit integer from ASCII to U64. */
+ int
+ read64(U64 * i64, const char *str)
+ {
+@@ -517,75 +448,14 @@ read64(U64 * i64, const char *str)
+ ok = 1;
+ u = *str - '0';
+ multBy10(*i64, &i64p);
+- memcpy(i64, &i64p, sizeof(i64p));
++ *i64 = i64p;
+ incrByU16(i64, u);
+ str++;
+ }
+ if (sign) {
+- i64->high = ~i64->high;
+- i64->low = ~i64->low;
++ i64->high = (uint32_t) ~i64->high;
++ i64->low = (uint32_t) ~i64->low;
+ incrByU16(i64, 1);
+ }
+ return ok;
+ }
+-
+-
+-
+-
+-#ifdef TESTING
+-void
+-main(int argc, char *argv[])
+-{
+- int i;
+- int j;
+- int l;
+- unsigned int u;
+- U64 u64a;
+- U64 u64b;
+-#define MXSZ 20
+- char aRes[MXSZ + 1];
+-
+-
+- if (argc < 2) {
+- printf("This program takes numbers from the command line\n"
+- "and prints them out.\n" "Usage: test <unsignedInt>...\n");
+- exit(1);
+- }
+-
+- aRes[MXSZ] = 0;
+-
+- for (i = 1; i < argc; i++) {
+- l = strlen(argv[i]);
+- zeroU64(&u64a);
+- for (j = 0; j < l; j++) {
+- if (!isdigit(argv[i][j])) {
+- printf("Argument is not a number \"%s\"\n", argv[i]);
+- exit(1);
+- }
+- u = argv[i][j] - '0';
+- multBy10(u64a, &u64b);
+- u64a = u64b;
+- incrByU16(&u64a, u);
+- }
+-
+- printf("number \"%s\" in hex is '%08x%08x'h\n",
+- argv[i], u64a.high, u64a.low);
+-
+- printf("number is \"%s\"\n", printU64(&u64a));
+- for (j = 0; j < MXSZ; j++) {
+- divBy10(u64a, &u64b, &u);
+- aRes[(MXSZ - 1) - j] = (char) ('0' + u);
+- u64a = u64b;
+- if (isZeroU64(&u64a))
+- break;
+- }
+-
+- printf("number is \"%s\"\n", &aRes[(MXSZ - 1) - j]);
+- }
+- exit(0);
+-} /* main */
+-#endif /* TESTING */
+-
+-/*
+- * file: test.c
+- */
+diff --git a/snmplib/keytools.c b/snmplib/keytools.c
+index 810a063..0faa0de 100644
+--- a/snmplib/keytools.c
++++ b/snmplib/keytools.c
+@@ -118,13 +118,11 @@ generate_Ku(const oid * hashtype, u_int hashtype_len,
+ u_char buf[USM_LENGTH_KU_HASHBLOCK], *bufp;
+
+ #ifdef NETSNMP_USE_OPENSSL
+- EVP_MD_CTX *ctx = (EVP_MD_CTX *)malloc(sizeof(EVP_MD_CTX));
+- unsigned int tmp_len;
++ EVP_MD_CTX *ctx = NULL;
+ #elif NETSNMP_USE_INTERNAL_CRYPTO
+ SHA_CTX csha1;
+ MD5_CTX cmd5;
+ char cryptotype = 0;
+- unsigned int tmp_len;
+ #define TYPE_MD5 1
+ #define TYPE_SHA1 2
+ #else
+@@ -151,6 +149,12 @@ generate_Ku(const oid * hashtype, u_int hashtype_len,
+ */
+ #ifdef NETSNMP_USE_OPENSSL
+
++#ifdef HAVE_EVP_MD_CTX_CREATE
++ ctx = EVP_MD_CTX_create();
++#else
++ ctx = malloc(sizeof(*ctx));
++ EVP_MD_CTX_init(ctx);
++#endif
+ #ifndef NETSNMP_DISABLE_MD5
+ if (ISTRANSFORM(hashtype, HMACMD5Auth))
+ EVP_DigestInit(ctx, EVP_md5());
+@@ -158,10 +162,8 @@ generate_Ku(const oid * hashtype, u_int hashtype_len,
+ #endif
+ if (ISTRANSFORM(hashtype, HMACSHA1Auth))
+ EVP_DigestInit(ctx, EVP_sha1());
+- else {
+- free(ctx);
+- return (SNMPERR_GENERR);
+- }
++ else
++ QUITFUN(SNMPERR_GENERR, generate_Ku_quit);
+ #elif NETSNMP_USE_INTERNAL_CRYPTO
+ #ifndef NETSNMP_DISABLE_MD5
+ if (ISTRANSFORM(hashtype, HMACMD5Auth)) {
+@@ -205,14 +207,17 @@ generate_Ku(const oid * hashtype, u_int hashtype_len,
+ }
+
+ #ifdef NETSNMP_USE_OPENSSL
++ {
++ unsigned int tmp_len;
++
+ tmp_len = *kulen;
+ EVP_DigestFinal(ctx, (unsigned char *) Ku, &tmp_len);
+ *kulen = tmp_len;
+ /*
+ * what about free()
+ */
++ }
+ #elif NETSNMP_USE_INTERNAL_CRYPTO
+- tmp_len = *kulen;
+ if (TYPE_SHA1 == cryptotype) {
+ SHA1_Final(Ku, &csha1);
+ } else {
+@@ -248,7 +253,14 @@ generate_Ku(const oid * hashtype, u_int hashtype_len,
+ generate_Ku_quit:
+ memset(buf, 0, sizeof(buf));
+ #ifdef NETSNMP_USE_OPENSSL
+- free(ctx);
++ if (ctx) {
++#ifdef HAVE_EVP_MD_CTX_DESTROY
++ EVP_MD_CTX_destroy(ctx);
++#else
++ EVP_MD_CTX_cleanup(ctx);
++ free(ctx);
++#endif
++ }
+ #endif
+ return rval;
+
+@@ -638,7 +650,8 @@ decode_keychange(const oid * hashtype, u_int hashtype_len,
+
+ decode_keychange_quit:
+ if (rval != SNMPERR_SUCCESS) {
+- memset(newkey, 0, properlength);
++ if (newkey)
++ memset(newkey, 0, properlength);
+ }
+ memset(tmp_buf, 0, SNMP_MAXBUF);
+ SNMP_FREE(tmpbuf);
+diff --git a/snmplib/large_fd_set.c b/snmplib/large_fd_set.c
+index 1176a5b..32f57b3 100644
+--- a/snmplib/large_fd_set.c
++++ b/snmplib/large_fd_set.c
+@@ -19,7 +19,7 @@
+ #include <net-snmp/library/large_fd_set.h>
+
+
+-#if ! defined(cygwin) && defined(HAVE_WINSOCK_H)
++#if !defined(cygwin) && defined(HAVE_WINSOCK_H)
+
+ void
+ netsnmp_large_fd_setfd(SOCKET fd, netsnmp_large_fd_set * fdset)
+@@ -39,7 +39,7 @@ netsnmp_large_fd_setfd(SOCKET fd, netsnmp_large_fd_set * fdset)
+ if (i == fdset->lfs_set.fd_count
+ && fdset->lfs_set.fd_count < fdset->lfs_setsize) {
+ fdset->lfs_set.fd_count++;
+- fdset->lfs_set.fd_array[i] = (fd);
++ fdset->lfs_set.fd_array[i] = fd;
+ }
+ }
+
+@@ -51,7 +51,7 @@ netsnmp_large_fd_clr(SOCKET fd, netsnmp_large_fd_set * fdset)
+ netsnmp_assert(fd != INVALID_SOCKET);
+
+ for (i = 0; i < fdset->lfs_set.fd_count; i++) {
+- if (fdset->lfs_set.fd_array[i] == (fd)) {
++ if (fdset->lfs_set.fd_array[i] == fd) {
+ while (i < fdset->lfs_set.fd_count - 1) {
+ fdset->lfs_set.fd_array[i] =
+ fdset->lfs_set.fd_array[i + 1];
+@@ -95,7 +95,7 @@ netsnmp_large_fd_clr(int fd, netsnmp_large_fd_set * fdset)
+ {
+ netsnmp_assert(fd >= 0);
+
+- if (fd < (int)fdset->lfs_setsize)
++ if ((unsigned)fd < fdset->lfs_setsize)
+ FD_CLR(fd, fdset->lfs_setptr);
+ }
+
+@@ -104,7 +104,7 @@ netsnmp_large_fd_is_set(int fd, netsnmp_large_fd_set * fdset)
+ {
+ netsnmp_assert(fd >= 0);
+
+- return fd < (int)fdset->lfs_setsize && FD_ISSET(fd, fdset->lfs_setptr);
++ return (unsigned)fd < fdset->lfs_setsize && FD_ISSET(fd, fdset->lfs_setptr);
+ }
+
+ #endif
+@@ -114,6 +114,9 @@ netsnmp_large_fd_set_init(netsnmp_large_fd_set * fdset, int setsize)
+ {
+ fdset->lfs_setsize = 0;
+ fdset->lfs_setptr = NULL;
++#if !defined(cygwin) && defined(HAVE_WINSOCK_H)
++ fdset->lfs_set.fd_count = 0;
++#endif
+ netsnmp_large_fd_set_resize(fdset, setsize);
+ }
+
+@@ -135,25 +138,32 @@ netsnmp_large_fd_set_select(int numfds, netsnmp_large_fd_set *readfds,
+ /* Array representation: no resizing is necessary. */
+ #endif
+
+- return select(numfds, readfds->lfs_setptr, writefds->lfs_setptr,
+- exceptfds->lfs_setptr, timeout);
++ return select(numfds,
++ readfds ? readfds->lfs_setptr : NULL,
++ writefds ? writefds->lfs_setptr : NULL,
++ exceptfds ? exceptfds->lfs_setptr : NULL,
++ timeout);
+ }
+
+-void
++int
+ netsnmp_large_fd_set_resize(netsnmp_large_fd_set * fdset, int setsize)
+ {
+ int fd_set_bytes;
+
+ if (fdset->lfs_setsize == setsize)
+- return;
++ goto success;
+
+ if (setsize > FD_SETSIZE) {
+ fd_set_bytes = NETSNMP_FD_SET_BYTES(setsize);
+- if (fdset->lfs_setsize > FD_SETSIZE)
+- fdset->lfs_setptr = (fd_set *)realloc(fdset->lfs_setptr, fd_set_bytes);
+- else {
+- fdset->lfs_setptr = (fd_set *)malloc(fd_set_bytes);
+- *fdset->lfs_setptr = fdset->lfs_set;
++ if (fdset->lfs_setsize > FD_SETSIZE) {
++ fdset->lfs_setptr = realloc(fdset->lfs_setptr, fd_set_bytes);
++ if (!fdset->lfs_setptr)
++ goto out_of_mem;
++ } else {
++ fdset->lfs_setptr = malloc(fd_set_bytes);
++ if (!fdset->lfs_setptr)
++ goto out_of_mem;
++ *fdset->lfs_setptr = fdset->lfs_set;
+ }
+ } else {
+ if (fdset->lfs_setsize > FD_SETSIZE) {
+@@ -163,20 +173,33 @@ netsnmp_large_fd_set_resize(netsnmp_large_fd_set * fdset, int setsize)
+ fdset->lfs_setptr = &fdset->lfs_set;
+ }
+
+-#if ! (! defined(cygwin) && defined(HAVE_WINSOCK_H))
++#if defined(cygwin) || !defined(HAVE_WINSOCK_H)
+ {
+ int i;
+
+- /*
+- * Unix: clear the file descriptors defined in the resized *fdset
+- * but that were not defined in the original *fdset.
+- */
+- for (i = fdset->lfs_setsize; i < setsize; i++)
+- FD_CLR(i, fdset->lfs_setptr);
++ /*
++ * Unix: when enlarging, clear the file descriptors defined in the
++ * resized *fdset but that were not defined in the original *fdset.
++ */
++ for (i = fdset->lfs_setsize; i < setsize; i++)
++ FD_CLR(i, fdset->lfs_setptr);
+ }
+ #endif
+
+ fdset->lfs_setsize = setsize;
++#if !defined(cygwin) && defined(HAVE_WINSOCK_H)
++ if (setsize < fdset->lfs_set.fd_count)
++ fdset->lfs_set.fd_count = setsize;
++#endif
++success:
++ return 1;
++
++out_of_mem:
++ fdset->lfs_setsize = 0;
++#if !defined(cygwin) && defined(HAVE_WINSOCK_H)
++ fdset->lfs_set.fd_count = 0;
++#endif
++ return 0;
+ }
+
+ void
+@@ -207,13 +230,13 @@ netsnmp_copy_large_fd_set_to_fd_set(fd_set * dst,
+
+ *dst = *src->lfs_setptr;
+
+-#if ! (! defined(cygwin) && defined(HAVE_WINSOCK_H))
++#if !(!defined(cygwin) && defined(HAVE_WINSOCK_H))
+ {
+ int i;
+
+- /* Unix: clear any file descriptors defined in *dst but not in *src. */
+- for (i = src->lfs_setsize; i < FD_SETSIZE; ++i)
+- FD_CLR(i, dst);
++ /* Unix: clear any file descriptors defined in *dst but not in *src. */
++ for (i = src->lfs_setsize; i < FD_SETSIZE; ++i)
++ FD_CLR(i, dst);
+ }
+ #endif
+
+diff --git a/snmplib/mib.c b/snmplib/mib.c
+index 7c8af9c..549d206 100644
+--- a/snmplib/mib.c
++++ b/snmplib/mib.c
+@@ -462,7 +462,7 @@ sprint_realloc_octet_string(u_char ** buf, size_t * buf_len,
+ const char *saved_hint = hint;
+ int hex = 0, x = 0;
+ u_char *cp;
+- int output_format, len_needed;
++ int output_format, cnt;
+
+ if ((var->type != ASN_OCTET_STR) &&
+ (!netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICKE_PRINT))) {
+@@ -571,18 +571,11 @@ sprint_realloc_octet_string(u_char ** buf, size_t * buf_len,
+ break;
+ case 't': /* new in rfc 3411 */
+ case 'a':
+- /* A string hint gives the max size - we may not need this much */
+- len_needed = SNMP_MIN( width, ecp-cp );
+- while ((*out_len + len_needed + 1) >= *buf_len) {
+- if (!(allow_realloc && snmp_realloc(buf, buf_len))) {
+- return 0;
+- }
+- }
+- for (x = 0; x < width && cp < ecp; x++) {
+- *(*buf + *out_len) = *cp++;
+- (*out_len)++;
+- }
+- *(*buf + *out_len) = '\0';
++ cnt = SNMP_MIN(width, ecp - cp);
++ if (!sprint_realloc_asciistring(buf, buf_len, out_len,
++ allow_realloc, cp, cnt))
++ return 0;
++ cp += cnt;
+ break;
+ default:
+ *out_len = saved_out_len;
+@@ -2800,6 +2793,8 @@ netsnmp_mibindex_load( void )
+ get_persistent_directory(), i );
+ tmpbuf[sizeof(tmpbuf)-1] = 0;
+ fp = fopen( tmpbuf, "r" );
++ if (!fp)
++ continue;
+ cp = fgets( tmpbuf2, sizeof(tmpbuf2), fp );
+ if ( !cp ) {
+ DEBUGMSGTL(("mibindex", "Empty MIB index (%d)\n", i));
+@@ -3057,14 +3052,11 @@ read_objid(const char *input, oid * output, size_t * out_len)
+ * get past leading '.', append '.' to Prefix.
+ */
+ if (*Prefix == '.')
+- strncpy(buf, Prefix + 1, sizeof(buf)-1);
++ strlcpy(buf, Prefix + 1, sizeof(buf));
+ else
+- strncpy(buf, Prefix, sizeof(buf)-1);
+- buf[ sizeof(buf)-1 ] = 0;
+- strcat(buf, ".");
+- buf[ sizeof(buf)-1 ] = 0;
+- strncat(buf, input, sizeof(buf)-strlen(buf));
+- buf[ sizeof(buf)-1 ] = 0;
++ strlcpy(buf, Prefix, sizeof(buf));
++ strlcat(buf, ".", sizeof(buf));
++ strlcat(buf, input, sizeof(buf));
+ input = buf;
+ }
+ #endif /* NETSNMP_DISABLE_MIB_LOADING */
+@@ -5106,8 +5098,7 @@ print_tree_node(u_char ** buf, size_t * buf_len,
+ else
+ if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc, ", "))
+ return 0;
+- snprintf(str, sizeof(str), "%s", vp->vblabel);
+- str[ sizeof(str)-1 ] = 0;
++ strlcpy(str, vp->vblabel, sizeof(str));
+ len = strlen(str);
+ if (pos + len + 2 > width) {
+ if (!snmp_cstrcat(buf, buf_len, out_len, allow_realloc,
+@@ -5720,8 +5711,7 @@ get_node(const char *name, oid * objid, size_t * objidlen)
+ module = (char *) malloc((size_t) (cp - name + 1));
+ if (!module)
+ return SNMPERR_GENERR;
+- memcpy(module, name, (size_t) (cp - name));
+- module[cp - name] = 0;
++ sprintf(module, "%.*s", (int) (cp - name), name);
+ cp++; /* cp now point to the subidentifier */
+ if (*cp == ':')
+ cp++;
+diff --git a/snmplib/oid_stash.c b/snmplib/oid_stash.c
+index 02c53a9..8a79897 100644
+--- a/snmplib/oid_stash.c
++++ b/snmplib/oid_stash.c
+@@ -305,6 +305,8 @@ netsnmp_oid_stash_get_data(netsnmp_oid_stash_node *root,
+ }
+ #endif /* NETSNMP_FEATURE_REMOVE_OID_STASH_GET_DATA */
+
++netsnmp_feature_child_of(oid_stash_store_all, oid_stash_all)
++#ifndef NETSNMP_FEATURE_REMOVE_OID_STASH_STORE_ALL
+ /** a wrapper around netsnmp_oid_stash_store for use with a snmp_alarm.
+ * when calling snmp_alarm, you can list this as a callback. The
+ * clientarg should be a pointer to a netsnmp_oid_stash_save_info
+@@ -316,8 +318,6 @@ netsnmp_oid_stash_get_data(netsnmp_oid_stash_node *root,
+ * @param serverarg
+ * @param clientarg A pointer to a netsnmp_oid_stash_save_info structure.
+ */
+-netsnmp_feature_child_of(oid_stash_store_all, oid_stash_all)
+-#ifndef NETSNMP_FEATURE_REMOVE_OID_STASH_STORE_ALL
+ int
+ netsnmp_oid_stash_store_all(int majorID, int minorID,
+ void *serverarg, void *clientarg) {
+diff --git a/snmplib/openssl/openssl_cfb128.c b/snmplib/openssl/openssl_cfb128.c
+index 7e78905..5e0bc1e 100644
+--- a/snmplib/openssl/openssl_cfb128.c
++++ b/snmplib/openssl/openssl_cfb128.c
+@@ -98,7 +98,7 @@ void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+ (*block)(ivec, ivec, key);
+ for (n=0; n<16; n+=sizeof(size_t)) {
+ *(size_t*)(out+n) =
+- *(size_t*)(ivec+n) ^= *(size_t*)(in+n);
++ *(size_t*)(ivec+n) ^= *(const size_t*)(in+n);
+ }
+ len -= 16;
+ out += 16;
+@@ -142,8 +142,8 @@ void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
+ while (len>=16) {
+ (*block)(ivec, ivec, key);
+ for (n=0; n<16; n+=sizeof(size_t)) {
+- size_t t = *(size_t*)(in+n);
+- *(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;
++ size_t t = *(const size_t*)(in+n);
++ *(size_t*)(out+n) = *(const size_t*)(ivec+n) ^ t;
+ *(size_t*)(ivec+n) = t;
+ }
+ len -= 16;
+diff --git a/snmplib/parse.c b/snmplib/parse.c
+index bfe5cad..1114586 100644
+--- a/snmplib/parse.c
++++ b/snmplib/parse.c
+@@ -2021,11 +2021,19 @@ parse_objectid(FILE * fp, char *name)
+ * The name for this node is the label for this entry
+ */
+ np->label = strdup(name);
++ if (np->label == NULL) {
++ SNMP_FREE(np->parent);
++ SNMP_FREE(np);
++ return (NULL);
++ }
+ } else {
+ if (!nop->label) {
+ nop->label = (char *) malloc(20 + ANON_LEN);
+- if (nop->label == NULL)
++ if (nop->label == NULL) {
++ SNMP_FREE(np->parent);
++ SNMP_FREE(np);
+ return (NULL);
++ }
+ sprintf(nop->label, "%s%d", ANON, anonymous++);
+ }
+ np->label = strdup(nop->label);
+@@ -2694,29 +2702,12 @@ parse_objecttype(FILE * fp, char *name)
+ break;
+ else if (type == LEFTBRACKET)
+ level++;
+- if (type == QUOTESTRING) {
+- if (strlen(defbuf)+2 < sizeof(defbuf)) {
+- defbuf[ strlen(defbuf)+2 ] = 0;
+- defbuf[ strlen(defbuf)+1 ] = '"';
+- defbuf[ strlen(defbuf) ] = '\\';
+- }
+- defbuf[ sizeof(defbuf)-1 ] = 0;
+- }
+- strncat(defbuf, quoted_string_buffer,
+- sizeof(defbuf)-strlen(defbuf)-1);
+- defbuf[ sizeof(defbuf)-1 ] = 0;
+- if (type == QUOTESTRING) {
+- if (strlen(defbuf)+2 < sizeof(defbuf)) {
+- defbuf[ strlen(defbuf)+2 ] = 0;
+- defbuf[ strlen(defbuf)+1 ] = '"';
+- defbuf[ strlen(defbuf) ] = '\\';
+- }
+- defbuf[ sizeof(defbuf)-1 ] = 0;
+- }
+- if (strlen(defbuf)+1 < sizeof(defbuf)) {
+- defbuf[ strlen(defbuf)+1 ] = 0;
+- defbuf[ strlen(defbuf) ] = ' ';
+- }
++ if (type == QUOTESTRING)
++ strlcat(defbuf, "\\\"", sizeof(defbuf));
++ strlcat(defbuf, quoted_string_buffer, sizeof(defbuf));
++ if (type == QUOTESTRING)
++ strlcat(defbuf, "\\\"", sizeof(defbuf));
++ strlcat(defbuf, " ", sizeof(defbuf));
+ }
+
+ if (type != RIGHTBRACKET) {
+@@ -3910,6 +3901,9 @@ read_module_internal(const char *name)
+ snmp_log_perror(mp->file);
+ return rval;
+ }
++#ifdef HAVE_FLOCKFILE
++ flockfile(fp);
++#endif
+ mp->no_imports = 0; /* Note that we've read the file */
+ File = mp->file;
+ mibLine = 1;
+@@ -3918,6 +3912,9 @@ read_module_internal(const char *name)
+ * Parse the file
+ */
+ np = parse(fp, NULL);
++#ifdef HAVE_FUNLOCKFILE
++ funlockfile(fp);
++#endif
+ fclose(fp);
+ File = oldFile;
+ mibLine = oldLine;
+@@ -4400,8 +4397,7 @@ parse(FILE * fp, struct node *root)
+ case ENDOFFILE:
+ continue;
+ default:
+- strncpy(name, token, sizeof(name));
+- name[sizeof(name)-1] = '\0';
++ strlcpy(name, token, sizeof(name));
+ type = get_token(fp, token, MAXTOKEN);
+ nnp = NULL;
+ if (type == MACRO) {
+@@ -4419,8 +4415,7 @@ parse(FILE * fp, struct node *root)
+ print_error(name, "is a reserved word", lasttype);
+ continue; /* see if we can parse the rest of the file */
+ }
+- strncpy(name, token, sizeof(name));
+- name[sizeof(name)-1] = '\0';
++ strlcpy(name, token, sizeof(name));
+ type = get_token(fp, token, MAXTOKEN);
+ nnp = NULL;
+
+@@ -4610,6 +4605,21 @@ is_labelchar(int ich)
+ return 0;
+ }
+
++/**
++ * Read a single character from a file. Assumes that the caller has invoked
++ * flockfile(). Uses fgetc_unlocked() instead of getc() since the former is
++ * implemented as an inline function in glibc. See also bug 3447196
++ * (http://sourceforge.net/tracker/?func=detail&aid=3447196&group_id=12694&atid=112694).
++ */
++static int netsnmp_getc(FILE *stream)
++{
++#ifdef HAVE_FGETC_UNLOCKED
++ return fgetc_unlocked(stream);
++#else
++ return getc(stream);
++#endif
++}
++
+ /*
+ * Parses a token from the file. The type of the token parsed is returned,
+ * and the text is placed in the string pointed to by token.
+@@ -4629,7 +4639,7 @@ get_token(FILE * fp, char *token, int maxtlen)
+ * skip all white space
+ */
+ do {
+- ch = getc(fp);
++ ch = netsnmp_getc(fp);
+ if (ch == '\n')
+ mibLine++;
+ }
+@@ -4643,7 +4653,7 @@ get_token(FILE * fp, char *token, int maxtlen)
+ return parseQuoteString(fp, token, maxtlen);
+ case '\'': /* binary or hex constant */
+ seenSymbols = bdigits;
+- while ((ch = getc(fp)) != EOF && ch != '\'') {
++ while ((ch = netsnmp_getc(fp)) != EOF && ch != '\'') {
+ switch (seenSymbols) {
+ case bdigits:
+ if (ch == '0' || ch == '1')
+@@ -4662,7 +4672,7 @@ get_token(FILE * fp, char *token, int maxtlen)
+ if (ch == '\'') {
+ unsigned long val = 0;
+ char *run = token + 1;
+- ch = getc(fp);
++ ch = netsnmp_getc(fp);
+ switch (ch) {
+ case EOF:
+ return ENDOFFILE;
+@@ -4721,25 +4731,25 @@ get_token(FILE * fp, char *token, int maxtlen)
+ case '|':
+ return BAR;
+ case '.':
+- ch_next = getc(fp);
++ ch_next = netsnmp_getc(fp);
+ if (ch_next == '.')
+ return RANGE;
+ ungetc(ch_next, fp);
+ return LABEL;
+ case ':':
+- ch_next = getc(fp);
++ ch_next = netsnmp_getc(fp);
+ if (ch_next != ':') {
+ ungetc(ch_next, fp);
+ return LABEL;
+ }
+- ch_next = getc(fp);
++ ch_next = netsnmp_getc(fp);
+ if (ch_next != '=') {
+ ungetc(ch_next, fp);
+ return LABEL;
+ }
+ return EQUALS;
+ case '-':
+- ch_next = getc(fp);
++ ch_next = netsnmp_getc(fp);
+ if (ch_next == '-') {
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_MIB_COMMENT_TERM)) {
+@@ -4747,7 +4757,7 @@ get_token(FILE * fp, char *token, int maxtlen)
+ * Treat the rest of this line as a comment.
+ */
+ while ((ch_next != EOF) && (ch_next != '\n'))
+- ch_next = getc(fp);
++ ch_next = netsnmp_getc(fp);
+ } else {
+ /*
+ * Treat the rest of the line or until another '--' as a comment
+@@ -4756,11 +4766,11 @@ get_token(FILE * fp, char *token, int maxtlen)
+ * (this is the "technically" correct way to parse comments)
+ */
+ ch = ' ';
+- ch_next = getc(fp);
++ ch_next = netsnmp_getc(fp);
+ while (ch_next != EOF && ch_next != '\n' &&
+ (ch != '-' || ch_next != '-')) {
+ ch = ch_next;
+- ch_next = getc(fp);
++ ch_next = netsnmp_getc(fp);
+ }
+ }
+ if (ch_next == EOF)
+@@ -4770,6 +4780,7 @@ get_token(FILE * fp, char *token, int maxtlen)
+ return get_token(fp, token, maxtlen);
+ }
+ ungetc(ch_next, fp);
++ /* fallthrough */
+ default:
+ /*
+ * Accumulate characters until end of token is found. Then attempt to
+@@ -4780,7 +4791,7 @@ get_token(FILE * fp, char *token, int maxtlen)
+ return LABEL;
+ hash += tolower(ch);
+ more:
+- while (is_labelchar(ch_next = getc(fp))) {
++ while (is_labelchar(ch_next = netsnmp_getc(fp))) {
+ hash += tolower(ch_next);
+ if (cp - token < maxtlen - 1)
+ *cp++ = ch_next;
+@@ -4799,7 +4810,7 @@ get_token(FILE * fp, char *token, int maxtlen)
+ if (tp) {
+ if (tp->token != CONTINUE)
+ return (tp->token);
+- while (isspace((ch_next = getc(fp))))
++ while (isspace((ch_next = netsnmp_getc(fp))))
+ if (ch_next == '\n')
+ mibLine++;
+ if (ch_next == EOF)
+@@ -4846,7 +4857,10 @@ add_mibfile(const char* tmpstr, const char* d_name, FILE *ip )
+ tmpstr));
+ mibLine = 1;
+ File = tmpstr;
+- get_token(fp, token, MAXTOKEN);
++ if (get_token(fp, token, MAXTOKEN) != LABEL) {
++ fclose(fp);
++ return 1;
++ }
+ /*
+ * simple test for this being a MIB
+ */
+@@ -4984,7 +4998,11 @@ read_mib(const char *filename)
+ mibLine = 1;
+ File = filename;
+ DEBUGMSGTL(("parse-mibs", "Parsing file: %s...\n", filename));
+- get_token(fp, token, MAXTOKEN);
++ if (get_token(fp, token, MAXTOKEN) != LABEL) {
++ snmp_log(LOG_ERR, "Failed to parse MIB file %s\n", filename);
++ fclose(fp);
++ return NULL;
++ }
+ fclose(fp);
+ new_module(token, filename);
+ (void) netsnmp_read_module(token);
+@@ -5055,7 +5073,7 @@ parseQuoteString(FILE * fp, char *token, int maxtlen)
+ int too_long = 0;
+ char *token_start = token;
+
+- for (ch = getc(fp); ch != EOF; ch = getc(fp)) {
++ for (ch = netsnmp_getc(fp); ch != EOF; ch = netsnmp_getc(fp)) {
+ if (ch == '\r')
+ continue;
+ if (ch == '\n') {
+diff --git a/snmplib/read_config.c b/snmplib/read_config.c
+index 5c5268b..2443230 100644
+--- a/snmplib/read_config.c
++++ b/snmplib/read_config.c
+@@ -180,8 +180,8 @@ internal_register_config_handler(const char *type_param,
+ struct config_line *ltmp2 = NULL;
+ char buf[STRINGMAX];
+ char *cptr = buf;
+- strncpy(buf, type, STRINGMAX - 1);
+- buf[STRINGMAX - 1] = '\0';
++
++ strlcpy(buf, type, STRINGMAX);
+ while (cptr) {
+ char* c = cptr;
+ cptr = strchr(cptr, ':');
+@@ -366,8 +366,8 @@ unregister_config_handler(const char *type_param, const char *token)
+ if (strchr(type, ':')) {
+ char buf[STRINGMAX];
+ char *cptr = buf;
+- strncpy(buf, type, STRINGMAX - 1);
+- buf[STRINGMAX - 1] = '\0';
++
++ strlcpy(buf, type, STRINGMAX);
+ while (cptr) {
+ char* c = cptr;
+ cptr = strchr(cptr, ':');
+@@ -582,10 +582,13 @@ snmp_config_when(char *line, int when)
+ return SNMPERR_GENERR;
+ }
+
+- strncpy(buf, line, STRINGMAX);
+- buf[STRINGMAX - 1] = '\0';
++ strlcpy(buf, line, STRINGMAX);
+ cptr = strtok_r(buf, SNMP_CONFIG_DELIMETERS, &st);
+- if (cptr && cptr[0] == '[') {
++ if (!cptr) {
++ netsnmp_config_warn("Wrong format: %s", line);
++ return SNMPERR_GENERR;
++ }
++ if (cptr[0] == '[') {
+ if (cptr[strlen(cptr) - 1] != ']') {
+ netsnmp_config_error("no matching ']' for type %s.", cptr + 1);
+ return SNMPERR_GENERR;
+@@ -887,15 +890,15 @@ read_config(const char *filename,
+ continue;
+ }
+ if ( cptr[0] == '/' ) {
+- strncpy(fname, cptr, SNMP_MAXPATH);
+- fname[SNMP_MAXPATH-1]='\0';
++ strlcpy(fname, cptr, SNMP_MAXPATH);
+ } else {
+- strncpy(fname, filename, SNMP_MAXPATH);
+- fname[SNMP_MAXPATH-1]='\0';
++ strlcpy(fname, filename, SNMP_MAXPATH);
+ cp = strrchr(fname, '/');
+- *(++cp) = '\0';
+- strncat(fname, cptr, SNMP_MAXPATH-strlen(fname));
+- fname[SNMP_MAXPATH-1]='\0';
++ if (!cp)
++ fname[0] = '\0';
++ else
++ *(++cp) = '\0';
++ strlcat(fname, cptr, SNMP_MAXPATH);
+ }
+ prev_filename = curfilename;
+ prev_linecount = linecount;
+@@ -2320,210 +2323,3 @@ read_config_store_data_prefix(char prefix, int type, char *storeto,
+ }
+
+ /** @} */
+-
+-#ifdef READ_CONFIG_UNIT_TEST
+-
+-#define NETSNMP_USE_ASSERT 1
+-#include <net-snmp/libary/snmp_assert.h>
+-
+-int
+-read64(U64 * i64, const char *str)
+-{
+- netsnmp_assert(0);
+-}
+-
+-int
+-snmp_get_do_debugging(void)
+-{
+- return 0;
+-}
+-
+-int
+-debug_is_token_registered(const char *token)
+-{
+- netsnmp_assert(0);
+-}
+-
+-void
+-debugmsg(const char *token, const char *format, ...)
+-{
+- netsnmp_assert(0);
+-}
+-
+-void
+-debugmsgtoken(const char *token, const char *format, ...)
+-{
+- netsnmp_assert(0);
+-}
+-
+-int
+-snmp_log(int priority, const char *format, ...)
+-{
+-#if 0
+- va_list ap;
+-
+- va_start(ap, format);
+- vprintf(format, ap);
+- va_end(ap);
+-#endif
+- return 0;
+-}
+-
+-void
+-snmp_log_perror(const char *s)
+-{
+- netsnmp_assert(0);
+-}
+-
+-int
+-snmp_vlog(int priority, const char *format, va_list ap)
+-{
+- netsnmp_assert(0);
+-}
+-
+-int
+-netsnmp_ds_set_boolean(int storeid, int which, int value)
+-{
+- netsnmp_assert(0);
+-}
+-
+-int
+-netsnmp_ds_get_boolean(int storeid, int which)
+-{
+- netsnmp_assert(0);
+-}
+-
+-int
+-netsnmp_ds_set_string(int storeid, int which, const char *value)
+-{
+- netsnmp_assert(0);
+-}
+-
+-char *
+-netsnmp_ds_get_string(int storeid, int which)
+-{
+- netsnmp_assert(0);
+-}
+-
+-char *
+-netsnmp_getenv(const char *name)
+-{
+- netsnmp_assert(0);
+-}
+-
+-int
+-snmp_call_callbacks(int major, int minor, void *caller_arg)
+-{
+- netsnmp_assert(0);
+-}
+-
+-int
+-mkdirhier(const char *pathname, mode_t mode, int skiplast)
+-{
+- netsnmp_assert(0);
+-}
+-
+-int
+-read_objid(const char *input, oid * output, size_t * out_len)
+-{
+- netsnmp_assert(0);
+-}
+-
+-struct read_config_testcase {
+- /*
+- * inputs
+- */
+- const char *(*pf) (const char * readfrom, u_char ** str,
+- size_t * len);
+- const char *readfrom;
+- size_t obuf_len;
+-
+- /*
+- * expected outputs
+- */
+- size_t expected_offset;
+- const u_char *expected_output;
+- size_t expected_len;
+-};
+-
+-static const u_char obuf1[] = { 1, 0, 2 };
+-static const u_char obuf2[] = { 'a', 'b', 'c', 0 };
+-static const u_char obuf3[] = { 1, 3, 2 };
+-
+-static const struct read_config_testcase test_input[] = {
+- { &read_config_read_octet_string_const, "", 1, -1, NULL, 0 },
+- { &read_config_read_octet_string_const, "0x0", 1, -1, NULL, 1 },
+- { &read_config_read_octet_string_const, "0x0 0", 1, -1, NULL, 1 },
+-
+- { &read_config_read_octet_string_const, "0x010002", 1, -1, NULL, 0 },
+- { &read_config_read_octet_string_const, "0x010002", 2, -1, NULL, 0 },
+- { &read_config_read_octet_string_const, "0x010002", 3, -1, obuf1, 0 },
+- { &read_config_read_octet_string_const, "0x010002", 4, -1, obuf1, 3 },
+- { &read_config_read_octet_string_const, "0x010002 0", 4, 9, obuf1, 3 },
+- { &read_config_read_octet_string_const, "0x010002", 0, -1, obuf1, 3 },
+-
+- { &read_config_read_octet_string_const, "abc", 1, -1, NULL, 0 },
+- { &read_config_read_octet_string_const, "abc z", 1, 4, NULL, 0 },
+- { &read_config_read_octet_string_const, "abc", 2, -1, NULL, 1 },
+- { &read_config_read_octet_string_const, "abc", 3, -1, obuf2, 2 },
+- { &read_config_read_octet_string_const, "abc", 4, -1, obuf2, 3 },
+- { &read_config_read_octet_string_const, "abc z", 4, 4, obuf2, 3 },
+- { &read_config_read_octet_string_const, "abc", 0, -1, obuf2, 3 },
+-};
+-
+-int
+-main(int argc, char **argv)
+-{
+- int failure_count = 0;
+- unsigned int i, j;
+-
+- printf("Start of unit test.\n");
+- for (i = 0; i < sizeof(test_input) / sizeof(test_input[0]); i++) {
+- const struct read_config_testcase *const p = &test_input[i];
+- size_t len = p->obuf_len;
+- u_char *str = len > 0 ? malloc(len) : NULL;
+- const char *result;
+- size_t offset;
+-
+- printf("Test %d ...\n", i);
+- fflush(stdout);
+- result = (p->pf) (p->readfrom, &str, &len);
+- offset = result ? result - p->readfrom : -1;
+- if (offset != p->expected_offset) {
+- failure_count++;
+- printf("test %d: expected offset %zd, got offset %" NETSNMP_PRIz "d\n",
+- i, p->expected_offset, offset);
+- } else if (len != p->expected_len) {
+- failure_count++;
+- printf("test %d: expected length %d, got length %d\n",
+- i, p->expected_len, len);
+- } else if (len >= 0 && p->expected_output
+- && memcmp(str, p->expected_output, len) != 0
+- && p->expected_output[len] == 0) {
+- failure_count++;
+- printf("test %d: output buffer mismatch\n", i);
+- printf("Expected: ");
+- for (j = 0; j < p->expected_len; ++j)
+- printf("%02x ", p->expected_output[j]);
+- printf("\nActual: ");
+- for (j = 0; j < len; ++j)
+- printf("%02x ", str[j]);
+- printf("\n");
+- }
+-
+- if (str)
+- free(str);
+- }
+- if (failure_count == 0)
+- printf("All %d tests passed.\n", i);
+- return 0;
+-}
+-#endif /* READ_CONFIG_UNIT_TEST */
+-
+-/*
+- * Local variables:
+- * c-basic-offset: 4
+- * indent-tabs-mode: nil
+- * compile-command: "gcc -Wall -Werror -DREAD_CONFIG_UNIT_TEST=1 -O1 -I../include -g -o read_config-unit-test read_config.c && ./read_config-unit-test && valgrind --leak-check=full ./read_config-unit-test"
+- * End:
+- */
+diff --git a/snmplib/scapi.c b/snmplib/scapi.c
+index a397344..fdd33ff 100644
+--- a/snmplib/scapi.c
++++ b/snmplib/scapi.c
+@@ -116,12 +116,12 @@ netsnmp_feature_child_of(usm_scapi, usm_support)
+
+ #ifdef NETSNMP_USE_INTERNAL_CRYPTO
+ static
+-int SHA1_hmac(u_char * data, size_t len, u_char * mac, size_t maclen,
+- u_char * secret, size_t secretlen);
++int SHA1_hmac(const u_char * data, size_t len, u_char * mac, size_t maclen,
++ const u_char * secret, size_t secretlen);
+
+ static
+-int MD5_hmac(u_char * data, size_t len, u_char * mac, size_t maclen,
+- u_char * secret, size_t secretlen);
++int MD5_hmac(const u_char * data, size_t len, u_char * mac, size_t maclen,
++ const u_char * secret, size_t secretlen);
+ #endif
+
+ /*
+@@ -454,7 +454,7 @@ sc_hash(const oid * hashtype, size_t hashtypelen, const u_char * buf,
+
+ #ifdef NETSNMP_USE_OPENSSL
+ const EVP_MD *hashfn;
+- EVP_MD_CTX ctx, *cptr;
++ EVP_MD_CTX *cptr;
+ #endif
+ #ifdef NETSNMP_USE_INTERNAL_CRYPTO
+ MD5_CTX cmd5;
+@@ -485,42 +485,32 @@ sc_hash(const oid * hashtype, size_t hashtypelen, const u_char * buf,
+ }
+
+ /** initialize the pointer */
+- memset(&ctx, 0, sizeof(ctx));
+- cptr = &ctx;
++#ifdef HAVE_EVP_MD_CTX_CREATE
++ cptr = EVP_MD_CTX_create();
++#else
++ cptr = malloc(sizeof(*cptr));
+ #if defined(OLD_DES)
+- EVP_DigestInit(cptr, hashfn);
+-#else /* !OLD_DES */
+- /* this is needed if the runtime library is different than the compiled
+- library since the openssl versions are very different. */
+- if (SSLeay() < 0x907000) {
+- /* the old version of the struct was bigger and thus more
+- memory is needed. should be 152, but we use 256 for safety. */
+- cptr = (EVP_MD_CTX *)malloc(256);
+- EVP_DigestInit(cptr, hashfn);
+- } else {
+- EVP_MD_CTX_init(cptr);
+- EVP_DigestInit(cptr, hashfn);
+- }
++ memset(cptr, 0, sizeof(*cptr));
++#else
++ EVP_MD_CTX_init(cptr);
++#endif
+ #endif
++ EVP_DigestInit(cptr, hashfn);
+
+ /** pass the data */
+ EVP_DigestUpdate(cptr, buf, buf_len);
+
+ /** do the final pass */
+-#if defined(OLD_DES)
+ EVP_DigestFinal(cptr, MAC, &tmp_len);
+ *MAC_len = tmp_len;
+-#else /* !OLD_DES */
+- if (SSLeay() < 0x907000) {
+- EVP_DigestFinal(cptr, MAC, &tmp_len);
+- *MAC_len = tmp_len;
+- free(cptr);
+- } else {
+- EVP_DigestFinal_ex(cptr, MAC, &tmp_len);
+- *MAC_len = tmp_len;
+- EVP_MD_CTX_cleanup(cptr);
+- }
+-#endif /* OLD_DES */
++#ifdef HAVE_EVP_MD_CTX_DESTROY
++ EVP_MD_CTX_destroy(cptr);
++#else
++#if !defined(OLD_DES)
++ EVP_MD_CTX_cleanup(cptr);
++#endif
++ free(cptr);
++#endif
+ return (rval);
+
+ #elif NETSNMP_USE_INTERNAL_CRYPTO
+@@ -1171,8 +1161,8 @@ sc_decrypt(const oid * privtype, size_t privtypelen,
+ * of data, and prepended with a secret in the standard fashion
+ */
+ static int
+-MD5_hmac(u_char * data, size_t len, u_char * mac, size_t maclen,
+- u_char * secret, size_t secretlen)
++MD5_hmac(const u_char * data, size_t len, u_char * mac, size_t maclen,
++ const u_char * secret, size_t secretlen)
+ {
+ #define MD5_HASHKEYLEN 64
+ #define MD5_SECRETKEYLEN 16
+@@ -1183,7 +1173,8 @@ MD5_hmac(u_char * data, size_t len, u_char * mac, size_t maclen,
+ u_char extendedAuthKey[MD5_HASHKEYLEN];
+ u_char buf[MD5_HASHKEYLEN];
+ size_t i;
+- u_char *cp, *newdata = NULL;
++ const u_char *cp;
++ u_char *newdata = NULL;
+ int rc = 0;
+
+ /*
+@@ -1268,8 +1259,8 @@ MD5_hmac(u_char * data, size_t len, u_char * mac, size_t maclen,
+ }
+
+ static int
+-SHA1_hmac(u_char * data, size_t len, u_char * mac, size_t maclen,
+- u_char * secret, size_t secretlen)
++SHA1_hmac(const u_char * data, size_t len, u_char * mac, size_t maclen,
++ const u_char * secret, size_t secretlen)
+ {
+ #define SHA1_HASHKEYLEN 64
+ #define SHA1_SECRETKEYLEN 20
+@@ -1280,7 +1271,8 @@ SHA1_hmac(u_char * data, size_t len, u_char * mac, size_t maclen,
+ u_char extendedAuthKey[SHA1_HASHKEYLEN];
+ u_char buf[SHA1_HASHKEYLEN];
+ size_t i;
+- u_char *cp, *newdata = NULL;
++ const u_char *cp;
++ u_char *newdata = NULL;
+ int rc = 0;
+
+ /*
+diff --git a/snmplib/snmp-tc.c b/snmplib/snmp-tc.c
+index 3b73da2..891c3a0 100644
+--- a/snmplib/snmp-tc.c
++++ b/snmplib/snmp-tc.c
+@@ -163,7 +163,7 @@ date_n_time(const time_t * when, size_t * length)
+ string[7] = 0;
+ *length = 8;
+
+-#ifndef cygwin
++#if defined(HAVE_STRUCT_TM_TM_GMTOFF) || defined(HAVE_TIMEZONE_VARIABLE)
+ /*
+ * Timezone offset
+ */
+diff --git a/snmplib/snmp_alarm.c b/snmplib/snmp_alarm.c
+index adfa93d..dc498cc 100644
+--- a/snmplib/snmp_alarm.c
++++ b/snmplib/snmp_alarm.c
+@@ -82,23 +82,22 @@ init_snmp_alarm(void)
+ void
+ sa_update_entry(struct snmp_alarm *a)
+ {
+- if (a->t_last.tv_sec == 0 && a->t_last.tv_usec == 0) {
++ if (!timerisset(&a->t_last)) {
+ struct timeval t_now;
+ /*
+ * Never been called yet, call time `t' from now.
+ */
+ gettimeofday(&t_now, NULL);
+
+- a->t_last.tv_sec = t_now.tv_sec;
+- a->t_last.tv_usec = t_now.tv_usec;
++ a->t_last = t_now;
+
+ NETSNMP_TIMERADD(&t_now, &a->t, &a->t_next);
+- } else if (a->t_next.tv_sec == 0 && a->t_next.tv_usec == 0) {
++ } else if (!timerisset(&a->t_next)) {
+ /*
+ * We've been called but not reset for the next call.
+ */
+ if (a->flags & SA_REPEAT) {
+- if (a->t.tv_sec == 0 && a->t.tv_usec == 0) {
++ if (!timerisset(&a->t)) {
+ DEBUGMSGTL(("snmp_alarm",
+ "update_entry: illegal interval specified\n"));
+ snmp_alarm_unregister(a->clientreg);
+@@ -144,7 +143,7 @@ snmp_alarm_unregister(unsigned int clientreg)
+ DEBUGMSGTL(("snmp_alarm", "unregistered alarm %d\n",
+ sa_ptr->clientreg));
+ /*
+- * Note: do not free the clientarg, its the clients responsibility
++ * Note: do not free the clientarg, it's the client's responsibility
+ */
+ free(sa_ptr);
+ } else {
+@@ -185,22 +184,13 @@ sa_find_next(void)
+ for (a = thealarms; a != NULL; a = a->next) {
+ if (!(a->flags & SA_FIRED)) {
+ /* check for time delta skew */
+- if ((a->t_next.tv_sec - t_now.tv_sec) > a->t.tv_sec)
+- {
++ if ((a->t_next.tv_sec - t_now.tv_sec) > a->t.tv_sec) {
+ DEBUGMSGTL(("time_skew", "Time delta too big (%ld seconds), should be %ld seconds - fixing\n",
+ (long)(a->t_next.tv_sec - t_now.tv_sec), (long)a->t.tv_sec));
+- a->t_next.tv_sec = t_now.tv_sec + a->t.tv_sec;
+- a->t_next.tv_usec = t_now.tv_usec + a->t.tv_usec;
+- }
+- if (lowest == NULL) {
+- lowest = a;
+- } else if (a->t_next.tv_sec == lowest->t_next.tv_sec) {
+- if (a->t_next.tv_usec < lowest->t_next.tv_usec) {
+- lowest = a;
+- }
+- } else if (a->t_next.tv_sec < lowest->t_next.tv_sec) {
+- lowest = a;
+- }
++ NETSNMP_TIMERADD(&t_now, &a->t, &a->t_next);
++ }
++ if (lowest == NULL || timercmp(&a->t_next, &lowest->t_next, <))
++ lowest = a;
+ }
+ }
+ return lowest;
+@@ -247,10 +237,8 @@ run_alarms(void)
+ DEBUGMSGTL(("snmp_alarm", "alarm %d completed\n", clientreg));
+
+ if ((a = sa_find_specific(clientreg)) != NULL) {
+- a->t_last.tv_sec = t_now.tv_sec;
+- a->t_last.tv_usec = t_now.tv_usec;
+- a->t_next.tv_sec = 0;
+- a->t_next.tv_usec = 0;
++ a->t_last = t_now;
++ timerclear(&a->t_next);
+ a->flags &= ~SA_FIRED;
+ sa_update_entry(a);
+ } else {
+@@ -274,39 +262,56 @@ alarm_handler(int a)
+
+
+
++/**
++ * Look up the time at which the next alarm will fire.
++ *
++ * @param[out] alarm_tm Time at which the next alarm will fire.
++ * @param[in] now Earliest time that should be written into *alarm_tm.
++ *
++ * @return Zero if no alarms are scheduled; non-zero 'clientreg' value
++ * identifying the first alarm that will fire if one or more alarms are
++ * scheduled.
++ */
+ int
+-get_next_alarm_delay_time(struct timeval *delta)
++netsnmp_get_next_alarm_time(struct timeval *alarm_tm, const struct timeval *now)
+ {
+ struct snmp_alarm *sa_ptr;
+- struct timeval t_now;
+
+ sa_ptr = sa_find_next();
+
+ if (sa_ptr) {
+- gettimeofday(&t_now, NULL);
+-
+- if (timercmp(&t_now, &sa_ptr->t_next, >)) {
+- /*
+- * Time has already passed. Return the smallest possible amount of
+- * time.
+- */
+- delta->tv_sec = 0;
+- delta->tv_usec = 1;
+- return sa_ptr->clientreg;
+- } else {
+- /*
+- * Time is still in the future.
+- */
+- NETSNMP_TIMERSUB(&sa_ptr->t_next, &t_now, delta);
+-
+- return sa_ptr->clientreg;
+- }
++ netsnmp_assert(alarm_tm);
++ netsnmp_assert(timerisset(&sa_ptr->t_next));
++ if (timercmp(&sa_ptr->t_next, now, >))
++ *alarm_tm = sa_ptr->t_next;
++ else
++ *alarm_tm = *now;
++ return sa_ptr->clientreg;
++ } else {
++ return 0;
+ }
++}
+
+- /*
+- * Nothing Left.
+- */
+- return 0;
++/**
++ * Get the time until the next alarm will fire.
++ *
++ * @param[out] delta Time until the next alarm.
++ *
++ * @return Zero if no alarms are scheduled; non-zero 'clientreg' value
++ * identifying the first alarm that will fire if one or more alarms are
++ * scheduled.
++ */
++int
++get_next_alarm_delay_time(struct timeval *delta)
++{
++ struct timeval t_now, alarm_tm;
++ int res;
++
++ gettimeofday(&t_now, NULL);
++ res = netsnmp_get_next_alarm_time(&alarm_tm, &t_now);
++ if (res)
++ NETSNMP_TIMERSUB(&alarm_tm, &t_now, delta);
++ return res;
+ }
+
+
+@@ -328,10 +333,8 @@ set_an_alarm(void)
+ # ifdef HAVE_SETITIMER
+ struct itimerval it;
+
+- it.it_value.tv_sec = delta.tv_sec;
+- it.it_value.tv_usec = delta.tv_usec;
+- it.it_interval.tv_sec = 0;
+- it.it_interval.tv_usec = 0;
++ it.it_value = delta;
++ timerclear(&it.it_interval);
+
+ signal(SIGALRM, alarm_handler);
+ setitimer(ITIMER_REAL, &it, NULL);
+@@ -452,8 +455,7 @@ snmp_alarm_register_hr(struct timeval t, unsigned int flags,
+ return 0;
+ }
+
+- (*s)->t.tv_sec = t.tv_sec;
+- (*s)->t.tv_usec = t.tv_usec;
++ (*s)->t = t;
+ (*s)->flags = flags;
+ (*s)->clientarg = cd;
+ (*s)->thecallback = cb;
+diff --git a/snmplib/snmp_api.c b/snmplib/snmp_api.c
+index df0dc1c..4fca5bf 100644
+--- a/snmplib/snmp_api.c
++++ b/snmplib/snmp_api.c
+@@ -506,8 +506,7 @@ void
+ snmp_set_detail(const char *detail_string)
+ {
+ if (detail_string != NULL) {
+- strncpy((char *) snmp_detail, detail_string, sizeof(snmp_detail));
+- snmp_detail[sizeof(snmp_detail) - 1] = '\0';
++ strlcpy((char *) snmp_detail, detail_string, sizeof(snmp_detail));
+ snmp_detail_f = 1;
+ }
+ }
+@@ -523,20 +522,22 @@ snmp_api_errstring(int snmp_errnumber)
+ {
+ const char *msg = "";
+ static char msg_buf[SPRINT_MAX_LEN];
++
+ if (snmp_errnumber >= SNMPERR_MAX && snmp_errnumber <= SNMPERR_GENERR) {
+ msg = api_errors[-snmp_errnumber];
+ } else if (snmp_errnumber != SNMPERR_SUCCESS) {
+ msg = NULL;
+ }
+- if (!msg)
++ if (!msg) {
+ snprintf(msg_buf, sizeof(msg_buf), "Unknown error: %d", snmp_errnumber);
+- else if (snmp_detail_f) {
++ msg_buf[sizeof(msg_buf)-1] = '\0';
++ } else if (snmp_detail_f) {
+ snprintf(msg_buf, sizeof(msg_buf), "%s (%s)", msg, snmp_detail);
++ msg_buf[sizeof(msg_buf)-1] = '\0';
+ snmp_detail_f = 0;
+ } else {
+- strncpy(msg_buf, msg, sizeof(msg_buf));
++ strlcpy(msg_buf, msg, sizeof(msg_buf));
+ }
+- msg_buf[sizeof(msg_buf)-1] = '\0';
+
+ return (msg_buf);
+ }
+@@ -566,15 +567,17 @@ snmp_error(netsnmp_session * psess,
+ if (snmp_detail_f) {
+ snprintf(buf, sizeof(buf), "%s (%s)", api_errors[-snmp_errnumber],
+ snmp_detail);
++ buf[sizeof(buf)-1] = '\0';
+ snmp_detail_f = 0;
+ }
+ else
+- strncpy(buf, api_errors[-snmp_errnumber], sizeof(buf));
++ strlcpy(buf, api_errors[-snmp_errnumber], sizeof(buf));
+ } else {
+- if (snmp_errnumber)
++ if (snmp_errnumber) {
+ snprintf(buf, sizeof(buf), "Unknown Error %d", snmp_errnumber);
++ buf[sizeof(buf)-1] = '\0';
++ }
+ }
+- buf[sizeof(buf)-1] = '\0';
+
+ /*
+ * append a useful system errno interpretation.
+@@ -704,6 +707,8 @@ _init_snmp(void)
+
+ netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_HEX_OUTPUT_LENGTH, 16);
++ netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_RETRIES,
++ DEFAULT_RETRIES);
+
+ #ifdef NETSNMP_USE_REVERSE_ASNENCODING
+ netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
+@@ -1280,6 +1285,7 @@ snmpv3_probe_contextEngineID_rfc5343(void *slp, netsnmp_session *session) {
+ if (memdup(&pdu->contextEngineID, probeEngineID, probeEngineID_len) !=
+ SNMPERR_SUCCESS) {
+ snmp_log(LOG_ERR, "failed to clone memory for rfc5343 probe\n");
++ snmp_free_pdu(pdu);
+ return SNMP_ERR_GENERR;
+ }
+ pdu->contextEngineIDLen = probeEngineID_len;
+@@ -1390,7 +1396,7 @@ snmpv3_engineID_probe(struct session_list *slp,
+ }
+
+ /* see if there was any hooks to call after the engineID probing */
+- if (sptr->post_probe_engineid) {
++ if (sptr && sptr->post_probe_engineid) {
+ status = (*sptr->post_probe_engineid)(slp, in_session);
+ if (status != SNMPERR_SUCCESS)
+ return 0;
+@@ -5341,8 +5347,8 @@ _sess_process_packet(void *sessp, netsnmp_session * sp,
+ if (sp->securityEngineID == NULL) {
+ /*
+ * TODO FIX: recover after message callback *?
+- * return -1;
+- */
++ */
++ return -1;
+ }
+ memcpy(sp->securityEngineID, pdu->securityEngineID,
+ pdu->securityEngineIDLen);
+@@ -5354,8 +5360,8 @@ _sess_process_packet(void *sessp, netsnmp_session * sp,
+ if (sp->contextEngineID == NULL) {
+ /*
+ * TODO FIX: recover after message callback *?
+- * return -1;
+ */
++ return -1;
+ }
+ memcpy(sp->contextEngineID,
+ pdu->securityEngineID,
+@@ -5868,7 +5874,7 @@ snmp_sess_read2(void *sessp, netsnmp_large_fd_set * fdset)
+ }
+
+
+-/*
++/**
+ * Returns info about what snmp requires from a select statement.
+ * numfds is the number of fds in the list that are significant.
+ * All file descriptors opened for SNMP are OR'd into the fdset.
+@@ -5889,54 +5895,43 @@ snmp_sess_read2(void *sessp, netsnmp_large_fd_set * fdset)
+ *
+ * snmp_select_info returns the number of open sockets. (i.e. The number of
+ * sessions open)
++ *
++ * @see See also snmp_sess_select_info2_flags().
+ */
+-
+ int
+-snmp_select_info(int *numfds,
+- fd_set * fdset, struct timeval *timeout, int *block)
+- /*
+- * input: set to 1 if input timeout value is undefined
+- * set to 0 if input timeout value is defined
+- * output: set to 1 if output timeout value is undefined
+- * set to 0 if output rimeout vlaue id defined
+- */
++snmp_select_info(int *numfds, fd_set *fdset, struct timeval *timeout,
++ int *block)
+ {
+- return snmp_sess_select_info((void *) 0, numfds, fdset, timeout,
+- block);
++ return snmp_sess_select_info(NULL, numfds, fdset, timeout, block);
+ }
+
++/**
++ * @see See also snmp_sess_select_info2_flags().
++ */
+ int
+-snmp_select_info2(int *numfds,
+- netsnmp_large_fd_set * fdset,
++snmp_select_info2(int *numfds, netsnmp_large_fd_set *fdset,
+ struct timeval *timeout, int *block)
+- /*
+- * input: set to 1 if input timeout value is undefined
+- * set to 0 if input timeout value is defined
+- * output: set to 1 if output timeout value is undefined
+- * set to 0 if output rimeout vlaue id defined
+- */
+ {
+- return snmp_sess_select_info2((void *) 0, numfds, fdset, timeout,
+- block);
++ return snmp_sess_select_info2(NULL, numfds, fdset, timeout, block);
+ }
+
+-/*
+- * Same as snmp_select_info, but works just one session.
++/**
++ * @see See also snmp_sess_select_info2_flags().
+ */
+ int
+-snmp_sess_select_info(void *sessp,
+- int *numfds,
+- fd_set * fdset, struct timeval *timeout, int *block)
++snmp_sess_select_info(void *sessp, int *numfds, fd_set *fdset,
++ struct timeval *timeout, int *block)
+ {
+ return snmp_sess_select_info_flags(sessp, numfds, fdset, timeout, block,
+ NETSNMP_SELECT_NOFLAGS);
+ }
+
++/**
++ * @see See also snmp_sess_select_info2_flags().
++ */
+ int
+-snmp_sess_select_info_flags(void *sessp,
+- int *numfds,
+- fd_set * fdset, struct timeval *timeout, int *block,
+- int flags)
++snmp_sess_select_info_flags(void *sessp, int *numfds, fd_set *fdset,
++ struct timeval *timeout, int *block, int flags)
+ {
+ int rc;
+ netsnmp_large_fd_set lfdset;
+@@ -5954,47 +5949,67 @@ snmp_sess_select_info_flags(void *sessp,
+ return rc;
+ }
+
++/**
++ * @see See also snmp_sess_select_info2_flags().
++ */
+ int
+-snmp_sess_select_info2(void *sessp,
+- int *numfds,
+- netsnmp_large_fd_set * fdset,
++snmp_sess_select_info2(void *sessp, int *numfds, netsnmp_large_fd_set *fdset,
+ struct timeval *timeout, int *block)
+ {
+ return snmp_sess_select_info2_flags(sessp, numfds, fdset, timeout, block,
+ NETSNMP_SELECT_NOFLAGS);
+ }
+
++/**
++ * Compute/update the arguments to be passed to select().
++ *
++ * @param[in] sessp Which sessions to process: either a pointer to a
++ * specific session or NULL which means to process all sessions.
++ * @param[in,out] numfds On POSIX systems one more than the the largest file
++ * descriptor that is present in *fdset. On systems that use Winsock (MinGW
++ * and MSVC), do not use the value written into *numfds.
++ * @param[in,out] fdset A large file descriptor set to which all file
++ * descriptors will be added that are associated with one of the examined
++ * sessions.
++ * @param[in,out] timeout On input, if *block = 1, the maximum time the caller
++ * will block while waiting for Net-SNMP activity. On output, if this function
++ * has set *block to 0, the maximum time the caller is allowed to wait before
++ * invoking the Net-SNMP processing functions (snmp_read(), snmp_timeout()
++ * and run_alarms()). If this function has set *block to 1, *timeout won't
++ * have been modified and no alarms are active.
++ * @param[in,out] block On input, whether the caller prefers to block forever
++ * when no alarms are active. On output, 0 means that no alarms are active
++ * nor that there is a timeout pending for any of the processed sessions.
++ * @param[in] flags Either 0 or NETSNMP_SELECT_NOALARMS.
++ *
++ * @return Number of sessions processed by this function.
++ *
++ * @see See also agent_check_and_process() for an example of how to use this
++ * function.
++ */
+ int
+-snmp_sess_select_info2_flags(void *sessp,
+- int *numfds,
+- netsnmp_large_fd_set * fdset,
+- struct timeval *timeout, int *block, int flags)
++snmp_sess_select_info2_flags(void *sessp, int *numfds,
++ netsnmp_large_fd_set * fdset,
++ struct timeval *timeout, int *block, int flags)
+ {
+- struct session_list *slptest = (struct session_list *) sessp;
+ struct session_list *slp, *next = NULL;
+ netsnmp_request_list *rp;
+- struct timeval now, earliest, delta;
++ struct timeval now, earliest, alarm_tm;
+ int active = 0, requests = 0;
+ int next_alarm = 0;
+
+ timerclear(&earliest);
+
+ /*
+- * For each request outstanding, add its socket to the fdset,
++ * For each session examined, add its socket to the fdset,
+ * and if it is the earliest timeout to expire, mark it as lowest.
+ * If a single session is specified, do just for that session.
+ */
+
+- if (sessp) {
+- slp = slptest;
+- } else {
+- slp = Sessions;
+- }
+-
+ DEBUGMSGTL(("sess_select", "for %s session%s: ",
+ sessp ? "single" : "all", sessp ? "" : "s"));
+
+- for (; slp; slp = next) {
++ for (slp = sessp ? sessp : Sessions; slp; slp = next) {
+ next = slp->next;
+
+ if (slp->transport == NULL) {
+@@ -6032,8 +6047,9 @@ snmp_sess_select_info2_flags(void *sessp,
+ */
+ requests++;
+ for (rp = slp->internal->requests; rp; rp = rp->next_request) {
+- if ((!timerisset(&earliest)
+- || (timercmp(&rp->expire, &earliest, <)))) {
++ if (!timerisset(&earliest)
++ || (timerisset(&rp->expire)
++ && timercmp(&rp->expire, &earliest, <))) {
+ earliest = rp->expire;
+ DEBUGMSG(("verbose:sess_select","(to in %d.%06d sec) ",
+ (int)earliest.tv_sec, (int)earliest.tv_usec));
+@@ -6051,12 +6067,15 @@ snmp_sess_select_info2_flags(void *sessp,
+ }
+ DEBUGMSG(("sess_select", "\n"));
+
++ gettimeofday(&now, NULL);
++
+ if (netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_ALARM_DONT_USE_SIG) &&
+ !(flags & NETSNMP_SELECT_NOALARMS)) {
+- next_alarm = get_next_alarm_delay_time(&delta);
+- DEBUGMSGT(("sess_select","next alarm %d.%06d sec\n",
+- (int)delta.tv_sec, (int)delta.tv_usec));
++ next_alarm = netsnmp_get_next_alarm_time(&alarm_tm, &now);
++ if (next_alarm)
++ DEBUGMSGT(("sess_select","next alarm at %ld.%06ld sec\n",
++ (long)alarm_tm.tv_sec, (long)alarm_tm.tv_usec));
+ }
+ if (next_alarm == 0 && requests == 0) {
+ /*
+@@ -6067,51 +6086,18 @@ snmp_sess_select_info2_flags(void *sessp,
+ return active;
+ }
+
+- /*
+- * * Now find out how much time until the earliest timeout. This
+- * * transforms earliest from an absolute time into a delta time, the
+- * * time left until the select should timeout.
+- */
+- gettimeofday(&now, (struct timezone *) 0);
+- /*
+- * Now = now;
+- */
++ if (next_alarm &&
++ (!timerisset(&earliest) || timercmp(&alarm_tm, &earliest, <)))
++ earliest = alarm_tm;
+
+- if (next_alarm) {
+- delta.tv_sec += now.tv_sec;
+- delta.tv_usec += now.tv_usec;
+- while (delta.tv_usec >= 1000000) {
+- delta.tv_usec -= 1000000;
+- delta.tv_sec += 1;
+- }
+- if (!timerisset(&earliest) ||
+- ((earliest.tv_sec > delta.tv_sec) ||
+- ((earliest.tv_sec == delta.tv_sec) &&
+- (earliest.tv_usec > delta.tv_usec)))) {
+- earliest.tv_sec = delta.tv_sec;
+- earliest.tv_usec = delta.tv_usec;
+- }
+- }
+-
+- if (earliest.tv_sec < now.tv_sec) {
+- DEBUGMSGT(("verbose:sess_select","timer overdue\n"));
+- earliest.tv_sec = 0;
+- earliest.tv_usec = 0;
+- } else if (earliest.tv_sec == now.tv_sec) {
+- earliest.tv_sec = 0;
+- earliest.tv_usec = (earliest.tv_usec - now.tv_usec);
+- if (earliest.tv_usec < 0) {
+- earliest.tv_usec = 100;
+- }
+- DEBUGMSGT(("verbose:sess_select","timer due *real* soon. %d usec\n",
+- (int)earliest.tv_usec));
++ NETSNMP_TIMERSUB(&earliest, &now, &earliest);
++ if (earliest.tv_sec < 0) {
++ time_t overdue_ms = -(earliest.tv_sec * 1000 + earliest.tv_usec / 1000);
++ if (overdue_ms >= 10)
++ DEBUGMSGT(("verbose:sess_select","timer overdue by %ld ms\n",
++ overdue_ms));
++ timerclear(&earliest);
+ } else {
+- earliest.tv_sec = (earliest.tv_sec - now.tv_sec);
+- earliest.tv_usec = (earliest.tv_usec - now.tv_usec);
+- if (earliest.tv_usec < 0) {
+- earliest.tv_sec--;
+- earliest.tv_usec = (1000000L + earliest.tv_usec);
+- }
+ DEBUGMSGT(("verbose:sess_select","timer due in %d.%06d sec\n",
+ (int)earliest.tv_sec, (int)earliest.tv_usec));
+ }
+diff --git a/snmplib/snmp_client.c b/snmplib/snmp_client.c
+index ae57613..c1aa9c4 100644
+--- a/snmplib/snmp_client.c
++++ b/snmplib/snmp_client.c
+@@ -804,6 +804,11 @@ snmp_set_var_value(netsnmp_variable_list * vars,
+ vars->val.string = NULL;
+ vars->val_len = 0;
+
++ if (value == NULL && len > 0) {
++ snmp_log(LOG_ERR, "bad size for NULL value\n");
++ return 1;
++ }
++
+ /*
+ * use built-in storage for smaller values
+ */
+@@ -823,84 +828,82 @@ snmp_set_var_value(netsnmp_variable_list * vars,
+ case ASN_UNSIGNED:
+ case ASN_TIMETICKS:
+ case ASN_COUNTER:
+- if (value) {
+- if (vars->val_len == sizeof(int)) {
+- if (ASN_INTEGER == vars->type) {
+- const int *val_int
+- = (const int *) value;
+- *(vars->val.integer) = (long) *val_int;
+- } else {
+- const u_int *val_uint
+- = (const u_int *) value;
+- *(vars->val.integer) = (unsigned long) *val_uint;
+- }
++ case ASN_UINTEGER:
++ if (vars->val_len == sizeof(int)) {
++ if (ASN_INTEGER == vars->type) {
++ const int *val_int
++ = (const int *) value;
++ *(vars->val.integer) = (long) *val_int;
++ } else {
++ const u_int *val_uint
++ = (const u_int *) value;
++ *(vars->val.integer) = (unsigned long) *val_uint;
+ }
++ }
+ #if SIZEOF_LONG != SIZEOF_INT
+- else if (vars->val_len == sizeof(long)){
+- const u_long *val_ulong
+- = (const u_long *) value;
+- *(vars->val.integer) = *val_ulong;
+- if (*(vars->val.integer) > 0xffffffff) {
+- snmp_log(LOG_ERR,"truncating integer value > 32 bits\n");
+- *(vars->val.integer) &= 0xffffffff;
+- }
++ else if (vars->val_len == sizeof(long)){
++ const u_long *val_ulong
++ = (const u_long *) value;
++ *(vars->val.integer) = *val_ulong;
++ if (*(vars->val.integer) > 0xffffffff) {
++ snmp_log(LOG_ERR,"truncating integer value > 32 bits\n");
++ *(vars->val.integer) &= 0xffffffff;
+ }
++ }
+ #endif
+ #if defined(SIZEOF_LONG_LONG) && (SIZEOF_LONG != SIZEOF_LONG_LONG)
+ #if !defined(SIZEOF_INTMAX_T) || (SIZEOF_LONG_LONG != SIZEOF_INTMAX_T)
+- else if (vars->val_len == sizeof(long long)){
+- const unsigned long long *val_ullong
+- = (const unsigned long long *) value;
+- *(vars->val.integer) = (long) *val_ullong;
+- if (*(vars->val.integer) > 0xffffffff) {
+- snmp_log(LOG_ERR,"truncating integer value > 32 bits\n");
+- *(vars->val.integer) &= 0xffffffff;
+- }
++ else if (vars->val_len == sizeof(long long)){
++ const unsigned long long *val_ullong
++ = (const unsigned long long *) value;
++ *(vars->val.integer) = (long) *val_ullong;
++ if (*(vars->val.integer) > 0xffffffff) {
++ snmp_log(LOG_ERR,"truncating integer value > 32 bits\n");
++ *(vars->val.integer) &= 0xffffffff;
+ }
++ }
+ #endif
+ #endif
+ #if defined(SIZEOF_INTMAX_T) && (SIZEOF_LONG != SIZEOF_INTMAX_T)
+- else if (vars->val_len == sizeof(intmax_t)){
+- const uintmax_t *val_uintmax_t
+- = (const uintmax_t *) value;
+- *(vars->val.integer) = (long) *val_uintmax_t;
+- if (*(vars->val.integer) > 0xffffffff) {
+- snmp_log(LOG_ERR,"truncating integer value > 32 bits\n");
+- *(vars->val.integer) &= 0xffffffff;
+- }
++ else if (vars->val_len == sizeof(intmax_t)){
++ const uintmax_t *val_uintmax_t
++ = (const uintmax_t *) value;
++ *(vars->val.integer) = (long) *val_uintmax_t;
++ if (*(vars->val.integer) > 0xffffffff) {
++ snmp_log(LOG_ERR,"truncating integer value > 32 bits\n");
++ *(vars->val.integer) &= 0xffffffff;
+ }
++ }
+ #endif
+ #if SIZEOF_SHORT != SIZEOF_INT
+- else if (vars->val_len == sizeof(short)) {
+- if (ASN_INTEGER == vars->type) {
+- const short *val_short
+- = (const short *) value;
+- *(vars->val.integer) = (long) *val_short;
+- } else {
+- const u_short *val_ushort
+- = (const u_short *) value;
+- *(vars->val.integer) = (unsigned long) *val_ushort;
+- }
++ else if (vars->val_len == sizeof(short)) {
++ if (ASN_INTEGER == vars->type) {
++ const short *val_short
++ = (const short *) value;
++ *(vars->val.integer) = (long) *val_short;
++ } else {
++ const u_short *val_ushort
++ = (const u_short *) value;
++ *(vars->val.integer) = (unsigned long) *val_ushort;
+ }
++ }
+ #endif
+- else if (vars->val_len == sizeof(char)) {
+- if (ASN_INTEGER == vars->type) {
+- const char *val_char
+- = (const char *) value;
+- *(vars->val.integer) = (long) *val_char;
+- } else {
++ else if (vars->val_len == sizeof(char)) {
++ if (ASN_INTEGER == vars->type) {
++ const char *val_char
++ = (const char *) value;
++ *(vars->val.integer) = (long) *val_char;
++ } else {
+ const u_char *val_uchar
+- = (const u_char *) value;
+- *(vars->val.integer) = (unsigned long) *val_uchar;
+- }
+- }
+- else {
+- snmp_log(LOG_ERR,"bad size for integer-like type (%d)\n",
+- (int)vars->val_len);
+- return (1);
++ = (const u_char *) value;
++ *(vars->val.integer) = (unsigned long) *val_uchar;
+ }
+- } else
+- *(vars->val.integer) = 0;
++ }
++ else {
++ snmp_log(LOG_ERR,"bad size for integer-like type (%d)\n",
++ (int)vars->val_len);
++ return (1);
++ }
+ vars->val_len = sizeof(long);
+ break;
+
+diff --git a/snmplib/snmp_enum.c b/snmplib/snmp_enum.c
+index cac0ed3..8a6bd38 100644
+--- a/snmplib/snmp_enum.c
++++ b/snmplib/snmp_enum.c
+@@ -156,12 +156,12 @@ se_read_conf(const char *word, char *cptr)
+
+ void
+ se_store_enum_list(struct snmp_enum_list *new_list,
+- const char *token, char *type)
++ const char *token, const char *type)
+ {
+ struct snmp_enum_list *listp = new_list;
+ char line[2048];
+ char buf[512];
+- int len = 0;
++ int len;
+
+ snprintf(line, sizeof(line), "enum %s", token);
+ while (listp) {
+@@ -175,26 +175,19 @@ se_store_enum_list(struct snmp_enum_list *new_list,
+ if ((int)strlen(buf) > len) {
+ read_config_store(type, line);
+ snprintf(line, sizeof(line), "enum %s", token);
+- len = sizeof(line);
++ len = sizeof(line) - strlen(line);
+ }
+
+ strncat(line, buf, len);
+ listp = listp->next;
+ }
+
+- /*
+- * If there's anything left, then save that.
+- * But don't bother saving an empty 'overflow' line.
+- */
+- if (len != sizeof(line))
+- read_config_store(type, line);
+-
+- return;
++ read_config_store(type, line);
+ }
+
+ #ifndef NETSNMP_FEATURE_REMOVE_SNMP_ENUM_STORE_LIST
+ void
+-se_store_list(unsigned int major, unsigned int minor, char *type)
++se_store_list(unsigned int major, unsigned int minor, const char *type)
+ {
+ char token[32];
+
+@@ -297,8 +290,10 @@ se_add_pair_to_list(struct snmp_enum_list **list, char *label, int value)
+ (*list) = SNMP_MALLOC_STRUCT(snmp_enum_list);
+ lastnode = (*list);
+ }
+- if (!lastnode)
++ if (!lastnode) {
++ free(label);
+ return (SE_NOMEM);
++ }
+ lastnode->label = label;
+ lastnode->value = value;
+ lastnode->next = NULL;
+@@ -445,7 +440,7 @@ se_clear_list(struct snmp_enum_list **list)
+
+ #ifndef NETSNMP_FEATURE_REMOVE_SNMP_ENUM_STORE_SLIST
+ void
+-se_store_slist(const char *listname, char *type)
++se_store_slist(const char *listname, const char *type)
+ {
+ struct snmp_enum_list *list = se_find_slist(listname);
+ se_store_enum_list(list, listname, type);
+diff --git a/snmplib/snmp_logging.c b/snmplib/snmp_logging.c
+index 37d5948..a2cd55a 100644
+--- a/snmplib/snmp_logging.c
++++ b/snmplib/snmp_logging.c
+@@ -535,7 +535,7 @@ char *
+ snmp_log_syslogname(const char *pstr)
+ {
+ if (pstr)
+- strncpy (syslogname, pstr, sizeof(syslogname));
++ strlcpy (syslogname, pstr, sizeof(syslogname));
+
+ return syslogname;
+ }
+diff --git a/snmplib/snmp_openssl.c b/snmplib/snmp_openssl.c
+index da5c114..3b0eaa8 100644
+--- a/snmplib/snmp_openssl.c
++++ b/snmplib/snmp_openssl.c
+@@ -737,7 +737,7 @@ _cert_get_san_type(X509 *ocert, int mapType)
+ if (lower)
+ for ( ; *lower; ++lower )
+ if (isascii(*lower))
+- *lower = tolower(*lower);
++ *lower = tolower(0xFF & *lower);
+ DEBUGMSGT(("openssl:cert:extension:san", "#%d type %d: %s\n", i,
+ oname ? oname->type : -1, buf ? buf : "NULL"));
+
+diff --git a/snmplib/snmp_parse_args.c b/snmplib/snmp_parse_args.c
+index e47542e..c73b84c 100644
+--- a/snmplib/snmp_parse_args.c
++++ b/snmplib/snmp_parse_args.c
+@@ -209,8 +209,13 @@ netsnmp_parse_args(int argc,
+ */
+ snmp_sess_init(session);
+ strcpy(Opts, "Y:VhHm:M:O:I:P:D:dv:r:t:c:Z:e:E:n:u:l:x:X:a:A:p:T:-:3:s:S:L:");
+- if (localOpts)
++ if (localOpts) {
++ if (strlen(localOpts) + strlen(Opts) >= sizeof(Opts)) {
++ snmp_log(LOG_ERR, "Too many localOpts in snmp_parse_args()\n");
++ return -1;
++ }
+ strcat(Opts, localOpts);
++ }
+
+ /*
+ * get the options
+@@ -364,10 +369,8 @@ netsnmp_parse_args(int argc,
+ }
+
+ /* set the config */
+- strncpy(leftside, tmpopt, sizeof(leftside));
+- leftside[sizeof(leftside)-1] = '0';
+- strncpy(rightside, tmpcp, sizeof(rightside));
+- rightside[sizeof(rightside)-1] = '0';
++ strlcpy(leftside, tmpopt, sizeof(leftside));
++ strlcpy(rightside, tmpcp, sizeof(rightside));
+
+ CONTAINER_INSERT(session->transport_configuration,
+ netsnmp_transport_create_config(leftside,
+diff --git a/snmplib/snmp_service.c b/snmplib/snmp_service.c
+index 90af5e4..ce7e8be 100644
+--- a/snmplib/snmp_service.c
++++ b/snmplib/snmp_service.c
+@@ -227,6 +227,15 @@ struct netsnmp_lookup_target {
+
+ static struct netsnmp_lookup_target* targets = NULL;
+
++/**
++ * Add an (application, domain, target) triplet to the targets list if target
++ * != NULL. Remove an entry if target == NULL and the userTarget pointer for
++ * the entry found is also NULL. Keep at most one target per (application,
++ * domain) pair.
++ *
++ * @return 1 if an entry for (application, domain) was already present in the
++ * targets list or 0 if such an entry was not yet present in the targets list.
++ */
+ int
+ netsnmp_register_default_target(const char* application, const char* domain,
+ const char* target)
+@@ -271,6 +280,9 @@ netsnmp_register_default_target(const char* application, const char* domain,
+ return res;
+ }
+
++/**
++ * Clear the targets list.
++ */
+ void
+ netsnmp_clear_default_target(void)
+ {
+diff --git a/snmplib/snmp_transport.c b/snmplib/snmp_transport.c
+index ae2b3ee..85a4f35 100644
+--- a/snmplib/snmp_transport.c
++++ b/snmplib/snmp_transport.c
+@@ -127,11 +127,10 @@ netsnmp_transport_copy(netsnmp_transport *t)
+ return NULL;
+ }
+
+- n = (netsnmp_transport *) malloc(sizeof(netsnmp_transport));
++ n = SNMP_MALLOC_TYPEDEF(netsnmp_transport);
+ if (n == NULL) {
+ return NULL;
+ }
+- memset(n, 0, sizeof(netsnmp_transport));
+
+ if (t->domain != NULL) {
+ n->domain = t->domain;
+@@ -551,7 +550,7 @@ netsnmp_tdomain_transport_full(const char *application,
+ if (NULL !=
+ (newhost = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
+ NETSNMP_DS_LIB_HOSTNAME))) {
+- strncpy(buf, newhost, sizeof(buf)-1);
++ strlcpy(buf, newhost, sizeof(buf));
+ str = buf;
+ }
+
+diff --git a/snmplib/snmptsm.c b/snmplib/snmptsm.c
+index 778001e..bf4b612 100644
+--- a/snmplib/snmptsm.c
++++ b/snmplib/snmptsm.c
+@@ -193,6 +193,7 @@ tsm_rgenerate_out_msg(struct snmp_secmod_outgoing_params *parms)
+ size_t *wholeMsgLen = parms->wholeMsgLen;
+ netsnmp_tsmSecurityReference *tsmSecRef;
+ netsnmp_tmStateReference *tmStateRef;
++ int tmStateRefLocal = 0;
+
+ DEBUGMSGTL(("tsm", "Starting TSM processing\n"));
+
+@@ -229,7 +230,8 @@ tsm_rgenerate_out_msg(struct snmp_secmod_outgoing_params *parms)
+ tmStateReference cache. */
+ tmStateRef = SNMP_MALLOC_TYPEDEF(netsnmp_tmStateReference);
+ netsnmp_assert_or_return(NULL != tmStateRef, SNMPERR_GENERR);
+-
++ tmStateRefLocal = 1;
++
+ /* XXX: we don't actually use this really in our implementation */
+ /* 4.2, step 2: Set tmTransportDomain to the value of
+ transportDomain, tmTransportAddress to the value of
+@@ -263,6 +265,7 @@ tsm_rgenerate_out_msg(struct snmp_secmod_outgoing_params *parms)
+ incremented, an error indication is returned to the
+ calling module, and message processing stops. */
+ snmp_increment_statistic(STAT_TSM_SNMPTSMUNKNOWNPREFIXES);
++ SNMP_FREE(tmStateRef);
+ return SNMPERR_GENERR;
+ }
+
+@@ -281,6 +284,7 @@ tsm_rgenerate_out_msg(struct snmp_secmod_outgoing_params *parms)
+ /* Note: since we're assiging the prefixes above the
+ prefix lengths always meet the 1-4 criteria */
+ snmp_increment_statistic(STAT_TSM_SNMPTSMINVALIDPREFIXES);
++ SNMP_FREE(tmStateRef);
+ return SNMPERR_GENERR;
+ }
+
+@@ -315,6 +319,8 @@ tsm_rgenerate_out_msg(struct snmp_secmod_outgoing_params *parms)
+ DEBUGINDENTLESS();
+ if (rc == 0) {
+ DEBUGMSGTL(("tsm", "building msgSecurityParameters failed.\n"));
++ if (tmStateRefLocal)
++ SNMP_FREE(tmStateRef);
+ return SNMPERR_TOO_LONG;
+ }
+
+@@ -324,6 +330,8 @@ tsm_rgenerate_out_msg(struct snmp_secmod_outgoing_params *parms)
+ while ((*wholeMsgLen - *offset) < parms->globalDataLen) {
+ if (!asn_realloc(wholeMsg, wholeMsgLen)) {
+ DEBUGMSGTL(("tsm", "building global data failed.\n"));
++ if (tmStateRefLocal)
++ SNMP_FREE(tmStateRef);
+ return SNMPERR_TOO_LONG;
+ }
+ }
+@@ -347,6 +355,8 @@ tsm_rgenerate_out_msg(struct snmp_secmod_outgoing_params *parms)
+ ASN_CONSTRUCTOR), *offset);
+ if (rc == 0) {
+ DEBUGMSGTL(("tsm", "building master packet sequence failed.\n"));
++ if (tmStateRefLocal)
++ SNMP_FREE(tmStateRef);
+ return SNMPERR_TOO_LONG;
+ }
+
+@@ -364,6 +374,8 @@ tsm_rgenerate_out_msg(struct snmp_secmod_outgoing_params *parms)
+ }
+ parms->pdu->transport_data_length = sizeof(*tmStateRef);
+
++ if (tmStateRefLocal)
++ SNMP_FREE(tmStateRef);
+ DEBUGMSGTL(("tsm", "TSM processing completed.\n"));
+ return SNMPERR_SUCCESS;
+ }
+diff --git a/snmplib/snmpusm.c b/snmplib/snmpusm.c
+index 8a673dc..d8d8932 100644
+--- a/snmplib/snmpusm.c
++++ b/snmplib/snmpusm.c
+@@ -2727,6 +2727,7 @@ usm_handle_report(void *sessp,
+ }
+ session->s_snmp_errno = res;
+ }
++ /* fallthrough */
+ case SNMPERR_USM_UNKNOWNENGINEID:
+ case SNMPERR_USM_UNKNOWNSECURITYNAME:
+ case SNMPERR_USM_UNSUPPORTEDSECURITYLEVEL:
+@@ -3150,6 +3151,7 @@ int usm_discover_engineid(void *slpv, netsnmp_session *session) {
+ break;
+ case STAT_TIMEOUT:
+ session->s_snmp_errno = SNMPERR_TIMEOUT;
++ break;
+ default:
+ DEBUGMSGTL(("snmp_sess_open",
+ "unable to connect with remote engine: %s (%d)\n",
+@@ -4160,8 +4162,8 @@ usm_set_password(const char *token, char *line)
+ {
+ char *cp;
+ char nameBuf[SNMP_MAXBUF];
+- u_char *engineID;
+- size_t engineIDLen;
++ u_char *engineID = NULL;
++ size_t engineIDLen = 0;
+ struct usmUser *user;
+
+ cp = copy_nword(line, nameBuf, sizeof(nameBuf));
+@@ -4185,15 +4187,18 @@ usm_set_password(const char *token, char *line)
+ cp = read_config_read_octet_string(cp, &engineID, &engineIDLen);
+ if (cp == NULL) {
+ config_perror("invalid engineID specifier");
++ SNMP_FREE(engineID);
+ return;
+ }
+
+ user = usm_get_user(engineID, engineIDLen, nameBuf);
+ if (user == NULL) {
+ config_perror("not a valid user/engineID pair");
++ SNMP_FREE(engineID);
+ return;
+ }
+ usm_set_user_password(user, token, cp);
++ SNMP_FREE(engineID);
+ }
+ }
+
+diff --git a/snmplib/snmpv3.c b/snmplib/snmpv3.c
+index f8bd90b..3369fb6 100644
+--- a/snmplib/snmpv3.c
++++ b/snmplib/snmpv3.c
+@@ -1274,7 +1274,7 @@ getHwAddress(const char *networkDevice, /* e.g. "eth0", "eth1" */
+ /*
+ * copy the name of the net device we want to find the HW address for
+ */
+- strncpy(request.ifr_name, networkDevice, IFNAMSIZ - 1);
++ strlcpy(request.ifr_name, networkDevice, IFNAMSIZ);
+ /*
+ * Get the HW address
+ */
+diff --git a/snmplib/strlcat.c b/snmplib/strlcat.c
+new file mode 100644
+index 0000000..90713ca
+--- /dev/null
++++ b/snmplib/strlcat.c
+@@ -0,0 +1,67 @@
++/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
++
++/*
++ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
++ *
++ * Permission to use, copy, modify, and distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++
++#include <net-snmp/net-snmp-config.h>
++
++#ifndef HAVE_STRLCAT
++
++#if HAVE_STRING_H
++#include <string.h>
++#else
++#include <strings.h>
++#endif
++#include <sys/types.h>
++
++#include <net-snmp/library/system.h>
++
++/*
++ * Appends src to string dst of size siz (unlike strncat, siz is the
++ * full size of dst, not space left). At most siz-1 characters
++ * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
++ * Returns strlen(src) + MIN(siz, strlen(initial dst)).
++ * If retval >= siz, truncation occurred.
++ */
++size_t
++strlcat(char * __restrict dst, const char * __restrict src, size_t siz)
++{
++ char *d = dst;
++ const char *s = src;
++ size_t n = siz;
++ size_t dlen;
++
++ /* Find the end of dst and adjust bytes left but don't go past end */
++ while (n-- != 0 && *d != '\0')
++ d++;
++ dlen = d - dst;
++ n = siz - dlen;
++
++ if (n == 0)
++ return(dlen + strlen(s));
++ while (*s != '\0') {
++ if (n != 1) {
++ *d++ = *s;
++ n--;
++ }
++ s++;
++ }
++ *d = '\0';
++
++ return(dlen + (s - src)); /* count does not include NUL */
++}
++
++#endif
+diff --git a/snmplib/strtoull.c b/snmplib/strtoull.c
+index be94f29..6c98fc4 100644
+--- a/snmplib/strtoull.c
++++ b/snmplib/strtoull.c
+@@ -49,13 +49,8 @@
+ #define ULLONG_MAX UINT64_C(0xffffffffffffffff)
+ #endif
+
+-#ifdef STRTOULL_UNIT_TEST
+-uint64_t
+-my_strtoull(const char *nptr, char **endptr, int base)
+-#else
+ uint64_t
+ strtoull(const char *nptr, char **endptr, int base)
+-#endif
+ {
+ uint64_t result = 0;
+ const char *p;
+@@ -161,123 +156,3 @@ strtoull(const char *nptr, char **endptr, int base)
+ *endptr = (char *) nptr;
+ return 0;
+ }
+-
+-#if defined(STRTOULL_UNIT_TEST)
+-
+-#include <stdio.h>
+-#include <stdlib.h>
+-
+-#ifndef PRIu64
+-#ifdef _MSC_VER
+-#define PRIu64 "I64u"
+-#else
+-#define PRIu64 "llu"
+-#endif
+-#endif
+-
+-struct strtoull_testcase {
+- /*
+- * inputs
+- */
+- const char *nptr;
+- int base;
+- /*
+- * expected outputs
+- */
+- int expected_errno;
+- int expected_end;
+- uint64_t expected_result;
+-};
+-
+-static const struct strtoull_testcase test_input[] = {
+- {"0x0", 0, 0, 3, 0},
+- {"1", 0, 0, 1, 1},
+- {"0x1", 0, 0, 3, 1},
+- {" -0666", 0, 0, 7, -0666},
+- {" -0x666", 0, 0, 8, -0x666},
+- {"18446744073709551614", 0, 0, 20, UINT64_C(0xfffffffffffffffe)},
+- {"0xfffffffffffffffe", 0, 0, 18, UINT64_C(0xfffffffffffffffe)},
+- {"18446744073709551615", 0, 0, 20, UINT64_C(0xffffffffffffffff)},
+- {"0xffffffffffffffff", 0, 0, 18, UINT64_C(0xffffffffffffffff)},
+- {"18446744073709551616", 0, ERANGE, 20, UINT64_C(0xffffffffffffffff)},
+- {"0x10000000000000000", 0, ERANGE, 19, UINT64_C(0xffffffffffffffff)},
+- {"ff", 16, 0, 2, 255},
+- {"0xff", 16, 0, 4, 255},
+- {" ", 0, 0, 0, 0},
+- {"0x", 0, 0, 1, 0},
+- {"0x", 8, 0, 1, 0},
+- {"0x", 16, 0, 1, 0},
+- {"zyyy", 0, 0, 0, 0},
+- {"0xfffffffffffffffff", 0, ERANGE, 19, ULLONG_MAX},
+- {"0xfffffffffffffffffz", 0, ERANGE, 19, ULLONG_MAX}
+-};
+-
+-int
+-main(void)
+-{
+- int failure_count = 0;
+- unsigned int i;
+-
+- for (i = 0; i < sizeof(test_input) / sizeof(test_input[0]); i++) {
+- const struct strtoull_testcase *const p = &test_input[i];
+- char *endptr;
+- uint64_t result;
+-
+- errno = 0;
+- result = my_strtoull(p->nptr, &endptr, p->base);
+- if (errno != p->expected_errno) {
+- failure_count++;
+- printf("test %d failed (input \"%s\"): expected errno %d"
+- ", got errno %d\n",
+- i, p->nptr, p->expected_errno, errno);
+- }
+- if (result != p->expected_result) {
+- failure_count++;
+- printf("test %d failed (input \"%s\"): expected result %" PRIu64
+- ", got result %" PRIu64 "\n",
+- i, p->nptr, p->expected_result, result);
+- }
+- if (endptr - p->nptr != p->expected_end) {
+- failure_count++;
+- printf("test %d failed (input \"%s\"): expected end %d,"
+- " got end %d\n",
+- i, p->nptr, p->expected_end, (int) (endptr - p->nptr));
+- }
+-
+-#if HAVE_STRTOULL
+- errno = 0;
+- result = strtoull(p->nptr, &endptr, p->base);
+- if (errno != p->expected_errno) {
+- failure_count++;
+- printf("test %d (input \"%s\"): expected errno %d"
+- ", libc strtoull() returned errno %d\n",
+- i, p->nptr, p->expected_errno, errno);
+- }
+- if (result != p->expected_result) {
+- failure_count++;
+- printf("test %d (input \"%s\"): expected result %" PRIu64
+- ", libc strtoull() returned result %" PRIu64 "\n",
+- i, p->nptr, p->expected_result, result);
+- }
+- if (endptr - p->nptr != p->expected_end) {
+- failure_count++;
+- printf("test %d (input \"%s\"): expected end %d,"
+- " libc strtoull() returned end %d\n",
+- i, p->nptr, p->expected_end, (int) (endptr - p->nptr));
+- }
+-#endif
+- }
+- if (failure_count == 0)
+- printf("All %d tests passed.\n", i);
+- return 0;
+-}
+-
+-#endif /* defined(STRTOULL_UNIT_TEST) */
+-
+-/*
+- * Local variables:
+- * c-basic-offset: 4
+- * indent-tabs-mode: nil
+- * compile-command: "gcc -Wall -Werror -DSTRTOULL_UNIT_TEST=1 -I../include -g -o strtoull-unit-test strtoull.c && ./strtoull-unit-test"
+- * End:
+- */
+diff --git a/snmplib/system.c b/snmplib/system.c
+index cec6c34..1070bbf 100644
+--- a/snmplib/system.c
++++ b/snmplib/system.c
+@@ -184,6 +184,8 @@ SOFTWARE.
+ #include <net-snmp/library/snmp_api.h>
+ #include <net-snmp/library/read_config.h> /* for get_temp_file_pattern() */
+
++#include "inet_ntop.h"
++
+ /* NetSNMP and DNSSEC-Tools both define FREE. We'll not use either here. */
+ #undef FREE
+
+@@ -637,25 +639,19 @@ get_boottime(void)
+ }
+ #endif
+
+-/*
+- * Returns uptime in centiseconds(!).
++/**
++ * Returns the system uptime in centiseconds.
++ *
++ * @note The value returned by this function is not identical to sysUpTime
++ * defined in RFC 1213. get_uptime() returns the system uptime while
++ * sysUpTime represents the time that has elapsed since the most recent
++ * restart of the network manager (snmpd).
++ *
++ * @see See also netsnmp_get_agent_uptime().
+ */
+ long
+ get_uptime(void)
+ {
+-#if !defined(solaris2) && !defined(linux) && !defined(cygwin) && !defined(aix4) && !defined(aix5) && !defined(aix6) && !defined(aix7)
+- struct timeval now;
+- long boottime_csecs, nowtime_csecs;
+-
+- boottime_csecs = get_boottime();
+- if (boottime_csecs == 0)
+- return 0;
+- gettimeofday(&now, (struct timezone *) 0);
+- nowtime_csecs = (now.tv_sec * 100) + (now.tv_usec / 10000);
+-
+- return (nowtime_csecs - boottime_csecs);
+-#endif
+-
+ #if defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
+ struct nlist nl;
+ int kmem;
+@@ -668,9 +664,7 @@ get_uptime(void)
+ read(kmem, &lbolt, sizeof(lbolt));
+ close(kmem);
+ return(lbolt);
+-#endif
+-
+-#ifdef solaris2
++#elif defined(solaris2)
+ kstat_ctl_t *ksc = kstat_open();
+ kstat_t *ks;
+ kid_t kid;
+@@ -695,9 +689,7 @@ get_uptime(void)
+ kstat_close(ksc);
+ }
+ return lbolt;
+-#endif /* solaris2 */
+-
+-#ifdef linux
++#elif defined(linux) || defined(cygwin)
+ FILE *in = fopen("/proc/uptime", "r");
+ long uptim = 0, a, b;
+ if (in) {
+@@ -706,10 +698,17 @@ get_uptime(void)
+ fclose(in);
+ }
+ return uptim;
+-#endif /* linux */
++#else
++ struct timeval now;
++ long boottime_csecs, nowtime_csecs;
+
+-#ifdef cygwin
+- return (0); /* not implemented */
++ boottime_csecs = get_boottime();
++ if (boottime_csecs == 0)
++ return 0;
++ gettimeofday(&now, (struct timezone *) 0);
++ nowtime_csecs = (now.tv_sec * 100) + (now.tv_usec / 10000);
++
++ return (nowtime_csecs - boottime_csecs);
+ #endif
+ }
+
+@@ -928,22 +927,33 @@ netsnmp_gethostbyname(const char *name)
+ #endif /* HAVE_GETHOSTBYNAME */
+ }
+
++/**
++ * Look up the host name via DNS.
++ *
++ * @param[in] addr Pointer to the address to resolve. This argument points e.g.
++ * to a struct in_addr for AF_INET or to a struct in6_addr for AF_INET6.
++ * @param[in] len Length in bytes of *addr.
++ * @param[in] type Address family, e.g. AF_INET or AF_INET6.
++ *
++ * @return Pointer to a hostent structure if address lookup succeeded or NULL
++ * if the lookup failed.
++ *
++ * @see See also the gethostbyaddr() man page.
++ */
+ struct hostent *
+ netsnmp_gethostbyaddr(const void *addr, socklen_t len, int type)
+ {
+ #if HAVE_GETHOSTBYADDR
+ struct hostent *hp = NULL;
+- struct sockaddr_in *saddr_in =
+- NETSNMP_REMOVE_CONST(struct sockaddr_in *,addr);
++ char buf[64];
+
+- DEBUGMSGTL(("dns:gethostbyaddr", "resolving { AF_INET, %s:%hu }\n",
+- inet_ntoa(saddr_in->sin_addr), ntohs(saddr_in->sin_port)));
++ DEBUGMSGTL(("dns:gethostbyaddr", "resolving %s\n",
++ inet_ntop(type, addr, buf, sizeof(buf))));
+
+ #ifdef DNSSEC_LOCAL_VALIDATION
+ val_status_t val_status;
+- hp = val_gethostbyaddr(netsnmp_validator_context(),
+- (const void*)&saddr_in->sin_addr,
+- sizeof(struct in_addr), AF_INET, &val_status);
++ hp = val_gethostbyaddr(netsnmp_validator_context(), addr, len, type,
++ &val_status);
+ DEBUGMSGTL(("dns:sec:val", "val_status %d / %s; trusted: %d\n",
+ val_status, p_val_status(val_status),
+ val_istrusted(val_status)));
+@@ -959,8 +969,7 @@ netsnmp_gethostbyaddr(const void *addr, socklen_t len, int type)
+ else if (val_does_not_exist(val_status) && hp)
+ hp = NULL;
+ #else
+- hp = gethostbyaddr((const void*) &saddr_in->sin_addr,
+- sizeof(struct in_addr), AF_INET);
++ hp = gethostbyaddr(addr, len, type);
+ #endif
+ if (hp == NULL) {
+ DEBUGMSGTL(("dns:gethostbyaddr", "couldn't resolve addr\n"));
+@@ -1069,44 +1078,30 @@ setenv(const char *name, const char *value, int overwrite)
+ }
+ #endif /* HAVE_SETENV */
+
+-/* returns centiseconds */
+ netsnmp_feature_child_of(calculate_time_diff, netsnmp_unused)
+ #ifndef NETSNMP_FEATURE_REMOVE_CALCULATE_TIME_DIFF
++/**
++ * Compute (*now - *then) in centiseconds.
++ */
+ int
+ calculate_time_diff(const struct timeval *now, const struct timeval *then)
+ {
+- struct timeval tmp, diff;
+- memcpy(&tmp, now, sizeof(struct timeval));
+- tmp.tv_sec--;
+- tmp.tv_usec += 1000000L;
+- diff.tv_sec = tmp.tv_sec - then->tv_sec;
+- diff.tv_usec = tmp.tv_usec - then->tv_usec;
+- if (diff.tv_usec > 1000000L) {
+- diff.tv_usec -= 1000000L;
+- diff.tv_sec++;
+- }
++ struct timeval diff;
++
++ NETSNMP_TIMERSUB(now, then, &diff);
+ return (int)(diff.tv_sec * 100 + diff.tv_usec / 10000);
+ }
+ #endif /* NETSNMP_FEATURE_REMOVE_CALCULATE_TIME_DIFF */
+
+ #ifndef NETSNMP_FEATURE_REMOVE_CALCULATE_SECTIME_DIFF
+-/* returns diff in rounded seconds */
++/** Compute rounded (*now - *then) in seconds. */
+ u_int
+ calculate_sectime_diff(const struct timeval *now, const struct timeval *then)
+ {
+- struct timeval tmp, diff;
+- memcpy(&tmp, now, sizeof(struct timeval));
+- tmp.tv_sec--;
+- tmp.tv_usec += 1000000L;
+- diff.tv_sec = tmp.tv_sec - then->tv_sec;
+- diff.tv_usec = tmp.tv_usec - then->tv_usec;
+- if (diff.tv_usec >= 1000000L) {
+- diff.tv_usec -= 1000000L;
+- diff.tv_sec++;
+- }
+- if (diff.tv_usec >= 500000L)
+- return (u_int)(diff.tv_sec + 1);
+- return (u_int)(diff.tv_sec);
++ struct timeval diff;
++
++ NETSNMP_TIMERSUB(now, then, &diff);
++ return diff.tv_sec + (diff.tv_usec >= 500000L);
+ }
+ #endif /* NETSNMP_FEATURE_REMOVE_CALCULATE_SECTIME_DIFF */
+
+@@ -1171,8 +1166,17 @@ mkdirhier(const char *pathname, mode_t mode, int skiplast)
+ struct stat sbuf;
+ char *ourcopy = strdup(pathname);
+ char *entry;
+- char buf[SNMP_MAXPATH];
++ char *buf = NULL;
+ char *st = NULL;
++ int res;
++
++ res = SNMPERR_GENERR;
++ if (!ourcopy)
++ goto out;
++
++ buf = malloc(strlen(pathname) + 2);
++ if (!buf)
++ goto out;
+
+ #if defined (WIN32) || defined (cygwin)
+ /* convert backslash to forward slash */
+@@ -1215,12 +1219,9 @@ mkdirhier(const char *pathname, mode_t mode, int skiplast)
+ #else
+ if (mkdir(buf, mode) == -1)
+ #endif
+- {
+- free(ourcopy);
+- return SNMPERR_GENERR;
+- } else {
++ goto out;
++ else
+ snmp_log(LOG_INFO, "Created directory: %s\n", buf);
+- }
+ } else {
+ /*
+ * exists, is it a file?
+@@ -1229,13 +1230,15 @@ mkdirhier(const char *pathname, mode_t mode, int skiplast)
+ /*
+ * ack! can't make a directory on top of a file
+ */
+- free(ourcopy);
+- return SNMPERR_GENERR;
++ goto out;
+ }
+ }
+ }
++ res = SNMPERR_SUCCESS;
++out:
++ free(buf);
+ free(ourcopy);
+- return SNMPERR_SUCCESS;
++ return res;
+ }
+
+ /**
+@@ -1254,9 +1257,14 @@ netsnmp_mktemp(void)
+ #endif
+ int fd = -1;
+
+- strcpy(name, get_temp_file_pattern());
++ strlcpy(name, get_temp_file_pattern(), sizeof(name));
+ #ifdef HAVE_MKSTEMP
+- fd = mkstemp(name);
++ {
++ mode_t oldmask = umask(~(S_IRUSR | S_IWUSR));
++ netsnmp_assert(oldmask != -1);
++ fd = mkstemp(name);
++ umask(oldmask);
++ }
+ #else
+ if (mktemp(name)) {
+ # ifndef WIN32
+@@ -1353,6 +1361,15 @@ netsnmp_os_kernel_width(void)
+
+ netsnmp_feature_child_of(str_to_uid, user_information)
+ #ifndef NETSNMP_FEATURE_REMOVE_STR_TO_UID
++/**
++ * Convert a user name or number into numeric form.
++ *
++ * @param[in] useroruid Either a Unix user name or the ASCII representation
++ * of a user number.
++ *
++ * @return Either a user number > 0 or 0 if useroruid is not a valid user
++ * name, not a valid user number or the name of the root user.
++ */
+ int netsnmp_str_to_uid(const char *useroruid) {
+ int uid;
+ #if HAVE_GETPWNAM && HAVE_PWD_H
+@@ -1361,13 +1378,13 @@ int netsnmp_str_to_uid(const char *useroruid) {
+
+ uid = atoi(useroruid);
+
+- if ( uid == 0 ) {
++ if (uid == 0) {
+ #if HAVE_GETPWNAM && HAVE_PWD_H
+- pwd = getpwnam( useroruid );
+- if (pwd)
+- uid = pwd->pw_uid;
+- else
++ pwd = getpwnam(useroruid);
++ uid = pwd ? pwd->pw_uid : 0;
++ endpwent();
+ #endif
++ if (uid == 0)
+ snmp_log(LOG_WARNING, "Can't identify user (%s).\n", useroruid);
+ }
+ return uid;
+@@ -1377,23 +1394,31 @@ int netsnmp_str_to_uid(const char *useroruid) {
+
+ netsnmp_feature_child_of(str_to_gid, user_information)
+ #ifndef NETSNMP_FEATURE_REMOVE_STR_TO_GID
+-int netsnmp_str_to_gid(const char *grouporgid) {
++/**
++ * Convert a group name or number into numeric form.
++ *
++ * @param[in] grouporgid Either a Unix group name or the ASCII representation
++ * of a group number.
++ *
++ * @return Either a group number > 0 or 0 if grouporgid is not a valid group
++ * name, not a valid group number or the root group.
++ */
++int netsnmp_str_to_gid(const char *grouporgid)
++{
+ int gid;
+-#if HAVE_GETGRNAM && HAVE_GRP_H
+- struct group *grp;
+-#endif
+
+ gid = atoi(grouporgid);
+
+- if ( gid == 0 ) {
++ if (gid == 0) {
+ #if HAVE_GETGRNAM && HAVE_GRP_H
+- grp = getgrnam( grouporgid );
+- if (grp)
+- gid = grp->gr_gid;
+- else
++ struct group *grp;
++
++ grp = getgrnam(grouporgid);
++ gid = grp ? grp->gr_gid : 0;
++ endgrent();
+ #endif
+- snmp_log(LOG_WARNING, "Can't identify group (%s).\n",
+- grouporgid);
++ if (gid == 0)
++ snmp_log(LOG_WARNING, "Can't identify group (%s).\n", grouporgid);
+ }
+
+ return gid;
+diff --git a/snmplib/test_binary_array.c b/snmplib/test_binary_array.c
+deleted file mode 100644
+index 44b1f0e..0000000
+--- a/snmplib/test_binary_array.c
++++ /dev/null
+@@ -1,171 +0,0 @@
+-#include <net-snmp/net-snmp-config.h>
+-
+-#if HAVE_IO_H
+-#include <io.h>
+-#endif
+-#include <stdio.h>
+-#if HAVE_STDLIB_H
+-#include <stdlib.h>
+-#endif
+-#if HAVE_MALLOC_H
+-#include <malloc.h>
+-#endif
+-#include <sys/types.h>
+-#if HAVE_STRING_H
+-#include <string.h>
+-#else
+-#include <strings.h>
+-#endif
+-
+-#include <net-snmp/net-snmp-includes.h>
+-#include <net-snmp/types.h>
+-#include <net-snmp/library/snmp_api.h>
+-#include <net-snmp/library/container.h>
+-#include <net-snmp/library/container_binary_array.h>
+-#include <net-snmp/library/tools.h>
+-#include <net-snmp/library/snmp_assert.h>
+-
+-#define TEST_SIZE 7
+-
+-void
+-print_int(netsnmp_index *i, void *v)
+-{
+- printf("item %p = %ld\n", i, i->oids[0]);
+-}
+-
+-int
+-test_int(void)
+-{
+- oid o1 = 1;
+- oid o2 = 2;
+- oid o3 = 6;
+- oid o4 = 8;
+- oid o5 = 9;
+- oid ox = 7;
+- oid oy = 10;
+- netsnmp_index i1,i2,i3,i4,i5,ix,iy, *ip;
+- netsnmp_index *a[TEST_SIZE] = { &i1, &i2, &i3, &ix, &i4, &i5, &iy };
+- netsnmp_container *c = netsnmp_container_get_binary_array();
+- int i;
+-
+- c->compare = netsnmp_compare_netsnmp_index;
+-
+- i1.oids = &o1;
+- i2.oids = &o2;
+- i3.oids = &o3;
+- i4.oids = &o4;
+- i5.oids = &o5;
+- ix.oids = &ox;
+- iy.oids = &oy;
+- i1.len = i2.len = i3.len = i4.len = i5.len = ix.len = iy.len = 1;
+-
+- printf("Creating container...\n");
+-
+- printf("Inserting data...\n");
+- CONTAINER_INSERT(c,&i4);
+- CONTAINER_INSERT(c,&i2);
+- CONTAINER_INSERT(c,&i3);
+- CONTAINER_INSERT(c,&i1);
+- CONTAINER_INSERT(c,&i5);
+-
+- printf("For each...\n");
+- CONTAINER_FOR_EACH(c, print_int, NULL);
+- printf("Done.\n");
+-
+- printf("\n");
+- ip = CONTAINER_FIRST(c);
+- printf("Find first = %p %ld\n",ip, ip->oids[0]);
+- while( ip ) {
+- ip = CONTAINER_NEXT(c,ip);
+- if(ip)
+- printf("Find next = %p %ld\n",ip, ip->oids[0]);
+- else
+- printf("Find next = %s\n",ip);
+- }
+-
+- for( i=0; i < TEST_SIZE; ++i) {
+- printf("\n");
+- ip = CONTAINER_FIND(c,a[i]);
+- printf("Find %ld = %p %ld\n", a[i]->oids[0], ip, ip ? ip->oids[0] : 0);
+- ip = CONTAINER_NEXT(c,a[i]);
+- printf("Next %ld = %p %ld\n", a[i]->oids[0], ip, ip ? ip->oids[0] : 0);
+- }
+-
+- printf("Done.\n");
+-
+- return 0;
+-}
+-
+-void
+-print_string(char *i, void *v)
+-{
+- printf("item %s\n", i);
+-}
+-
+-int
+-my_strcmp(char *lhs, char *rhs)
+-{
+- int rc = strcmp(lhs,rhs);
+-/* printf("%s %d %s\n",lhs, rc, rhs); */
+- return rc;
+-}
+-
+-int
+-test_string()
+-{
+- const char *o1 = "zebra";
+- const char *o2 = "b-two";
+- const char *o3 = "b";
+- const char *o4 = "cedar";
+- const char *o5 = "alpha";
+- const char *ox = "dev";
+- const char *oy = "aa";
+- const char * ip;
+-
+- const char *a[TEST_SIZE] = { o1, o2, o3, ox, o4, o5, oy };
+- netsnmp_container *c = netsnmp_container_get_binary_array();
+- int i;
+-
+- c->compare = my_strcmp;
+-
+- printf("Creating container...\n");
+-
+- printf("Inserting data...\n");
+- CONTAINER_INSERT(c,o4);
+- CONTAINER_INSERT(c,o2);
+- CONTAINER_INSERT(c,o3);
+- CONTAINER_INSERT(c,o1);
+- CONTAINER_INSERT(c,o5);
+- printf("\n");
+- printf("For each...\n");
+- CONTAINER_FOR_EACH(c, print_string, NULL);
+- printf("Done.\n");
+-
+- printf("\n");
+- ip = CONTAINER_FIRST(c);
+- printf("Find first = %s\n",ip);
+- while( ip ) {
+- ip = CONTAINER_NEXT(c,ip);
+- printf("Find next = %s\n",ip);
+- }
+-
+- for( i=0; i < TEST_SIZE; ++i) {
+- printf("\n");
+- ip = CONTAINER_FIND(c,a[i]);
+- printf("Find %s = %s\n", a[i], ip);
+- ip = CONTAINER_NEXT(c,a[i]);
+- printf("Next %s = %s\n", a[i], ip);
+- }
+-
+- printf("Done.\n");
+-
+- return 0;
+-}
+-
+-int
+-main(int argc, char** argv)
+-{
+-
+- test_int();
+- test_string();
+-}
+diff --git a/snmplib/tools.c b/snmplib/tools.c
+index 676f36c..b2be790 100644
+--- a/snmplib/tools.c
++++ b/snmplib/tools.c
+@@ -613,7 +613,7 @@ void
+ dump_chunk(const char *debugtoken, const char *title, const u_char * buf,
+ int size)
+ {
+- u_int printunit = 64; /* XXX Make global. */
++ int printunit = 64; /* XXX Make global. */
+ char chunk[SNMP_MAXBUF], *s, *sp;
+
+ if (title && (*title != '\0')) {
+@@ -626,8 +626,8 @@ dump_chunk(const char *debugtoken, const char *title, const u_char * buf,
+ sp = s;
+
+ while (size > 0) {
+- if (size > (int) printunit) {
+- strncpy(chunk, sp, printunit);
++ if (size > printunit) {
++ memcpy(chunk, sp, printunit);
+ chunk[printunit] = '\0';
+ DEBUGMSGTL((debugtoken, "\t%s\n", chunk));
+ } else {
+@@ -803,15 +803,10 @@ dump_snmpEngineID(const u_char * estring, size_t * estring_len)
+
+ case 4: /* Text. */
+
+- /*
+- * Doesn't exist on all (many) architectures
+- */
+- /*
+- * s += snprintf(s, remaining_len+3, "\"%s\"", esp);
+- */
+- s += sprintf(s, "\"%.*s\"", sizeof(buf)-strlen(buf)-3, esp);
++ s += sprintf(s, "\"%.*s\"", (int) (sizeof(buf)-strlen(buf)-3), esp);
+ goto dump_snmpEngineID_quit;
+ break;
++
+ /*NOTREACHED*/ case 5: /* Octets. */
+
+ snprint_hexstring(s, (SNMP_MAXBUF - (s-buf)),
+@@ -820,6 +815,7 @@ dump_snmpEngineID(const u_char * estring, size_t * estring_len)
+ s -= 1;
+ goto dump_snmpEngineID_quit;
+ break;
++
+ /*NOTREACHED*/ dump_snmpEngineID_violation:
+ case 0: /* Violation of RESERVED,
+ * * -OR- of expected length.
+@@ -941,11 +937,11 @@ uatime_hdiff(const_marker_t first, const_marker_t second)
+ }
+
+ /**
+- * Test: Has (marked time plus delta) exceeded current time (in msec) ?
++ * Test: Has (marked time plus delta) exceeded current time ?
+ * Returns 0 if test fails or cannot be tested (no marker).
+ */
+ int
+-atime_ready(const_marker_t pm, int deltaT)
++atime_ready(const_marker_t pm, int delta_ms)
+ {
+ marker_t now;
+ long diff;
+@@ -956,19 +952,19 @@ atime_ready(const_marker_t pm, int deltaT)
+
+ diff = atime_diff(pm, now);
+ free(now);
+- if (diff < deltaT)
++ if (diff < delta_ms)
+ return 0;
+
+ return 1;
+ }
+
++#ifndef NETSNMP_FEATURE_REMOVE_UATIME_READY
+ /**
+- * Test: Has (marked time plus delta) exceeded current time (in msec) ?
++ * Test: Has (marked time plus delta) exceeded current time ?
+ * Returns 0 if test fails or cannot be tested (no marker).
+ */
+-#ifndef NETSNMP_FEATURE_REMOVE_UATIME_READY
+ int
+-uatime_ready(const_marker_t pm, unsigned int deltaT)
++uatime_ready(const_marker_t pm, unsigned int delta_ms)
+ {
+ marker_t now;
+ u_long diff;
+@@ -979,7 +975,7 @@ uatime_ready(const_marker_t pm, unsigned int deltaT)
+
+ diff = uatime_diff(pm, now);
+ free(now);
+- if (diff < deltaT)
++ if (diff < delta_ms)
+ return 0;
+
+ return 1;
+diff --git a/snmplib/transports/snmpAAL5PVCDomain.c b/snmplib/transports/snmpAAL5PVCDomain.c
+index f6684f0..5ac69a1 100644
+--- a/snmplib/transports/snmpAAL5PVCDomain.c
++++ b/snmplib/transports/snmpAAL5PVCDomain.c
+@@ -32,6 +32,7 @@
+ #include <net-snmp/config_api.h>
+
+ #include <net-snmp/library/snmp_transport.h>
++#include <net-snmp/library/tools.h>
+
+
+ oid netsnmp_AAL5PVCDomain[10] = { NETSNMP_ENTERPRISE_MIB, 3, 3, 3 };
+@@ -87,11 +88,13 @@ netsnmp_aal5pvc_recv(netsnmp_transport *t, void *buf, int size,
+ }
+
+ if (rc >= 0) {
+- char *str = netsnmp_aal5pvc_fmtaddr(t, NULL, 0);
+- DEBUGMSGTL(("netsnmp_aal5pvc",
+- "recv on fd %d got %d bytes (from %s)\n", t->sock,
+- rc, str));
+- free(str);
++ DEBUGIF("netsnmp_aal5pvc") {
++ char *str = netsnmp_aal5pvc_fmtaddr(t, NULL, 0);
++ DEBUGMSGTL(("netsnmp_aal5pvc",
++ "recv on fd %d got %d bytes (from %s)\n", t->sock,
++ rc, str));
++ free(str);
++ }
+ } else {
+ DEBUGMSGTL(("netsnmp_aal5pvc", "recv on fd %d err %d (\"%s\")\n",
+ t->sock, errno, strerror(errno)));
+@@ -120,11 +123,14 @@ netsnmp_aal5pvc_send(netsnmp_transport *t, void *buf, int size,
+ }
+
+ if (to != NULL && t != NULL && t->sock >= 0) {
+- char *str = netsnmp_aal5pvc_fmtaddr(NULL, (void *)to,
+- sizeof(struct sockaddr_atmpvc));
+- DEBUGMSGTL(("netsnmp_aal5pvc","send %d bytes from %p to %s on fd %d\n",
+- size, buf, str, t->sock));
+- free(str);
++ DEBUGIF("netsnmp_aal5pvc") {
++ char *str = netsnmp_aal5pvc_fmtaddr(NULL, (void *)to,
++ sizeof(struct sockaddr_atmpvc));
++ DEBUGMSGTL(("netsnmp_aal5pvc",
++ "send %d bytes from %p to %s on fd %d\n",
++ size, buf, str, t->sock));
++ free(str);
++ }
+ while (rc < 0) {
+ rc = sendto(t->sock, buf, size, 0, NULL, 0);
+ if (rc < 0 && errno != EINTR) {
+@@ -165,8 +171,6 @@ netsnmp_aal5pvc_close(netsnmp_transport *t)
+ netsnmp_transport *
+ netsnmp_aal5pvc_transport(struct sockaddr_atmpvc *addr, int local)
+ {
+- char *str = NULL;
+- struct atm_qos qos;
+ netsnmp_transport *t = NULL;
+
+ #ifdef NETSNMP_NO_LISTEN_SUPPORT
+@@ -178,18 +182,18 @@ netsnmp_aal5pvc_transport(struct sockaddr_atmpvc *addr, int local)
+ return NULL;
+ }
+
+- t = (netsnmp_transport *) malloc(sizeof(netsnmp_transport));
++ t = SNMP_MALLOC_TYPEDEF(netsnmp_transport);
+ if (t == NULL) {
+ return NULL;
+ }
+
+- str = netsnmp_aal5pvc_fmtaddr(NULL, (void *) addr,
+- sizeof(struct sockaddr_atmpvc));
+- DEBUGMSGTL(("netsnmp_aal5pvc", "open %s %s\n", local ? "local" : "remote",
+- str));
+- free(str);
+-
+- memset(t, 0, sizeof(netsnmp_transport));
++ DEBUGIF("netsnmp_aal5pvc") {
++ char *str = netsnmp_aal5pvc_fmtaddr(NULL, (void *) addr,
++ sizeof(struct sockaddr_atmpvc));
++ DEBUGMSGTL(("netsnmp_aal5pvc", "open %s %s\n",
++ local ? "local" : "remote", str));
++ free(str);
++ }
+
+ t->domain = netsnmp_AAL5PVCDomain;
+ t->domain_length =
+@@ -203,22 +207,24 @@ netsnmp_aal5pvc_transport(struct sockaddr_atmpvc *addr, int local)
+ }
+ DEBUGMSGTL(("netsnmp_aal5pvc", "fd %d opened\n", t->sock));
+
+- /*
+- * Set up the QOS parameters.
+- */
++ {
++ /*
++ * Set up the QOS parameters.
++ */
+
+- memset(&qos, 0, sizeof(struct atm_qos));
+- qos.aal = ATM_AAL5;
+- qos.rxtp.traffic_class = ATM_UBR;
+- qos.rxtp.max_sdu = SNMP_MAX_LEN; /* Hmm -- this is a bit small? */
+- qos.txtp = qos.rxtp;
++ struct atm_qos qos = { 0 };
++ qos.aal = ATM_AAL5;
++ qos.rxtp.traffic_class = ATM_UBR;
++ qos.rxtp.max_sdu = SNMP_MAX_LEN; /* Hmm -- this is a bit small? */
++ qos.txtp = qos.rxtp;
+
+- if (setsockopt(t->sock, SOL_ATM, SO_ATMQOS, &qos, sizeof(qos)) < 0) {
+- DEBUGMSGTL(("netsnmp_aal5pvc", "setsockopt failed (%s)\n",
+- strerror(errno)));
+- netsnmp_aal5pvc_close(t);
+- netsnmp_transport_free(t);
+- return NULL;
++ if (setsockopt(t->sock, SOL_ATM, SO_ATMQOS, &qos, sizeof(qos)) < 0) {
++ DEBUGMSGTL(("netsnmp_aal5pvc", "setsockopt failed (%s)\n",
++ strerror(errno)));
++ netsnmp_aal5pvc_close(t);
++ netsnmp_transport_free(t);
++ return NULL;
++ }
+ }
+
+ if (local) {
+diff --git a/snmplib/transports/snmpCallbackDomain.c b/snmplib/transports/snmpCallbackDomain.c
+index e487f28..95018b8 100644
+--- a/snmplib/transports/snmpCallbackDomain.c
++++ b/snmplib/transports/snmpCallbackDomain.c
+@@ -353,7 +353,7 @@ netsnmp_callback_accept(netsnmp_transport *t)
+ {
+ DEBUGMSGTL(("transport_callback", "hook_accept enter\n"));
+ DEBUGMSGTL(("transport_callback", "hook_accept exit\n"));
+- return 0;
++ return -1;
+ }
+
+
+@@ -385,8 +385,10 @@ netsnmp_callback_transport(int to)
+ * our stuff
+ */
+ mydata = SNMP_MALLOC_TYPEDEF(netsnmp_callback_info);
+- if (!mydata)
++ if (!mydata) {
++ SNMP_FREE(t);
+ return NULL;
++ }
+ mydata->linkedto = to;
+ mydata->callback_num = ++callback_count;
+ mydata->data = NULL;
+diff --git a/snmplib/transports/snmpDTLSUDPDomain.c b/snmplib/transports/snmpDTLSUDPDomain.c
+index fcbc5a2..9c56d19 100644
+--- a/snmplib/transports/snmpDTLSUDPDomain.c
++++ b/snmplib/transports/snmpDTLSUDPDomain.c
+@@ -231,8 +231,10 @@ start_new_cached_connection(netsnmp_transport *t,
+ return NULL;
+
+ /* allocate our TLS specific data */
+- if (NULL == (tlsdata = netsnmp_tlsbase_allocate_tlsdata(t, !we_are_client)))
++ if (NULL == (tlsdata = netsnmp_tlsbase_allocate_tlsdata(t, !we_are_client))) {
++ SNMP_FREE(cachep);
+ return NULL;
++ }
+ cachep->tlsdata = tlsdata;
+
+ /* RFC5953: section 5.3.1, step 1:
+@@ -427,7 +429,7 @@ _extract_addr_pair(netsnmp_transport *t, void *opaque, int olen)
+
+ if (opaque && olen == sizeof(netsnmp_tmStateReference)) {
+ netsnmp_tmStateReference *tmStateRef =
+- tmStateRef = (netsnmp_tmStateReference *) opaque;
++ (netsnmp_tmStateReference *) opaque;
+
+ if (tmStateRef->have_addresses)
+ addr_pair = &(tmStateRef->addresses);
+@@ -817,6 +819,7 @@ netsnmp_dtlsudp_recv(netsnmp_transport *t, void *buf, int size,
+ DEBUGMSGTL(("dtlsudp", "peer disconnected\n"));
+ cachep->flags |= NETSNMP_BIO_DISCONNECTED;
+ remove_and_free_bio_cache(cachep);
++ SNMP_FREE(tmStateRef);
+ return rc;
+ }
+ cachep->flags |= NETSNMP_BIO_CONNECTED;
+@@ -913,6 +916,7 @@ netsnmp_dtlsudp_recv(netsnmp_transport *t, void *buf, int size,
+ /* XXX: probably need to check for whether we should
+ send stuff from our end to continue the transaction
+ */
++ SNMP_FREE(tmStateRef);
+ return -1;
+ } else {
+ /* XXX: free needed memory */
+@@ -922,6 +926,7 @@ netsnmp_dtlsudp_recv(netsnmp_transport *t, void *buf, int size,
+ /* Step 5 says these are always incremented */
+ snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONINVALIDSERVERCERTIFICATES);
+ snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONOPENERRORS);
++ SNMP_FREE(tmStateRef);
+ return -1;
+ }
+ }
+@@ -939,12 +944,14 @@ netsnmp_dtlsudp_recv(netsnmp_transport *t, void *buf, int size,
+ /* XXX: probably need to check for whether we should
+ send stuff from our end to continue the transaction
+ */
++ SNMP_FREE(tmStateRef);
+ return -1;
+ } else {
+ /* XXX: free needed memory */
+ snmp_log(LOG_ERR,
+ "DTLSUDP: failed to verify ssl certificate (of the client)\n");
+ snmp_increment_statistic(STAT_TLSTM_SNMPTLSTMSESSIONINVALIDCLIENTCERTIFICATES);
++ SNMP_FREE(tmStateRef);
+ return -1;
+ }
+ }
+@@ -1061,7 +1068,7 @@ netsnmp_dtlsudp_send(netsnmp_transport *t, void *buf, int size,
+ specs) then we create one automatically here.
+ */
+ if (opaque != NULL && *opaque != NULL &&
+- *olength == sizeof(netsnmp_tmStateReference))
++ olength != NULL && *olength == sizeof(netsnmp_tmStateReference))
+ tmStateRef = (netsnmp_tmStateReference *) *opaque;
+
+
+@@ -1506,13 +1513,11 @@ netsnmp_dtlsudp_create_tstring(const char *str, int isserver,
+ tlsdata = (_netsnmpTLSBaseData *) t->data;
+ /* search for a : */
+ if (NULL != (cp = strrchr(str, ':'))) {
+- strncpy(buf, str, SNMP_MIN(cp-str, sizeof(buf)-1));
+- buf[SNMP_MIN(cp-str, sizeof(buf)-1)] = '\0';
++ sprintf(buf, "%.*s", (int) SNMP_MIN(cp - str, sizeof(buf) - 1),
++ str);
+ } else {
+ /* else the entire spec is a host name only */
+- strncpy(buf, str,
+- SNMP_MIN(strlen(str), sizeof(buf)-1));
+- buf[SNMP_MIN(strlen(str), sizeof(buf)-1)] = '\0';
++ strlcpy(buf, str, sizeof(buf));
+ }
+ tlsdata->their_hostname = strdup(buf);
+ }
+diff --git a/snmplib/transports/snmpIPXDomain.c b/snmplib/transports/snmpIPXDomain.c
+index 75994d4..24c13a4 100644
+--- a/snmplib/transports/snmpIPXDomain.c
++++ b/snmplib/transports/snmpIPXDomain.c
+@@ -34,6 +34,7 @@
+ #include <net-snmp/config_api.h>
+
+ #include <net-snmp/library/snmp_transport.h>
++#include <net-snmp/library/tools.h>
+
+ #define SNMP_IPX_DEFAULT_PORT 36879 /* Specified in RFC 1420. */
+ static netsnmp_tdomain ipxDomain;
+@@ -99,10 +100,13 @@ netsnmp_ipx_recv(netsnmp_transport *t, void *buf, int size,
+ }
+
+ if (rc >= 0) {
+- char *str = netsnmp_ipx_fmtaddr(NULL, from, fromlen);
+- DEBUGMSGTL(("netsnmp_ipx","recvfrom fd %d got %d bytes(from %s)\n",
+- t->sock, rc, str));
+- free(str);
++ DEBUGIF("netsnmp_ipx") {
++ char *str = netsnmp_ipx_fmtaddr(NULL, from, fromlen);
++ DEBUGMSGTL(("netsnmp_ipx",
++ "recvfrom fd %d got %d bytes(from %s)\n",
++ t->sock, rc, str));
++ free(str);
++ }
+ } else {
+ DEBUGMSGTL(("netsnmp_ipx", "recvfrom fd %d err %d (\"%s\")\n",
+ t->sock, errno, strerror(errno)));
+@@ -131,11 +135,13 @@ netsnmp_ipx_send(netsnmp_transport *t, void *buf, int size,
+ }
+
+ if (to != NULL && t != NULL && t->sock >= 0) {
+- char *str = netsnmp_ipx_fmtaddr(NULL, (void *)to,
+- sizeof(struct sockaddr_ipx));
+- DEBUGMSGTL(("netsnmp_ipx", "send %d bytes from %p to %s on fd %d\n",
+- size, buf, str, t->sock));
+- free(str);
++ DEBUGIF("netsnmp_ipx") {
++ char *str = netsnmp_ipx_fmtaddr(NULL, (void *)to,
++ sizeof(struct sockaddr_ipx));
++ DEBUGMSGTL(("netsnmp_ipx", "send %d bytes from %p to %s on fd %d\n",
++ size, buf, str, t->sock));
++ free(str);
++ }
+ while (rc < 0) {
+ rc = sendto(t->sock, buf, size, 0, to, sizeof(struct sockaddr));
+ if (rc < 0 && errno != EINTR) {
+@@ -176,7 +182,6 @@ netsnmp_ipx_transport(struct sockaddr_ipx *addr, int local)
+ {
+ netsnmp_transport *t = NULL;
+ int rc = 0;
+- char *str = NULL;
+
+ #ifdef NETSNMP_NO_LISTEN_SUPPORT
+ if (local)
+@@ -187,18 +192,18 @@ netsnmp_ipx_transport(struct sockaddr_ipx *addr, int local)
+ return NULL;
+ }
+
+- t = (netsnmp_transport *) malloc(sizeof(netsnmp_transport));
++ t = SNMP_MALLOC_TYPEDEF(netsnmp_transport);
+ if (t == NULL) {
+ return NULL;
+ }
+
+- str = netsnmp_ipx_fmtaddr(NULL, (void *)addr,
+- sizeof(struct sockaddr_ipx));
+- DEBUGMSGTL(("netsnmp_ipx", "open %s %s\n", local ? "local" : "remote",
+- str));
+- free(str);
+-
+- memset(t, 0, sizeof(netsnmp_transport));
++ DEBUGIF("netsnmp_ipx") {
++ char *str = netsnmp_ipx_fmtaddr(NULL, (void *)addr,
++ sizeof(struct sockaddr_ipx));
++ DEBUGMSGTL(("netsnmp_ipx", "open %s %s\n", local ? "local" : "remote",
++ str));
++ free(str);
++ }
+
+ t->domain = netsnmpIPXDomain;
+ t->domain_length = netsnmpIPXDomain_len;
+@@ -358,9 +363,7 @@ netsnmp_sockaddr_ipx2(struct sockaddr_ipx *addr, const char *peername,
+ node = "000000000000";
+
+ if (port == NULL || *port == '\0')
+-#define val(x) __STRING(x)
+- port = val(SNMP_IPX_DEFAULT_PORT);
+-#undef val
++ port = __STRING(SNMP_IPX_DEFAULT_PORT);
+
+ DEBUGMSGTL(("netsnmp_sockaddr_ipx", "Address: %s:%s/%s\n",
+ network ? network : "[NIL]", node ? node : "[NIL]",
+diff --git a/snmplib/transports/snmpIPv6BaseDomain.c b/snmplib/transports/snmpIPv6BaseDomain.c
+index a7daf1c..9bad950 100644
+--- a/snmplib/transports/snmpIPv6BaseDomain.c
++++ b/snmplib/transports/snmpIPv6BaseDomain.c
+@@ -127,7 +127,6 @@ netsnmp_sockaddr_in6_2(struct sockaddr_in6 *addr,
+ char debug_addr[INET6_ADDRSTRLEN];
+ #if HAVE_GETADDRINFO
+ struct addrinfo *addrs = NULL;
+- struct addrinfo hint;
+ int err;
+ #elif HAVE_GETIPNODEBYNAME
+ struct hostent *hp = NULL;
+@@ -333,13 +332,15 @@ netsnmp_sockaddr_in6_2(struct sockaddr_in6 *addr,
+ }
+
+ #if HAVE_GETADDRINFO
+- memset(&hint, 0, sizeof hint);
+- hint.ai_flags = 0;
+- hint.ai_family = PF_INET6;
+- hint.ai_socktype = SOCK_DGRAM;
+- hint.ai_protocol = 0;
+-
+- err = netsnmp_getaddrinfo(peername, NULL, &hint, &addrs);
++ {
++ struct addrinfo hint = { 0 };
++ hint.ai_flags = 0;
++ hint.ai_family = PF_INET6;
++ hint.ai_socktype = SOCK_DGRAM;
++ hint.ai_protocol = 0;
++
++ err = netsnmp_getaddrinfo(peername, NULL, &hint, &addrs);
++ }
+ if (err != 0) {
+ #if HAVE_GAI_STRERROR
+ snmp_log(LOG_ERR, "getaddrinfo(\"%s\", NULL, ...): %s\n", peername,
+diff --git a/snmplib/transports/snmpSSHDomain.c b/snmplib/transports/snmpSSHDomain.c
+index 72cc59e..a9ed81f 100644
+--- a/snmplib/transports/snmpSSHDomain.c
++++ b/snmplib/transports/snmpSSHDomain.c
+@@ -236,9 +236,8 @@ netsnmp_ssh_recv(netsnmp_transport *t, void *buf, int size,
+ user_pw->pw_name);
+ return -1;
+ }
+- strncpy(addr_pair->username, user_pw->pw_name,
++ strlcpy(addr_pair->username, user_pw->pw_name,
+ sizeof(addr_pair->username));
+- addr_pair->username[sizeof(addr_pair->username)-1] = '\0';
+ }
+ DEBUGMSGTL(("ssh", "Setting user name to %s\n",
+ addr_pair->username));
+@@ -309,9 +308,8 @@ netsnmp_ssh_recv(netsnmp_transport *t, void *buf, int size,
+ user_pw->pw_name);
+ return -1;
+ }
+- strncpy(addr_pair->username, user_pw->pw_name,
++ strlcpy(addr_pair->username, user_pw->pw_name,
+ sizeof(addr_pair->username));
+- addr_pair->username[sizeof(addr_pair->username)-1] = '\0';
+ }
+ */
+
+@@ -330,12 +328,12 @@ netsnmp_ssh_recv(netsnmp_transport *t, void *buf, int size,
+ if (iamclient && 0) {
+ /* XXX: we're on the client; we should have named the
+ connection ourselves... pull this from session somehow? */
+- strncpy(tmStateRef->securityName, addr_pair->username,
+- sizeof(tmStateRef->securityName)-1);
++ strlcpy(tmStateRef->securityName, addr_pair->username,
++ sizeof(tmStateRef->securityName));
+ } else {
+ #ifdef SNMPSSHDOMAIN_USE_EXTERNAL_PIPE
+- strncpy(tmStateRef->securityName, addr_pair->username,
+- sizeof(tmStateRef->securityName)-1);
++ strlcpy(tmStateRef->securityName, addr_pair->username,
++ sizeof(tmStateRef->securityName));
+ #else /* we're called directly by sshd and use stdin/out */
+ /* we're on the server... */
+ /* XXX: this doesn't copy properly and can get pointer
+@@ -349,8 +347,8 @@ netsnmp_ssh_recv(netsnmp_transport *t, void *buf, int size,
+
+ /* XXX: detect and throw out overflow secname sizes rather
+ than truncating. */
+- strncpy(tmStateRef->securityName, getenv("USER"),
+- sizeof(tmStateRef->securityName)-1);
++ strlcpy(tmStateRef->securityName, getenv("USER"),
++ sizeof(tmStateRef->securityName));
+ #endif /* ! SNMPSSHDOMAIN_USE_EXTERNAL_PIPE */
+ }
+ tmStateRef->securityName[sizeof(tmStateRef->securityName)-1] = '\0';
+@@ -389,9 +387,8 @@ netsnmp_ssh_send(netsnmp_transport *t, void *buf, int size,
+
+ if (NULL != t && NULL != addr_pair && NULL != addr_pair->channel) {
+ if (addr_pair->username[0] == '\0') {
+- strncpy(addr_pair->username, tmStateRef->securityName,
+- sizeof(addr_pair->username)-1);
+- addr_pair->username[sizeof(addr_pair->username)-1] = '\0';
++ strlcpy(addr_pair->username, tmStateRef->securityName,
++ sizeof(addr_pair->username));
+ } else if (strcmp(addr_pair->username, tmStateRef->securityName) != 0 ||
+ strlen(addr_pair->username) != tmStateRef->securityNameLen) {
+ /* error! they must always match */
+@@ -599,7 +596,6 @@ netsnmp_ssh_transport(struct sockaddr_in *addr, int local)
+ if (t == NULL) {
+ return NULL;
+ }
+- memset(t, 0, sizeof(netsnmp_transport));
+
+ t->domain = netsnmp_snmpSSHDomain;
+ t->domain_length = netsnmp_snmpSSHDomain_len;
+@@ -728,7 +724,6 @@ netsnmp_ssh_transport(struct sockaddr_in *addr, int local)
+ #endif /* NETSNMP_NO_LISTEN_SUPPORT */
+ } else {
+ char *username;
+- size_t username_len;
+ char *keyfilepub;
+ char *keyfilepriv;
+
+@@ -740,7 +735,6 @@ netsnmp_ssh_transport(struct sockaddr_in *addr, int local)
+ snmp_log(LOG_ERR, "You must specify a ssh username to use. See the snmp.conf manual page\n");
+ return NULL;
+ }
+- username_len = strlen(username);
+
+ /* use the requested public key file */
+ keyfilepub = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
+diff --git a/snmplib/transports/snmpSTDDomain.c b/snmplib/transports/snmpSTDDomain.c
+index 21e0d79..0a1c3f9 100644
+--- a/snmplib/transports/snmpSTDDomain.c
++++ b/snmplib/transports/snmpSTDDomain.c
+@@ -154,11 +154,10 @@ netsnmp_std_transport(const char *instring, size_t instring_len,
+ {
+ netsnmp_transport *t;
+
+- t = (netsnmp_transport *) malloc(sizeof(netsnmp_transport));
++ t = SNMP_MALLOC_TYPEDEF(netsnmp_transport);
+ if (t == NULL) {
+ return NULL;
+ }
+- memset(t, 0, sizeof(netsnmp_transport));
+
+ t->domain = netsnmp_snmpSTDDomain;
+ t->domain_length =
+diff --git a/snmplib/transports/snmpTCPDomain.c b/snmplib/transports/snmpTCPDomain.c
+index 426ae08..b8bdba4 100644
+--- a/snmplib/transports/snmpTCPDomain.c
++++ b/snmplib/transports/snmpTCPDomain.c
+@@ -41,6 +41,7 @@
+ #include <net-snmp/library/snmpIPv4BaseDomain.h>
+ #include <net-snmp/library/snmpSocketBaseDomain.h>
+ #include <net-snmp/library/snmpTCPBaseDomain.h>
++#include <net-snmp/library/tools.h>
+
+ /*
+ * needs to be in sync with the definitions in snmplib/snmpUDPDomain.c
+@@ -77,7 +78,6 @@ netsnmp_tcp_accept(netsnmp_transport *t)
+ netsnmp_udp_addr_pair *addr_pair = NULL;
+ int newsock = -1;
+ socklen_t farendlen = sizeof(netsnmp_udp_addr_pair);
+- char *str = NULL;
+
+ addr_pair = (netsnmp_udp_addr_pair *)malloc(farendlen);
+ if (addr_pair == NULL) {
+@@ -106,9 +106,11 @@ netsnmp_tcp_accept(netsnmp_transport *t)
+
+ t->data = addr_pair;
+ t->data_length = sizeof(netsnmp_udp_addr_pair);
+- str = netsnmp_tcp_fmtaddr(NULL, farend, farendlen);
+- DEBUGMSGTL(("netsnmp_tcp", "accept succeeded (from %s)\n", str));
+- free(str);
++ DEBUGIF("netsnmp_tcp") {
++ char *str = netsnmp_tcp_fmtaddr(NULL, farend, farendlen);
++ DEBUGMSGTL(("netsnmp_tcp", "accept succeeded (from %s)\n", str));
++ free(str);
++ }
+
+ /*
+ * Try to make the new socket blocking.
+@@ -157,11 +159,10 @@ netsnmp_tcp_transport(struct sockaddr_in *addr, int local)
+ return NULL;
+ }
+
+- t = (netsnmp_transport *) malloc(sizeof(netsnmp_transport));
++ t = SNMP_MALLOC_TYPEDEF(netsnmp_transport);
+ if (t == NULL) {
+ return NULL;
+ }
+- memset(t, 0, sizeof(netsnmp_transport));
+
+ addr_pair = (netsnmp_udp_addr_pair *)malloc(sizeof(netsnmp_udp_addr_pair));
+ if (addr_pair == NULL) {
+diff --git a/snmplib/transports/snmpTCPIPv6Domain.c b/snmplib/transports/snmpTCPIPv6Domain.c
+index 5e866eb..3c96856 100644
+--- a/snmplib/transports/snmpTCPIPv6Domain.c
++++ b/snmplib/transports/snmpTCPIPv6Domain.c
+@@ -47,6 +47,7 @@
+ #include <net-snmp/library/snmp_transport.h>
+ #include <net-snmp/library/snmpSocketBaseDomain.h>
+ #include <net-snmp/library/snmpTCPBaseDomain.h>
++#include <net-snmp/library/tools.h>
+
+ #include "inet_ntop.h"
+
+@@ -70,7 +71,6 @@ netsnmp_tcp6_accept(netsnmp_transport *t)
+ struct sockaddr_in6 *farend = NULL;
+ int newsock = -1;
+ socklen_t farendlen = sizeof(struct sockaddr_in6);
+- char *str = NULL;
+
+ farend = (struct sockaddr_in6 *) malloc(sizeof(struct sockaddr_in6));
+
+@@ -98,9 +98,11 @@ netsnmp_tcp6_accept(netsnmp_transport *t)
+
+ t->data = farend;
+ t->data_length = farendlen;
+- str = netsnmp_tcp6_fmtaddr(NULL, farend, farendlen);
+- DEBUGMSGTL(("netsnmp_tcp6", "accept succeeded (from %s)\n", str));
+- free(str);
++ DEBUGIF("netsnmp_tcp6") {
++ char *str = netsnmp_tcp6_fmtaddr(NULL, farend, farendlen);
++ DEBUGMSGTL(("netsnmp_tcp6", "accept succeeded (from %s)\n", str));
++ free(str);
++ }
+
+ /*
+ * Try to make the new socket blocking.
+@@ -138,7 +140,6 @@ netsnmp_tcp6_transport(struct sockaddr_in6 *addr, int local)
+ {
+ netsnmp_transport *t = NULL;
+ int rc = 0;
+- char *str = NULL;
+
+ #ifdef NETSNMP_NO_LISTEN_SUPPORT
+ if (local)
+@@ -149,19 +150,18 @@ netsnmp_tcp6_transport(struct sockaddr_in6 *addr, int local)
+ return NULL;
+ }
+
+- t = (netsnmp_transport *) malloc(sizeof(netsnmp_transport));
++ t = SNMP_MALLOC_TYPEDEF(netsnmp_transport);
+ if (t == NULL) {
+ return NULL;
+ }
+- memset(t, 0, sizeof(netsnmp_transport));
+-
+- str = netsnmp_tcp6_fmtaddr(NULL, (void *)addr,
+- sizeof(struct sockaddr_in6));
+- DEBUGMSGTL(("netsnmp_tcp6", "open %s %s\n", local ? "local" : "remote",
+- str));
+- free(str);
+
+- memset(t, 0, sizeof(netsnmp_transport));
++ DEBUGIF("netsnmp_tcp6") {
++ char *str = netsnmp_tcp6_fmtaddr(NULL, (void *)addr,
++ sizeof(struct sockaddr_in6));
++ DEBUGMSGTL(("netsnmp_tcp6", "open %s %s\n", local ? "local" : "remote",
++ str));
++ free(str);
++ }
+
+ t->data = malloc(sizeof(netsnmp_indexed_addr_pair));
+ if (t->data == NULL) {
+@@ -169,7 +169,7 @@ netsnmp_tcp6_transport(struct sockaddr_in6 *addr, int local)
+ return NULL;
+ }
+ t->data_length = sizeof(netsnmp_indexed_addr_pair);
+- memcpy(t->data, addr, sizeof(netsnmp_indexed_addr_pair));
++ memcpy(t->data, addr, sizeof(struct sockaddr_in6));
+
+ t->domain = netsnmp_TCPIPv6Domain;
+ t->domain_length = sizeof(netsnmp_TCPIPv6Domain) / sizeof(oid);
+diff --git a/snmplib/transports/snmpTLSBaseDomain.c b/snmplib/transports/snmpTLSBaseDomain.c
+index 12a69c6..c54d6ad 100644
+--- a/snmplib/transports/snmpTLSBaseDomain.c
++++ b/snmplib/transports/snmpTLSBaseDomain.c
+@@ -51,6 +51,7 @@ netsnmp_feature_require(cert_util)
+ #include <net-snmp/library/snmp_transport.h>
+ #include <net-snmp/library/snmp_secmod.h>
+ #include <net-snmp/library/read_config.h>
++#include <net-snmp/library/system.h>
+
+ #define LOGANDDIE(msg) do { snmp_log(LOG_ERR, "%s\n", msg); return 0; } while(0)
+
+@@ -105,12 +106,13 @@ int verify_callback(int ok, X509_STORE_CTX *ctx) {
+ DEBUGMSGTL(("tls_x509:verify", "verify_callback called with: ok=%d ctx=%p depth=%d err=%i:%s\n", ok, ctx, depth, err, X509_verify_cert_error_string(err)));
+ DEBUGMSGTL(("tls_x509:verify", " accepting matching fp of self-signed certificate found in: %s\n",
+ cert->info.filename));
++ SNMP_FREE(fingerprint);
+ return 1;
+ } else {
+ DEBUGMSGTL(("tls_x509:verify", " no matching fp found\n"));
+ /* log where we are and why called */
+ snmp_log(LOG_ERR, "tls verification failure: ok=%d ctx=%p depth=%d err=%i:%s\n", ok, ctx, depth, err, X509_verify_cert_error_string(err));
+-
++ SNMP_FREE(fingerprint);
+ return 0;
+ }
+
+@@ -118,6 +120,7 @@ int verify_callback(int ok, X509_STORE_CTX *ctx) {
+ (verify_info->flags & VRFY_PARENT_WAS_OK)) {
+ DEBUGMSGTL(("tls_x509:verify", "verify_callback called with: ok=%d ctx=%p depth=%d err=%i:%s\n", ok, ctx, depth, err, X509_verify_cert_error_string(err)));
+ DEBUGMSGTL(("tls_x509:verify", " a parent was ok, so returning ok for this child certificate\n"));
++ SNMP_FREE(fingerprint);
+ return 1; /* we'll check the hostname later at this level */
+ }
+ }
+@@ -128,6 +131,7 @@ int verify_callback(int ok, X509_STORE_CTX *ctx) {
+ DEBUGMSGTL(("tls_x509:verify", "verify_callback called with: ok=%d ctx=%p depth=%d err=%i:%s\n", ok, ctx, depth, err, X509_verify_cert_error_string(err)));
+ DEBUGMSGTL(("tls_x509:verify", " returning the passed in value of %d\n",
+ ok));
++ SNMP_FREE(fingerprint);
+ return(ok);
+ }
+
+@@ -186,6 +190,7 @@ _netsnmp_tlsbase_verify_remote_fingerprint(X509 *remote_cert,
+ }
+ } else {
+ DEBUGMSGTL(("tls_x509:verify", "No fingerprint for the remote entity available to verify\n"));
++ free(fingerprint);
+ return NO_FINGERPRINT_AVAILABLE;
+ }
+
+@@ -262,7 +267,7 @@ netsnmp_tlsbase_verify_server_cert(SSL *ssl, _netsnmpTLSBaseData *tlsdata) {
+ *check_name && j < sizeof(buf)-1;
+ ++check_name, ++j ) {
+ if (isascii(*check_name))
+- buf[j] = tolower(*check_name);
++ buf[j] = tolower(0xFF & *check_name);
+ }
+ if (j < sizeof(buf))
+ buf[j] = '\0';
+@@ -914,9 +919,8 @@ int netsnmp_tlsbase_wrapup_recv(netsnmp_tmStateReference *tmStateRef,
+ /* RFC5953 Section 5.1.2 step 2: tmSecurityName */
+ /* XXX: detect and throw out overflow secname sizes rather
+ than truncating. */
+- strncpy(tmStateRef->securityName, tlsdata->securityName,
+- sizeof(tmStateRef->securityName)-1);
+- tmStateRef->securityName[sizeof(tmStateRef->securityName)-1] = '\0';
++ strlcpy(tmStateRef->securityName, tlsdata->securityName,
++ sizeof(tmStateRef->securityName));
+ tmStateRef->securityNameLen = strlen(tmStateRef->securityName);
+
+ /* RFC5953 Section 5.1.2 step 2: tmSessionID */
+@@ -1080,6 +1084,7 @@ const char * _x509_get_error(int x509failvalue, const char *location) {
+ #endif
+ case X509_V_ERR_APPLICATION_VERIFICATION:
+ reason = "X509_V_ERR_APPLICATION_VERIFICATION";
++ break;
+ default:
+ reason = "unknown failure code";
+ }
+diff --git a/snmplib/transports/snmpTLSTCPDomain.c b/snmplib/transports/snmpTLSTCPDomain.c
+index c1423f6..a92091e 100644
+--- a/snmplib/transports/snmpTLSTCPDomain.c
++++ b/snmplib/transports/snmpTLSTCPDomain.c
+@@ -152,7 +152,7 @@ netsnmp_tlstcp_recv(netsnmp_transport *t, void *buf, int size,
+ snmp_log(LOG_ERR,
+ "tlstcp received an invalid invocation with missing data\n");
+ DEBUGMSGTL(("tlstcp", "recvfrom fd %d err %d (\"%s\")\n",
+- t->sock, errno, strerror(errno)));
++ (t ? t->sock : -1), errno, strerror(errno)));
+ DEBUGMSGTL(("tlstcp", " tdata = %p\n", t->data));
+ return -1;
+ }
+@@ -248,8 +248,8 @@ netsnmp_tlstcp_recv(netsnmp_transport *t, void *buf, int size,
+ */
+
+ /* read the packet from openssl */
+- rc = SSL_read(tlsdata->ssl, buf, size);
+- while (rc <= 0) {
++ do {
++ rc = SSL_read(tlsdata->ssl, buf, size);
+ if (rc == 0) {
+ /* XXX closed connection */
+ DEBUGMSGTL(("tlstcp", "remote side closed connection\n"));
+@@ -257,24 +257,22 @@ netsnmp_tlstcp_recv(netsnmp_transport *t, void *buf, int size,
+ SNMP_FREE(tmStateRef);
+ return -1;
+ }
+- rc = SSL_read(tlsdata->ssl, buf, size);
+- }
++ if (rc == -1) {
++ int err = SSL_get_error(tlsdata->ssl, rc);
++ if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) {
++ /* error detected */
++ _openssl_log_error(rc, tlsdata->ssl, "SSL_read");
++ SNMP_FREE(tmStateRef);
++ return rc;
++ }
++ }
++ /* retry read for SSL_ERROR_WANT_READ || SSL_ERROR_WANT_WRITE */
++ } while (rc <= 0);
+
+ DEBUGMSGTL(("tlstcp", "received %d decoded bytes from tls\n", rc));
+
+- /* Check for errors */
+- if (rc == -1) {
+- if (SSL_get_error(tlsdata->ssl, rc) == SSL_ERROR_WANT_READ)
+- return -1; /* XXX: it's ok, but what's the right return? */
+-
+- _openssl_log_error(rc, tlsdata->ssl, "SSL_read");
+- SNMP_FREE(tmStateRef);
+-
+- return rc;
+- }
+-
+ /* log the packet */
+- {
++ DEBUGIF("tlstcp") {
+ char *str = netsnmp_tlstcp_fmtaddr(t, NULL, 0);
+ DEBUGMSGTL(("tlstcp",
+ "recvfrom fd %d got %d bytes (from %s)\n",
+@@ -416,7 +414,7 @@ netsnmp_tlstcp_send(netsnmp_transport *t, void *buf, int size,
+ /* If the first packet and we have no secname, then copy the
+ important securityName data into the longer-lived session
+ reference information. */
+- if ((tlsdata->flags | NETSNMP_TLSBASE_IS_CLIENT) &&
++ if ((tlsdata->flags & NETSNMP_TLSBASE_IS_CLIENT) &&
+ !tlsdata->securityName && tmStateRef && tmStateRef->securityNameLen > 0)
+ tlsdata->securityName = strdup(tmStateRef->securityName);
+
+@@ -921,7 +919,6 @@ netsnmp_tlstcp_transport(const char *addr_string, int isserver)
+ if (NULL == t) {
+ return NULL;
+ }
+- memset(t, 0, sizeof(netsnmp_transport));
+
+ /* allocate our TLS specific data */
+ if (NULL == (tlsdata = netsnmp_tlsbase_allocate_tlsdata(t, isserver)))
+@@ -936,12 +933,13 @@ netsnmp_tlstcp_transport(const char *addr_string, int isserver)
+ if (!isserver && tlsdata && addr_string) {
+ /* search for a : */
+ if (NULL != (cp = strrchr(addr_string, ':'))) {
+- strncpy(buf, addr_string, sizeof(buf)-1);
++ sprintf(buf, "%.*s",
++ (int) SNMP_MIN(cp - addr_string, sizeof(buf) - 1),
++ addr_string);
+ } else {
+ /* else the entire spec is a host name only */
+- strncpy(buf, addr_string, sizeof(buf)-1);
++ strlcpy(buf, addr_string, sizeof(buf));
+ }
+- buf[sizeof(buf)-1] = '\0';
+ tlsdata->their_hostname = strdup(buf);
+ }
+
+@@ -989,7 +987,7 @@ netsnmp_tlstcp_create_tstring(const char *str, int local,
+ for(cp = str; *cp != '\0'; cp++) {
+ /* if ALL numbers, it must be just a port */
+ /* if it contains anything else, assume a host or ip address */
+- if (!isdigit(*cp)) {
++ if (!isdigit(0xFF & *cp)) {
+ isport = 0;
+ break;
+ }
+diff --git a/snmplib/transports/snmpUDPBaseDomain.c b/snmplib/transports/snmpUDPBaseDomain.c
+index eb5f1a1..fc5c1cc 100644
+--- a/snmplib/transports/snmpUDPBaseDomain.c
++++ b/snmplib/transports/snmpUDPBaseDomain.c
+@@ -89,6 +89,160 @@ _netsnmp_udp_sockopt_set(int fd, int local)
+ netsnmp_sock_buffer_set(fd, SO_RCVBUF, local, 0);
+ }
+
++#if (defined(linux) && defined(IP_PKTINFO)) \
++ || defined(IP_RECVDSTADDR) && HAVE_STRUCT_MSGHDR_MSG_CONTROL \
++ && HAVE_STRUCT_MSGHDR_MSG_FLAGS
++#if defined(linux) && defined(IP_PKTINFO)
++#elif defined(IP_RECVDSTADDR)
++# ifndef IP_SENDSRCADDR
++# define IP_SENDSRCADDR IP_RECVDSTADDR /* DragonFly BSD */
++# endif
++#endif
++
++#define netsnmp_udpbase_recvfrom_sendto_defined
++
++enum {
++#if defined(linux) && defined(IP_PKTINFO)
++ cmsg_data_size = sizeof(struct in_pktinfo)
++#elif defined(IP_RECVDSTADDR)
++ cmsg_data_size = sizeof(struct in_addr)
++#endif
++};
++
++int
++netsnmp_udpbase_recvfrom(int s, void *buf, int len, struct sockaddr *from,
++ socklen_t *fromlen, struct sockaddr *dstip,
++ socklen_t *dstlen, int *if_index)
++{
++ int r;
++ struct iovec iov;
++ char cmsg[CMSG_SPACE(cmsg_data_size)];
++ struct cmsghdr *cm;
++ struct msghdr msg;
++
++ iov.iov_base = buf;
++ iov.iov_len = len;
++
++ memset(&msg, 0, sizeof msg);
++ msg.msg_name = from;
++ msg.msg_namelen = *fromlen;
++ msg.msg_iov = &iov;
++ msg.msg_iovlen = 1;
++ msg.msg_control = &cmsg;
++ msg.msg_controllen = sizeof(cmsg);
++
++ r = recvmsg(s, &msg, NETSNMP_DONTWAIT);
++
++ if (r == -1) {
++ return -1;
++ }
++
++ DEBUGMSGTL(("udpbase:recv", "got source addr: %s\n",
++ inet_ntoa(((struct sockaddr_in *)from)->sin_addr)));
++
++ {
++ /* Get the local port number for use in diagnostic messages */
++ int r2 = getsockname(s, dstip, dstlen);
++ netsnmp_assert(r2 == 0);
++ }
++
++ for (cm = CMSG_FIRSTHDR(&msg); cm != NULL; cm = CMSG_NXTHDR(&msg, cm)) {
++#if defined(linux) && defined(IP_PKTINFO)
++ if (cm->cmsg_level == SOL_IP && cm->cmsg_type == IP_PKTINFO) {
++ struct in_pktinfo* src = (struct in_pktinfo *)CMSG_DATA(cm);
++ netsnmp_assert(dstip->sa_family == AF_INET);
++ ((struct sockaddr_in*)dstip)->sin_addr = src->ipi_addr;
++ *if_index = src->ipi_ifindex;
++ DEBUGMSGTL(("udpbase:recv",
++ "got destination (local) addr %s, iface %d\n",
++ inet_ntoa(((struct sockaddr_in*)dstip)->sin_addr),
++ *if_index));
++ }
++#elif defined(IP_RECVDSTADDR)
++ if (cm->cmsg_level == IPPROTO_IP && cm->cmsg_type == IP_RECVDSTADDR) {
++ struct in_addr* src = (struct in_addr *)CMSG_DATA(cm);
++ ((struct sockaddr_in*)dstip)->sin_addr = *src;
++ DEBUGMSGTL(("netsnmp_udp", "got destination (local) addr %s\n",
++ inet_ntoa(((struct sockaddr_in*)dstip)->sin_addr)));
++ }
++#endif
++ }
++ return r;
++}
++
++int netsnmp_udpbase_sendto(int fd, struct in_addr *srcip, int if_index,
++ struct sockaddr *remote, void *data, int len)
++{
++ struct iovec iov;
++ struct msghdr m = { 0 };
++ char cmsg[CMSG_SPACE(cmsg_data_size)];
++
++ iov.iov_base = data;
++ iov.iov_len = len;
++
++ m.msg_name = remote;
++ m.msg_namelen = sizeof(struct sockaddr_in);
++ m.msg_iov = &iov;
++ m.msg_iovlen = 1;
++ m.msg_flags = 0;
++
++ if (srcip && srcip->s_addr != INADDR_ANY) {
++ struct cmsghdr *cm;
++
++ DEBUGMSGTL(("udpbase:sendto", "sending from %s\n", inet_ntoa(*srcip)));
++
++ memset(cmsg, 0, sizeof(cmsg));
++
++ m.msg_control = &cmsg;
++ m.msg_controllen = sizeof(cmsg);
++
++ cm = CMSG_FIRSTHDR(&m);
++ cm->cmsg_len = CMSG_LEN(cmsg_data_size);
++
++#if defined(linux) && defined(IP_PKTINFO)
++ cm->cmsg_level = SOL_IP;
++ cm->cmsg_type = IP_PKTINFO;
++
++ {
++ struct in_pktinfo ipi = { 0 };
++ ipi.ipi_ifindex = 0;
++ ipi.ipi_spec_dst.s_addr = srcip->s_addr;
++ memcpy(CMSG_DATA(cm), &ipi, sizeof(ipi));
++ }
++
++ {
++ errno = 0;
++ const int rc = sendmsg(fd, &m, NETSNMP_NOSIGNAL|NETSNMP_DONTWAIT);
++
++ if (rc >= 0 || errno != EINVAL)
++ return rc;
++ }
++
++ /*
++ * The error might be caused by broadcast srcip (i.e. we're responding
++ * to a broadcast request) - sendmsg does not like it. Try to resend it
++ * using the interface on which it was received
++ */
++
++ DEBUGMSGTL(("udpbase:sendto", "re-sending on iface %d\n", if_index));
++
++ {
++ struct in_pktinfo ipi = { 0 };
++ ipi.ipi_ifindex = if_index;
++ ipi.ipi_spec_dst.s_addr = INADDR_ANY;
++ memcpy(CMSG_DATA(cm), &ipi, sizeof(ipi));
++ }
++#elif defined(IP_SENDSRCADDR)
++ cm->cmsg_level = IPPROTO_IP;
++ cm->cmsg_type = IP_SENDSRCADDR;
++ memcpy((struct in_addr *)CMSG_DATA(cm), srcip, sizeof(struct in_addr));
++#endif
++ }
++
++ return sendmsg(fd, &m, NETSNMP_NOSIGNAL|NETSNMP_DONTWAIT);
++}
++#endif /* (linux && IP_PKTINFO) || IP_RECVDSTADDR */
++
+ /*
+ * You can write something into opaque that will subsequently get passed back
+ * to your send function if you like. For instance, you might want to
+@@ -116,25 +270,28 @@ netsnmp_udpbase_recv(netsnmp_transport *t, void *buf, int size,
+ }
+
+ while (rc < 0) {
+-#if defined(linux) && defined(IP_PKTINFO)
++#ifdef netsnmp_udpbase_recvfrom_sendto_defined
+ socklen_t local_addr_len = sizeof(addr_pair->local_addr);
+ rc = netsnmp_udp_recvfrom(t->sock, buf, size, from, &fromlen,
+ (struct sockaddr*)&(addr_pair->local_addr),
+ &local_addr_len, &(addr_pair->if_index));
+ #else
+ rc = recvfrom(t->sock, buf, size, NETSNMP_DONTWAIT, from, &fromlen);
+-#endif /* linux && IP_PKTINFO */
++#endif /* netsnmp_udpbase_recvfrom_sendto_defined */
+ if (rc < 0 && errno != EINTR) {
+ break;
+ }
+ }
+
+ if (rc >= 0) {
+- char *str = netsnmp_udp_fmtaddr(NULL, addr_pair, sizeof(netsnmp_indexed_addr_pair));
+- DEBUGMSGTL(("netsnmp_udp",
+- "recvfrom fd %d got %d bytes (from %s)\n",
+- t->sock, rc, str));
+- free(str);
++ DEBUGIF("netsnmp_udp") {
++ char *str = netsnmp_udp_fmtaddr(
++ NULL, addr_pair, sizeof(netsnmp_indexed_addr_pair));
++ DEBUGMSGTL(("netsnmp_udp",
++ "recvfrom fd %d got %d bytes (from %s)\n",
++ t->sock, rc, str));
++ free(str);
++ }
+ } else {
+ DEBUGMSGTL(("netsnmp_udp", "recvfrom fd %d err %d (\"%s\")\n",
+ t->sock, errno, strerror(errno)));
+@@ -167,19 +324,21 @@ netsnmp_udpbase_send(netsnmp_transport *t, void *buf, int size,
+ to = &addr_pair->remote_addr.sa;
+
+ if (to != NULL && t != NULL && t->sock >= 0) {
+- char *str = netsnmp_udp_fmtaddr(NULL, (void *) addr_pair,
+- sizeof(netsnmp_indexed_addr_pair));
+- DEBUGMSGTL(("netsnmp_udp", "send %d bytes from %p to %s on fd %d\n",
+- size, buf, str, t->sock));
+- free(str);
++ DEBUGIF("netsnmp_udp") {
++ char *str = netsnmp_udp_fmtaddr(NULL, (void *) addr_pair,
++ sizeof(netsnmp_indexed_addr_pair));
++ DEBUGMSGTL(("netsnmp_udp", "send %d bytes from %p to %s on fd %d\n",
++ size, buf, str, t->sock));
++ free(str);
++ }
+ while (rc < 0) {
+-#if defined(linux) && defined(IP_PKTINFO)
++#ifdef netsnmp_udpbase_recvfrom_sendto_defined
+ rc = netsnmp_udp_sendto(t->sock,
+ addr_pair ? &(addr_pair->local_addr.sin.sin_addr) : NULL,
+ addr_pair ? addr_pair->if_index : 0, to, buf, size);
+ #else
+ rc = sendto(t->sock, buf, size, 0, to, sizeof(struct sockaddr));
+-#endif /* linux && IP_PKTINFO */
++#endif /* netsnmp_udpbase_recvfrom_sendto_defined */
+ if (rc < 0 && errno != EINTR) {
+ DEBUGMSGTL(("netsnmp_udp", "sendto error, rc %d (errno %d)\n",
+ rc, errno));
+@@ -189,153 +348,3 @@ netsnmp_udpbase_send(netsnmp_transport *t, void *buf, int size,
+ }
+ return rc;
+ }
+-
+-#if (defined(linux) && defined(IP_PKTINFO)) \
+- || defined(IP_RECVDSTADDR) && HAVE_STRUCT_MSGHDR_MSG_CONTROL \
+- && HAVE_STRUCT_MSGHDR_MSG_FLAGS
+-#if defined(linux) && defined(IP_PKTINFO)
+-# define netsnmp_dstaddr(x) (&(((struct in_pktinfo *)(CMSG_DATA(x)))->ipi_addr))
+-#elif defined(IP_RECVDSTADDR)
+-# define netsnmp_dstaddr(x) (&(struct cmsghr *)(CMSG_DATA(x)))
+-# ifndef IP_SENDSRCADDR
+-# define IP_SENDSRCADDR IP_RECVDSTADDR /* DragonFly BSD */
+-# endif
+-#endif
+-
+-int
+-netsnmp_udpbase_recvfrom(int s, void *buf, int len, struct sockaddr *from,
+- socklen_t *fromlen, struct sockaddr *dstip,
+- socklen_t *dstlen, int *if_index)
+-{
+- int r, r2;
+- struct iovec iov[1];
+-#if defined(linux) && defined(IP_PKTINFO)
+- char cmsg[CMSG_SPACE(sizeof(struct in_pktinfo))];
+-#elif defined(IP_RECVDSTADDR)
+- char cmsg[CMSG_SPACE(sizeof(struct in_addr))];
+-#endif
+- struct cmsghdr *cmsgptr;
+- struct msghdr msg;
+-
+- iov[0].iov_base = buf;
+- iov[0].iov_len = len;
+-
+- memset(&msg, 0, sizeof msg);
+- msg.msg_name = from;
+- msg.msg_namelen = *fromlen;
+- msg.msg_iov = iov;
+- msg.msg_iovlen = 1;
+- msg.msg_control = &cmsg;
+- msg.msg_controllen = sizeof(cmsg);
+-
+- r = recvmsg(s, &msg, NETSNMP_DONTWAIT);
+-
+- if (r == -1) {
+- return -1;
+- }
+-
+- r2 = getsockname(s, dstip, dstlen);
+- netsnmp_assert(r2 == 0);
+-
+- DEBUGMSGTL(("udpbase:recv", "got source addr: %s\n",
+- inet_ntoa(((struct sockaddr_in *)from)->sin_addr)));
+-#if defined(linux) && defined(IP_PKTINFO)
+- for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
+- if (cmsgptr->cmsg_level != SOL_IP || cmsgptr->cmsg_type != IP_PKTINFO)
+- continue;
+-
+- netsnmp_assert(dstip->sa_family == AF_INET);
+- ((struct sockaddr_in*)dstip)->sin_addr = *netsnmp_dstaddr(cmsgptr);
+- *if_index = (((struct in_pktinfo *)(CMSG_DATA(cmsgptr)))->ipi_ifindex);
+- DEBUGMSGTL(("udpbase:recv",
+- "got destination (local) addr %s, iface %d\n",
+- inet_ntoa(((struct sockaddr_in*)dstip)->sin_addr),
+- *if_index));
+- }
+-#elif defined(IP_RECVDSTADDR)
+- for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL; cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
+- if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_RECVDSTADDR) {
+- memcpy((void *) dstip, CMSG_DATA(cmsgptr), sizeof(struct in_addr));
+- DEBUGMSGTL(("netsnmp_udp", "got destination (local) addr %s\n",
+- inet_ntoa(((struct sockaddr_in*)dstip)->sin_addr)));
+- }
+- }
+-#endif
+- return r;
+-}
+-
+-#if defined(linux) && defined(IP_PKTINFO)
+-int netsnmp_udpbase_sendto(int fd, struct in_addr *srcip, int if_index,
+- struct sockaddr *remote, void *data, int len)
+-{
+- struct iovec iov;
+- struct {
+- struct cmsghdr cm;
+- struct in_pktinfo ipi;
+- } cmsg;
+- struct msghdr m;
+- int ret;
+-
+- iov.iov_base = data;
+- iov.iov_len = len;
+- memset(&cmsg, 0, sizeof(cmsg));
+- cmsg.cm.cmsg_len = sizeof(struct cmsghdr) + sizeof(struct in_pktinfo);
+- cmsg.cm.cmsg_level = SOL_IP;
+- cmsg.cm.cmsg_type = IP_PKTINFO;
+- cmsg.ipi.ipi_ifindex = 0;
+- cmsg.ipi.ipi_spec_dst.s_addr = (srcip ? srcip->s_addr : INADDR_ANY);
+-
+- m.msg_name = remote;
+- m.msg_namelen = sizeof(struct sockaddr_in);
+- m.msg_iov = &iov;
+- m.msg_iovlen = 1;
+- m.msg_control = &cmsg;
+- m.msg_controllen = sizeof(cmsg);
+- m.msg_flags = 0;
+-
+- DEBUGMSGTL(("udpbase:sendto", "sending from %s iface %d\n",
+- (srcip ? inet_ntoa(*srcip) : "NULL"), if_index));
+- errno = 0;
+- ret = sendmsg(fd, &m, NETSNMP_NOSIGNAL|NETSNMP_DONTWAIT);
+- if (ret < 0 && errno == EINVAL && srcip) {
+- /* The error might be caused by broadcast srcip (i.e. we're responding
+- * to broadcast request) - sendmsg does not like it. Try to resend it
+- * with global address and using the interface on whicg it was
+- * received */
+- cmsg.ipi.ipi_ifindex = if_index;
+- cmsg.ipi.ipi_spec_dst.s_addr = INADDR_ANY;
+- DEBUGMSGTL(("udpbase:sendto", "re-sending the message\n"));
+- ret = sendmsg(fd, &m, NETSNMP_NOSIGNAL|NETSNMP_DONTWAIT);
+- }
+- return ret;
+-}
+-#elif defined(IP_SENDSRCADDR)
+-int netsnmp_udpbase_sendto(int fd, struct in_addr *srcip, int if_index,
+- struct sockaddr *remote, void *data, int len)
+-{
+- struct iovec iov = { data, len };
+- struct cmsghdr *cm;
+- struct msghdr m;
+- char cmbuf[CMSG_SPACE(sizeof(struct in_addr))];
+-
+- memset(&m, 0, sizeof(struct msghdr));
+- m.msg_name = remote;
+- m.msg_namelen = sizeof(struct sockaddr_in);
+- m.msg_iov = &iov;
+- m.msg_iovlen = 1;
+- m.msg_control = cmbuf;
+- m.msg_controllen = sizeof(cmbuf);
+- m.msg_flags = 0;
+-
+- cm = CMSG_FIRSTHDR(&m);
+- cm->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
+- cm->cmsg_level = IPPROTO_IP;
+- cm->cmsg_type = IP_SENDSRCADDR;
+-
+- memcpy((struct in_addr *)CMSG_DATA(cm), srcip, sizeof(struct in_addr));
+-
+- return sendmsg(fd, &m, NETSNMP_NOSIGNAL|NETSNMP_DONTWAIT);
+-}
+-#endif
+-#endif /* (linux && IP_PKTINFO) || IP_RECVDSTADDR */
+-
+diff --git a/snmplib/transports/snmpUDPIPv4BaseDomain.c b/snmplib/transports/snmpUDPIPv4BaseDomain.c
+index 5a4f5b0..5f2f2da 100644
+--- a/snmplib/transports/snmpUDPIPv4BaseDomain.c
++++ b/snmplib/transports/snmpUDPIPv4BaseDomain.c
+@@ -64,7 +64,6 @@ netsnmp_udpipv4base_transport(struct sockaddr_in *addr, int local)
+ {
+ netsnmp_transport *t = NULL;
+ int rc = 0, rc2;
+- char *str = NULL;
+ char *client_socket = NULL;
+ netsnmp_indexed_addr_pair addr_pair;
+ socklen_t local_addr_len;
+@@ -84,11 +83,13 @@ netsnmp_udpipv4base_transport(struct sockaddr_in *addr, int local)
+ t = SNMP_MALLOC_TYPEDEF(netsnmp_transport);
+ netsnmp_assert_or_return(t != NULL, NULL);
+
+- str = netsnmp_udp_fmtaddr(NULL, (void *)&addr_pair,
+- sizeof(netsnmp_indexed_addr_pair));
+- DEBUGMSGTL(("netsnmp_udpbase", "open %s %s\n", local ? "local" : "remote",
+- str));
+- free(str);
++ DEBUGIF("netsnmp_udpbase") {
++ char *str = netsnmp_udp_fmtaddr(NULL, (void *)&addr_pair,
++ sizeof(netsnmp_indexed_addr_pair));
++ DEBUGMSGTL(("netsnmp_udpbase", "open %s %s\n",
++ local ? "local" : "remote", str));
++ free(str);
++ }
+
+ t->sock = socket(PF_INET, SOCK_DGRAM, 0);
+ DEBUGMSGTL(("UDPBase", "openned socket %d as local=%d\n", t->sock, local));
+@@ -128,6 +129,17 @@ netsnmp_udpipv4base_transport(struct sockaddr_in *addr, int local)
+ }
+ DEBUGMSGTL(("netsnmp_udpbase", "set IP_PKTINFO\n"));
+ }
++#elif defined(IP_RECVDSTADDR)
++ {
++ int sockopt = 1;
++ if (setsockopt(t->sock, IPPROTO_IP, IP_RECVDSTADDR, &sockopt, sizeof sockopt) == -1) {
++ DEBUGMSGTL(("netsnmp_udp", "couldn't set IP_RECVDSTADDR: %s\n",
++ strerror(errno)));
++ netsnmp_transport_free(t);
++ return NULL;
++ }
++ DEBUGMSGTL(("netsnmp_udp", "set IP_RECVDSTADDR\n"));
++ }
+ #endif
+ rc = bind(t->sock, (struct sockaddr *) addr,
+ sizeof(struct sockaddr));
+@@ -169,10 +181,12 @@ netsnmp_udpipv4base_transport(struct sockaddr_in *addr, int local)
+ netsnmp_assert(rc2 == 0);
+ }
+
+- str = netsnmp_udp_fmtaddr(NULL, (void *)&addr_pair,
+- sizeof(netsnmp_indexed_addr_pair));
+- DEBUGMSGTL(("netsnmp_udpbase", "client open %s\n", str));
+- free(str);
++ DEBUGIF("netsnmp_udpbase") {
++ char *str = netsnmp_udp_fmtaddr(NULL, (void *)&addr_pair,
++ sizeof(netsnmp_indexed_addr_pair));
++ DEBUGMSGTL(("netsnmp_udpbase", "client open %s\n", str));
++ free(str);
++ }
+
+ /*
+ * Save the (remote) address in the
+diff --git a/snmplib/transports/snmpUDPIPv6Domain.c b/snmplib/transports/snmpUDPIPv6Domain.c
+index 90607b5..b3eaae4 100644
+--- a/snmplib/transports/snmpUDPIPv6Domain.c
++++ b/snmplib/transports/snmpUDPIPv6Domain.c
+@@ -65,6 +65,7 @@ static const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
+
+ #include <net-snmp/library/snmp_transport.h>
+ #include <net-snmp/library/snmpSocketBaseDomain.h>
++#include <net-snmp/library/tools.h>
+
+ #include "inet_ntop.h"
+ #include "inet_pton.h"
+@@ -123,11 +124,13 @@ netsnmp_udp6_recv(netsnmp_transport *t, void *buf, int size,
+ }
+
+ if (rc >= 0) {
+- char *str = netsnmp_udp6_fmtaddr(NULL, from, fromlen);
+- DEBUGMSGTL(("netsnmp_udp6",
+- "recvfrom fd %d got %d bytes (from %s)\n", t->sock,
+- rc, str));
+- free(str);
++ DEBUGIF("netsnmp_udp6") {
++ char *str = netsnmp_udp6_fmtaddr(NULL, from, fromlen);
++ DEBUGMSGTL(("netsnmp_udp6",
++ "recvfrom fd %d got %d bytes (from %s)\n", t->sock,
++ rc, str));
++ free(str);
++ }
+ } else {
+ DEBUGMSGTL(("netsnmp_udp6", "recvfrom fd %d err %d (\"%s\")\n",
+ t->sock, errno, strerror(errno)));
+@@ -157,11 +160,14 @@ netsnmp_udp6_send(netsnmp_transport *t, void *buf, int size,
+ }
+
+ if (to != NULL && t != NULL && t->sock >= 0) {
+- char *str = netsnmp_udp6_fmtaddr(NULL, (void *)to,
+- sizeof(struct sockaddr_in6));
+- DEBUGMSGTL(("netsnmp_udp6", "send %d bytes from %p to %s on fd %d\n",
+- size, buf, str, t->sock));
+- free(str);
++ DEBUGIF("netsnmp_udp6") {
++ char *str = netsnmp_udp6_fmtaddr(NULL, (void *)to,
++ sizeof(struct sockaddr_in6));
++ DEBUGMSGTL(("netsnmp_udp6",
++ "send %d bytes from %p to %s on fd %d\n",
++ size, buf, str, t->sock));
++ free(str);
++ }
+ while (rc < 0) {
+ rc = sendto(t->sock, buf, size, 0, to,sizeof(struct sockaddr_in6));
+ if (rc < 0 && errno != EINTR) {
+@@ -184,7 +190,6 @@ netsnmp_udp6_transport(struct sockaddr_in6 *addr, int local)
+ {
+ netsnmp_transport *t = NULL;
+ int rc = 0;
+- char *str = NULL;
+
+ #ifdef NETSNMP_NO_LISTEN_SUPPORT
+ if (local)
+@@ -195,18 +200,18 @@ netsnmp_udp6_transport(struct sockaddr_in6 *addr, int local)
+ return NULL;
+ }
+
+- t = (netsnmp_transport *) malloc(sizeof(netsnmp_transport));
++ t = SNMP_MALLOC_TYPEDEF(netsnmp_transport);
+ if (t == NULL) {
+ return NULL;
+ }
+
+- str = netsnmp_udp6_fmtaddr(NULL, (void *) addr,
+- sizeof(struct sockaddr_in6));
+- DEBUGMSGTL(("netsnmp_udp6", "open %s %s\n", local ? "local" : "remote",
+- str));
+- free(str);
+-
+- memset(t, 0, sizeof(netsnmp_transport));
++ DEBUGIF("netsnmp_udp6") {
++ char *str = netsnmp_udp6_fmtaddr(NULL, (void *) addr,
++ sizeof(struct sockaddr_in6));
++ DEBUGMSGTL(("netsnmp_udp6", "open %s %s\n", local ? "local" : "remote",
++ str));
++ free(str);
++ }
+
+ t->domain = netsnmp_UDPIPv6Domain;
+ t->domain_length =
+diff --git a/snmplib/transports/snmpUnixDomain.c b/snmplib/transports/snmpUnixDomain.c
+index fbdeb03..674dc2b 100644
+--- a/snmplib/transports/snmpUnixDomain.c
++++ b/snmplib/transports/snmpUnixDomain.c
+@@ -35,6 +35,7 @@
+ #include <net-snmp/library/snmp_transport.h>
+ #include <net-snmp/library/snmpSocketBaseDomain.h>
+ #include <net-snmp/library/system.h> /* mkdirhier */
++#include <net-snmp/library/tools.h>
+
+ netsnmp_feature_child_of(transport_unix_socket_all, transport_all)
+ netsnmp_feature_child_of(unix_socket_paths, transport_unix_socket_all)
+@@ -294,7 +295,6 @@ netsnmp_unix_transport(struct sockaddr_un *addr, int local)
+ netsnmp_transport *t = NULL;
+ sockaddr_un_pair *sup = NULL;
+ int rc = 0;
+- char *string = NULL;
+
+ #ifdef NETSNMP_NO_LISTEN_SUPPORT
+ /* SPECIAL CIRCUMSTANCE: We still want AgentX to be able to operate,
+@@ -307,18 +307,18 @@ netsnmp_unix_transport(struct sockaddr_un *addr, int local)
+ return NULL;
+ }
+
+- t = (netsnmp_transport *) malloc(sizeof(netsnmp_transport));
++ t = SNMP_MALLOC_TYPEDEF(netsnmp_transport);
+ if (t == NULL) {
+ return NULL;
+ }
+
+- string = netsnmp_unix_fmtaddr(NULL, (void *)addr,
+- sizeof(struct sockaddr_un));
+- DEBUGMSGTL(("netsnmp_unix", "open %s %s\n", local ? "local" : "remote",
+- string));
+- free(string);
+-
+- memset(t, 0, sizeof(netsnmp_transport));
++ DEBUGIF("netsnmp_unix") {
++ char *str = netsnmp_unix_fmtaddr(NULL, (void *)addr,
++ sizeof(struct sockaddr_un));
++ DEBUGMSGTL(("netsnmp_unix", "open %s %s\n", local ? "local" : "remote",
++ str));
++ free(str);
++ }
+
+ t->domain = netsnmp_UnixDomain;
+ t->domain_length =
+@@ -463,7 +463,7 @@ netsnmp_unix_create_tstring(const char *string, int local,
+ (strlen(string) < sizeof(addr.sun_path))) {
+ addr.sun_family = AF_UNIX;
+ memset(addr.sun_path, 0, sizeof(addr.sun_path));
+- strncpy(addr.sun_path, string, sizeof(addr.sun_path) - 1);
++ strlcpy(addr.sun_path, string, sizeof(addr.sun_path));
+ return netsnmp_unix_transport(&addr, local);
+ } else {
+ if (string != NULL && *string != '\0') {
+@@ -483,7 +483,7 @@ netsnmp_unix_create_ostring(const u_char * o, size_t o_len, int local)
+ if (o_len > 0 && o_len < (sizeof(addr.sun_path) - 1)) {
+ addr.sun_family = AF_UNIX;
+ memset(addr.sun_path, 0, sizeof(addr.sun_path));
+- strncpy(addr.sun_path, (const char *)o, o_len);
++ strlcpy(addr.sun_path, (const char *)o, sizeof(addr.sun_path));
+ return netsnmp_unix_transport(&addr, local);
+ } else {
+ if (o_len > 0) {
+diff --git a/testing/RUNTESTS b/testing/RUNTESTS
+index 8976c31..0b093da 100755
+--- a/testing/RUNTESTS
++++ b/testing/RUNTESTS
+@@ -10,13 +10,13 @@ if [ "x$MIBDIRS" = "x" ]; then
+ export MIBDIRS
+ fi
+
+-# Make sure MinGW / MSYS users have the kill.exe program to stop the agent and
++# Make sure MinGW / MSYS users have the pskill.exe program to stop the agent and
+ # snmptrapd
+-if [ "x$OSTYPE" = "xmsys" -a "x`type -p kill.exe`" = "x" ]; then
+- echo Could not find kill.exe. Aborting tests.
+- echo kill.exe can be installed as follows:
+- echo - Download pskill.exe from http://technet.microsoft.com/en-us/sysinternals/default.aspx.
+- echo - Copy pskill.exe to C:\Windows\kill.exe.
++if [ "x$OSTYPE" = "xmsys" -a "x`type -p pskill.exe`" = "x" ]; then
++ echo "Could not find pskill.exe. Aborting tests."
++ echo "pskill.exe can be installed as follows:"
++ echo "- Download pskill.exe from http://technet.microsoft.com/en-us/sysinternals/default.aspx."
++ echo "- Copy pskill.exe to C:\\MinGW\\msys\\1.0\\bin."
+ exit 1
+ fi
+
+diff --git a/testing/fulltests/default/T035snmpv3trapdusermgmt_simple b/testing/fulltests/default/T035snmpv3trapdusermgmt_simple
+index e42690f..e1b06c1 100644
+--- a/testing/fulltests/default/T035snmpv3trapdusermgmt_simple
++++ b/testing/fulltests/default/T035snmpv3trapdusermgmt_simple
+@@ -7,7 +7,8 @@ HEADER SNMPv3 snmptrapd USM user management with snmpusm
+ SKIPIFNOT USING_AGENTX_MASTER_MODULE
+ SKIPIFNOT USING_AGENTX_SUBAGENT_MODULE
+ SKIPIFNOT USING_SNMPV3_USMUSER_MODULE
+-SKIPIF NETSNMP_SNMPTRAPD_DISABLE_AGENTX
++SKIPIF NETSNMP_SNMPTRAPD_DISABLE_AGENTX
++SKIPIF NETSNMP_DISABLE_SET_SUPPORT
+ SKIPIFNOT NETSNMP_CAN_DO_CRYPTO
+ SKIPIFNOT NETSNMP_ENABLE_SCAPI_AUTHPRIV
+
+diff --git a/testing/fulltests/default/T065agentextend_simple b/testing/fulltests/default/T065agentextend_simple
+index c7cf6aa..07dcae3 100644
+--- a/testing/fulltests/default/T065agentextend_simple
++++ b/testing/fulltests/default/T065agentextend_simple
+@@ -4,6 +4,7 @@
+
+ HEADER "extending agent functionality with extend"
+
++[ "x$OSTYPE" = xmsys -a "x$MSYS_SH" = x ] && SKIP "\$MSYS_SH has not been set"
+ SKIPIF NETSNMP_DISABLE_SNMPV2C
+ SKIPIFNOT USING_AGENT_EXTEND_MODULE
+ SKIPIFNOT USING_UTILITIES_EXECUTE_MODULE
+diff --git a/testing/fulltests/default/T066pass_simple b/testing/fulltests/default/T066pass_simple
+new file mode 100644
+index 0000000..6396ed1
+--- /dev/null
++++ b/testing/fulltests/default/T066pass_simple
+@@ -0,0 +1,53 @@
++#!/bin/sh
++
++. ../support/simple_eval_tools.sh
++
++HEADER "extending agent functionality with pass"
++
++SKIPIF NETSNMP_DISABLE_SNMPV2C
++SKIPIFNOT USING_UCD_SNMP_PASS_MODULE
++SKIPIFNOT USING_UTILITIES_EXECUTE_MODULE
++
++# Don't run this test on MinGW - local/passtest is a shell script and
++# hence passing it to the MSVCRT popen() doesn't work.
++[ "x$OSTYPE" = "xmsys" ] && SKIP "MinGW"
++
++# make sure snmpget and snmpwalk can be executed
++SNMPGET="${builddir}/apps/snmpget"
++[ -x "$SNMPGET" ] || SKIP
++SNMPWALK="${builddir}/apps/snmpwalk"
++[ -x "$SNMPWALK" ] || SKIP
++
++snmp_version=v2c
++TESTCOMMUNITY=testcommunity
++. ./Sv2cconfig
++
++#
++# Begin test
++#
++oid=.1.3.6.1.4.1.8072.2.255 # NET-SNMP-PASS-MIB::netSnmpPassExamples
++CONFIGAGENT pass $oid ${srcdir}/local/passtest
++
++ORIG_AGENT_FLAGS="$AGENT_FLAGS"
++AGENT_FLAGS="$ORIG_AGENT_FLAGS -Ducd-snmp/pass"
++STARTAGENT
++
++#COMMENT Check a full walk of the sample data
++CAPTURE "$SNMPWALK $SNMP_FLAGS -$snmp_version -c $TESTCOMMUNITY $SNMP_TRANSPORT_SPEC:$SNMP_TEST_DEST$SNMP_SNMPD_PORT $oid"
++CHECKORDIE "NET-SNMP-PASS-MIB::netSnmpPassString.0 = STRING: Life, the Universe, and Everything"
++CHECKORDIE "NET-SNMP-PASS-MIB::netSnmpPassInteger.1 = INTEGER: 42"
++CHECKORDIE "NET-SNMP-PASS-MIB::netSnmpPassOID.1 = OID: NET-SNMP-PASS-MIB::netSnmpPassOIDValue"
++CHECKORDIE "NET-SNMP-PASS-MIB::netSnmpPassTimeTicks.0 = Timeticks: (363136200) 42 days, 0:42:42.00 "
++CHECKORDIE "NET-SNMP-PASS-MIB::netSnmpPassIpAddress.0 = IpAddress: 127.0.0.1"
++CHECKORDIE "NET-SNMP-PASS-MIB::netSnmpPassCounter.0 = Counter32: 42"
++CHECKORDIE "NET-SNMP-PASS-MIB::netSnmpPassGauge.0 = Gauge32: 42"
++
++#COMMENT A couple of spot checks of GET requests.
++CAPTURE "$SNMPGET $SNMP_FLAGS -$snmp_version -c $TESTCOMMUNITY $SNMP_TRANSPORT_SPEC:$SNMP_TEST_DEST$SNMP_SNMPD_PORT NET-SNMP-PASS-MIB::netSnmpPassInteger.1"
++CHECKORDIE "INTEGER: 42"
++
++CAPTURE "$SNMPGET $SNMP_FLAGS -$snmp_version -c $TESTCOMMUNITY $SNMP_TRANSPORT_SPEC:$SNMP_TEST_DEST$SNMP_SNMPD_PORT NET-SNMP-PASS-MIB::netSnmpPassCounter.0"
++CHECKORDIE "Counter32: 42"
++
++STOPAGENT
++FINISHED
+diff --git a/testing/fulltests/default/T067passpersist_simple b/testing/fulltests/default/T067passpersist_simple
+new file mode 100644
+index 0000000..f91651a
+--- /dev/null
++++ b/testing/fulltests/default/T067passpersist_simple
+@@ -0,0 +1,61 @@
++#!/bin/sh
++
++. ../support/simple_eval_tools.sh
++
++HEADER "extending agent functionality with pass_persist"
++
++SKIPIF NETSNMP_DISABLE_SNMPV2C
++SKIPIFNOT USING_UCD_SNMP_PASS_PERSIST_MODULE
++
++# Don't run this test on MinGW - local/pass_persisttest is a shell script and
++# hence passing it to the MSVCRT popen() doesn't work.
++[ "x$OSTYPE" = "xmsys" ] && SKIP "MinGW"
++
++# make sure snmpget and snmpwalk can be executed
++SNMPGET="${builddir}/apps/snmpget"
++[ -x "$SNMPGET" ] || SKIP
++SNMPWALK="${builddir}/apps/snmpwalk"
++[ -x "$SNMPWALK" ] || SKIP
++
++snmp_version=v2c
++TESTCOMMUNITY=testcommunity
++. ./Sv2cconfig
++
++#
++# Begin test
++#
++oid=.1.3.6.1.4.1.8072.2.255 # NET-SNMP-PASS-MIB::netSnmpPassExamples
++CONFIGAGENT pass_persist $oid ${srcdir}/local/pass_persisttest
++
++ORIG_AGENT_FLAGS="$AGENT_FLAGS"
++AGENT_FLAGS="$ORIG_AGENT_FLAGS -Ducd-snmp/pass_persist"
++PASS_PERSIST_PIDFILE="$SNMP_TMPDIR/pass_persist.pid.$$"
++export PASS_PERSIST_PIDFILE
++STARTAGENT
++
++#COMMENT Check a full walk of the sample data
++CAPTURE "$SNMPWALK $SNMP_FLAGS -$snmp_version -c $TESTCOMMUNITY $SNMP_TRANSPORT_SPEC:$SNMP_TEST_DEST$SNMP_SNMPD_PORT $oid"
++CHECKORDIE "NET-SNMP-PASS-MIB::netSnmpPassString.0 = STRING: Life, the Universe, and Everything"
++CHECKORDIE "NET-SNMP-PASS-MIB::netSnmpPassInteger.1 = INTEGER: 42"
++CHECKORDIE "NET-SNMP-PASS-MIB::netSnmpPassOID.1 = OID: NET-SNMP-PASS-MIB::netSnmpPassOIDValue"
++CHECKORDIE "NET-SNMP-PASS-MIB::netSnmpPassTimeTicks.0 = Timeticks: (363136200) 42 days, 0:42:42.00 "
++CHECKORDIE "NET-SNMP-PASS-MIB::netSnmpPassIpAddress.0 = IpAddress: 127.0.0.1"
++CHECKORDIE "NET-SNMP-PASS-MIB::netSnmpPassCounter.0 = Counter32: 1"
++CHECKORDIE "NET-SNMP-PASS-MIB::netSnmpPassGauge.0 = Gauge32: 42"
++
++#COMMENT A couple of spot checks of GET requests.
++CAPTURE "$SNMPGET $SNMP_FLAGS -$snmp_version -c $TESTCOMMUNITY $SNMP_TRANSPORT_SPEC:$SNMP_TEST_DEST$SNMP_SNMPD_PORT NET-SNMP-PASS-MIB::netSnmpPassInteger.1"
++CHECKORDIE "INTEGER: 42"
++
++#COMMENT netSnmpPassCounter should increment, since this is pass_persist
++CAPTURE "$SNMPGET $SNMP_FLAGS -$snmp_version -c $TESTCOMMUNITY $SNMP_TRANSPORT_SPEC:$SNMP_TEST_DEST$SNMP_SNMPD_PORT NET-SNMP-PASS-MIB::netSnmpPassCounter.0"
++CHECKORDIE "Counter32: 2"
++
++#COMMENT now kill the pass_persist script, and check that it recovers.
++STOPPROG $PASS_PERSIST_PIDFILE
++#COMMENT netSnmpPassCounter should have reverted to 1, as this is a new instance.
++CAPTURE "$SNMPGET $SNMP_FLAGS -$snmp_version -c $TESTCOMMUNITY $SNMP_TRANSPORT_SPEC:$SNMP_TEST_DEST$SNMP_SNMPD_PORT NET-SNMP-PASS-MIB::netSnmpPassCounter.0"
++CHECKORDIE "Counter32: 1"
++
++STOPAGENT
++FINISHED
+diff --git a/testing/fulltests/default/T111agentxset_simple b/testing/fulltests/default/T111agentxset_simple
+index 2423be5..c767064 100644
+--- a/testing/fulltests/default/T111agentxset_simple
++++ b/testing/fulltests/default/T111agentxset_simple
+@@ -7,6 +7,7 @@ HEADER AgentX SET support
+ SKIPIFNOT USING_AGENTX_MASTER_MODULE
+ SKIPIFNOT USING_AGENTX_SUBAGENT_MODULE
+ SKIPIFNOT USING_MIBII_SYSTEM_MIB_MODULE
++SKIPIF NETSNMP_DISABLE_SET_SUPPORT
+
+ #
+ # Begin test
+diff --git a/testing/fulltests/default/T112agentxsetfail_simple b/testing/fulltests/default/T112agentxsetfail_simple
+index 9976144..4f1f0cb 100644
+--- a/testing/fulltests/default/T112agentxsetfail_simple
++++ b/testing/fulltests/default/T112agentxsetfail_simple
+@@ -7,6 +7,7 @@ HEADER AgentX illegal SET handling support
+ SKIPIFNOT USING_AGENTX_MASTER_MODULE
+ SKIPIFNOT USING_AGENTX_SUBAGENT_MODULE
+ SKIPIFNOT USING_MIBII_SYSTEM_MIB_MODULE
++SKIPIF NETSNMP_DISABLE_SET_SUPPORT
+
+ #
+ # Begin test
+diff --git a/testing/fulltests/default/T114agentxagentxtrap_simple b/testing/fulltests/default/T114agentxagentxtrap_simple
+index ae72d5c..58475d0 100644
+--- a/testing/fulltests/default/T114agentxagentxtrap_simple
++++ b/testing/fulltests/default/T114agentxagentxtrap_simple
+@@ -38,7 +38,7 @@ STOPAGENT
+ STOPTRAPD
+
+ # Check that the trap was received
+-CHECKTRAPD "mostly_harmless"
++CHECKTRAPD "= STRING: \"*mostly_harmless\"*"
+
+ # all done (whew)
+ FINISHED
+diff --git a/testing/fulltests/default/T121proxyset_simple b/testing/fulltests/default/T121proxyset_simple
+index 335a2da..d3d77d9 100644
+--- a/testing/fulltests/default/T121proxyset_simple
++++ b/testing/fulltests/default/T121proxyset_simple
+@@ -6,7 +6,8 @@ HEADER Proxy SET support
+
+ SKIPIFNOT USING_UCD_SNMP_PROXY_MODULE
+ SKIPIFNOT USING_MIBII_SYSTEM_MIB_MODULE
+-SKIPIF NETSNMP_DISABLE_SNMPV2C
++SKIPIF NETSNMP_DISABLE_SNMPV2C
++SKIPIF NETSNMP_DISABLE_SET_SUPPORT
+
+ # XXX: ucd-snmp/proxy doesn't properly support TCP -- remove this once it does
+ [ "x$SNMP_TRANSPORT_SPEC" = "xtcp" -o "x$SNMP_TRANSPORT_SPEC" = "xtcp6" ] && SKIP
+diff --git a/testing/fulltests/default/T122proxysetfail_simple b/testing/fulltests/default/T122proxysetfail_simple
+index a49b3ef..d149f56 100644
+--- a/testing/fulltests/default/T122proxysetfail_simple
++++ b/testing/fulltests/default/T122proxysetfail_simple
+@@ -6,7 +6,8 @@ HEADER Proxy illegal SET handling support
+
+ SKIPIFNOT USING_UCD_SNMP_PROXY_MODULE
+ SKIPIFNOT USING_MIBII_SYSTEM_MIB_MODULE
+-SKIPIF NETSNMP_DISABLE_SNMPV2C
++SKIPIF NETSNMP_DISABLE_SNMPV2C
++SKIPIF NETSNMP_DISABLE_SET_SUPPORT
+
+ # XXX: ucd-snmp/proxy doesn't properly support TCP -- remove this once it does
+ [ "x$SNMP_TRANSPORT_SPEC" = "xtcp" ] && SKIP
+diff --git a/testing/fulltests/default/T130snmpv1vacmget_simple b/testing/fulltests/default/T130snmpv1vacmget_simple
+index 1974b7f..80623f4 100644
+--- a/testing/fulltests/default/T130snmpv1vacmget_simple
++++ b/testing/fulltests/default/T130snmpv1vacmget_simple
+@@ -16,6 +16,7 @@ SKIPIF NETSNMP_DISABLE_SNMPV1
+ snmp_version=v1
+ . ./Svacmconfig
+
++AGENT_FLAGS="$AGENT_FLAGS -I-winExtDLL"
+ STARTAGENT
+
+ CAPTURE "snmpget -On $SNMP_FLAGS -c testcommunity1 -v 1 $SNMP_TRANSPORT_SPEC:$SNMP_TEST_DEST$SNMP_SNMPD_PORT .1.3.6.1.2.1.1.1.0"
+diff --git a/testing/fulltests/default/T141snmpv2cvacmgetfail_simple b/testing/fulltests/default/T141snmpv2cvacmgetfail_simple
+index b97cf5d..69c2925 100644
+--- a/testing/fulltests/default/T141snmpv2cvacmgetfail_simple
++++ b/testing/fulltests/default/T141snmpv2cvacmgetfail_simple
+@@ -5,6 +5,7 @@
+ HEADER SNMPv2 vacm denial support
+
+ SKIPIF NETSNMP_DISABLE_SNMPV2C
++SKIPIF NETSNMP_DISABLE_SET_SUPPORT
+ SKIPIFNOT USING_MIBII_VACM_CONF_MODULE
+
+ #
+diff --git a/testing/fulltests/snmpv3/T040keymanagetest_capp.c b/testing/fulltests/snmpv3/T040keymanagetest_capp.c
+index f3f8dcc..d68f663 100644
+--- a/testing/fulltests/snmpv3/T040keymanagetest_capp.c
++++ b/testing/fulltests/snmpv3/T040keymanagetest_capp.c
+@@ -360,7 +360,6 @@ test_genkul(void)
+ char *s = NULL;
+ const char *testname = "Using HMACMD5 to create master key.";
+ const char *hashname_Ku = "usmHMACMD5AuthProtocol";
+- const char *hashname_kul = NULL;
+
+ u_char Ku[LOCAL_MAXBUF], kul[LOCAL_MAXBUF];
+
+@@ -413,7 +412,6 @@ test_genkul(void)
+ test_genkul_again_master:
+ memset(Ku, 0, LOCAL_MAXBUF);
+ kulen = LOCAL_MAXBUF;
+- hashname_kul = "usmHMACMD5AuthProtocol";
+ hashtype_kul = usmHMACMD5AuthProtocol;
+ properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACMD5);
+
+@@ -461,7 +459,6 @@ test_genkul(void)
+ */
+ if (hashtype_kul == usmHMACMD5AuthProtocol) {
+ hashtype_kul = usmHMACSHA1AuthProtocol;
+- hashname_kul = "usmHMACSHA1AuthProtocol";
+ properlength = BYTESIZE(SNMP_TRANS_AUTHLEN_HMACSHA1);
+ goto test_genkul_again_local;
+ }
+diff --git a/testing/fulltests/support/clib_build b/testing/fulltests/support/clib_build
+index 7a72285..0c7eb6d 100755
+--- a/testing/fulltests/support/clib_build
++++ b/testing/fulltests/support/clib_build
+@@ -13,6 +13,7 @@ cat >>"$2.c" <<EOF
+ #include <net-snmp/library/testing.h>
+
+ /* standard headers */
++#include <errno.h>
+ #include <stdio.h>
+ #include <sys/types.h>
+ #ifdef HAVE_STDLIB_H
+@@ -23,6 +24,9 @@ cat >>"$2.c" <<EOF
+ #else
+ #include <strings.h>
+ #endif
++#ifdef HAVE_NETDB_H
++#include <netdb.h>
++#endif
+ #ifdef HAVE_ARPA_INET_H
+ #include <arpa/inet.h>
+ #endif
+diff --git a/testing/fulltests/support/simple_TESTCONF.sh b/testing/fulltests/support/simple_TESTCONF.sh
+index f8f229a..83c38c2 100644
+--- a/testing/fulltests/support/simple_TESTCONF.sh
++++ b/testing/fulltests/support/simple_TESTCONF.sh
+@@ -7,6 +7,28 @@
+ # *SNMP_PERSISTENT_FILE: where to store the agent's persistent information
+ # (XXX: this should be specific to just the agent)
+
++# MinGW/MSYS only: translate an MSYS path back into a DOS path such that snmpd
++# and the Net-SNMP applications can understand it. One of the features of MSYS
++# is that if a POSIX-style path is passed as a command-line argument to an
++# executable that MSYS translates that path to a DOS-style path before
++# starting the executable. This is a key feature of MSYS that makes it
++# possible to run shell scripts unmodified and at the same time to use
++# executables that accept DOS-style paths. There is no support however for
++# automatical translation of environment variables that contain paths. Hence
++# this function that translates paths explicitly.
++translate_path() {
++ if [ "$OSTYPE" = msys ]; then
++ local t=`set \
++ | sed -n -e "s/^$1='\(.*\)'$/${SNMP_ENV_SEPARATOR}\1/p" \
++ -e "s/^$1=\(.*\)$/${SNMP_ENV_SEPARATOR}\1/p" \
++ | sed -e "s|${SNMP_ENV_SEPARATOR}/c/|${SNMP_ENV_SEPARATOR}c:/|g" \
++ -e "s|${SNMP_ENV_SEPARATOR}/tmp/|${SNMP_ENV_SEPARATOR}c:/windows/temp/|g" \
++ | sed -e "s/^${SNMP_ENV_SEPARATOR}//" \
++ `
++ eval "$1='$t'"
++ fi
++}
++
+ #
+ # Only allow ourselves to be eval'ed once
+ #
+@@ -48,6 +70,8 @@ if [ "x$SNMP_VERBOSE" = "x" ]; then
+ export SNMP_VERBOSE
+ fi
+
++SNMP_ENV_SEPARATOR="`${builddir}/net-snmp-config --env-separator`"
++
+ if [ "x$MIBDIRS" = "x" ]; then
+ if [ "x$SNMP_PREFER_NEAR_MIBS" = "x1" ]; then
+ MIBDIRS=${srcdir}/mibs
+@@ -103,6 +127,7 @@ if [ "x$SNMP_HEADERONLY" != "xyes" ]; then
+ testnum=0
+ fi
+ SNMP_TMPDIR="/tmp/snmp-test-$testnum-$$"
++ translate_path SNMP_TMPDIR
+ export SNMP_TMPDIR
+ if [ -d $SNMP_TMPDIR ]; then
+ echo "$0: ERROR: $SNMP_TMPDIR already existed."
+@@ -110,7 +135,7 @@ if [ "x$SNMP_HEADERONLY" != "xyes" ]; then
+ fi
+ fi
+ if [ ! -d $SNMP_TMPDIR ]; then
+- mkdir $SNMP_TMPDIR
++ mkdir -p $SNMP_TMPDIR
+ chmod 0700 $SNMP_TMPDIR
+ fi
+ if [ "x$SNMP_TMP_PERSISTENTDIR" = "x" ]; then
+@@ -130,7 +155,6 @@ fi
+
+ SNMP_IGNORE_WINDOWS_REGISTRY="true"
+ export SNMP_IGNORE_WINDOWS_REGISTRY
+-SNMP_ENV_SEPARATOR="`${builddir}/net-snmp-config --env-separator`"
+ SNMP_PERLPROG="`${builddir}/net-snmp-config --perlprog`"
+ SNMP_TESTDIR="$SNMP_BASEDIR/tests"
+ SNMP_CONFIG_FILE="$SNMP_TMPDIR/snmpd.conf"
+@@ -144,8 +168,10 @@ SNMP_SNMPD_LOG_FILE="$SNMP_TMPDIR/snmpd.log"
+ SNMP_AGENTX_PID_FILE="$SNMP_TMPDIR/agentx.pid"
+ SNMP_AGENTX_LOG_FILE="$SNMP_TMPDIR/agentx.log"
+ SNMPCONFPATH="${SNMP_TMPDIR}${SNMP_ENV_SEPARATOR}${SNMP_TMP_PERSISTENTDIR}"
++translate_path SNMPCONFPATH
+ export SNMPCONFPATH
+ SNMP_PERSISTENT_DIR=$SNMP_TMP_PERSISTENTDIR
++translate_path SNMP_PERSISTENT_DIR
+ export SNMP_PERSISTENT_DIR
+ #SNMP_PERSISTENT_FILE="$SNMP_TMP_PERSISTENTDIR/persistent-store.conf"
+ #export SNMP_PERSISTENT_FILE
+@@ -175,8 +201,12 @@ else
+ fi
+
+ if [ "x$OSTYPE" = "xmsys" ]; then
+- # To do: make configure find out the path of MSYS' sh.exe.
+- MSYS_SH="c:/msys/1.0/bin/sh.exe"
++ # Obtain the MSYS installation path from the !C: environment variable,
++ # remove surrounding single quotes and convert backslashes into forward
++ # slashes.
++ MSYS_PATH="$(set \
++ | sed -n 's|^\!C:='"'"'\(.*\)'"'"'$|\1|p' | sed 's|\\|/|g')"
++ MSYS_SH="$MSYS_PATH/sh.exe"
+ fi
+
+ PROBE_FOR_PORT() {
+diff --git a/testing/fulltests/support/simple_eval_tools.sh b/testing/fulltests/support/simple_eval_tools.sh
+index f16d9a6..d1dfbc8 100644
+--- a/testing/fulltests/support/simple_eval_tools.sh
++++ b/testing/fulltests/support/simple_eval_tools.sh
+@@ -114,7 +114,7 @@ SKIP() {
+ }
+
+ ISDEFINED() {
+- grep "^#define $1" ${builddir}/include/net-snmp/net-snmp-config.h ${builddir}/include/net-snmp/agent/mib_module_config.h ${builddir}/include/net-snmp/agent/agent_module_config.h > /dev/null
++ grep -wq "^#define $1" ${builddir}/include/net-snmp/net-snmp-config.h ${builddir}/include/net-snmp/agent/mib_module_config.h ${builddir}/include/net-snmp/agent/agent_module_config.h
+ }
+
+ SKIPIFNOT() {
+@@ -131,7 +131,7 @@ VERIFY() { # <path_to_file(s)>
+ local missingfiles=
+
+ for f in $*; do
+- [ -e "$f" ] && continue
++ [ -f "$f" ] && continue
+ echo "FAILED: Cannot find file \"$f\"."
+ missingfiles=true
+ done
+@@ -148,7 +148,7 @@ NEWOUTPUTFILE() {
+ #
+ STARTTEST() {
+ NEWOUTPUTFILE
+- [ ! -e "$junkoutputfile" ] && {
++ [ ! -f "$junkoutputfile" ] && {
+ touch $junkoutputfile
+ return
+ }
+@@ -365,7 +365,7 @@ ISRUNNING() {
+ # Echo a command that asks the process with pid $1 to stop.
+ ECHOSENDSIGTERM() {
+ if [ "x$OSTYPE" = "xmsys" ]; then
+- echo kill.exe $1
++ echo pskill.exe $1
+ else
+ echo kill -TERM $1
+ fi
+@@ -374,7 +374,7 @@ ECHOSENDSIGTERM() {
+ # Echo a command that stops the process with pid $1 forcibly.
+ ECHOSENDSIGKILL() {
+ if [ "x$OSTYPE" = "xmsys" ]; then
+- echo kill.exe $1
++ echo pskill.exe $1
+ else
+ echo kill -KILL $1
+ fi
+@@ -489,7 +489,6 @@ CONFIGAPP() {
+ #
+ # common to STARTAGENT and STARTTRAPD
+ # log command to "invoked" file
+-# delay after command to allow for settle
+ #
+ STARTPROG() {
+ if [ "x$DYNAMIC_ANALYZER" != "x" ]; then
+@@ -537,6 +536,7 @@ STARTAGENT() {
+ PORT_SPEC="${SNMP_TRANSPORT_SPEC}:${SNMP_TEST_DEST}${PORT_SPEC}"
+ fi
+ STARTPROG
++ WAITFORCOND test -f $SNMP_SNMPD_PID_FILE
+ WAITFORAGENT "NET-SNMP version"
+ }
+
+@@ -551,6 +551,7 @@ STARTTRAPD() {
+ PORT_SPEC="${SNMP_TRANSPORT_SPEC}:${SNMP_TEST_DEST}${PORT_SPEC}"
+ fi
+ STARTPROG
++ WAITFORCOND test -f $SNMP_SNMPTRAPD_PID_FILE
+ WAITFORTRAPD "NET-SNMP version"
+ }
+
+@@ -559,7 +560,7 @@ STARTTRAPD() {
+ HUPPROG() {
+ if [ -f $1 ]; then
+ if [ "x$OSTYPE" = "xmsys" ]; then
+- COMMAND='echo "Skipping SIGHUP (not supported by kill.exe on MinGW)"'
++ COMMAND='echo "Skipping SIGHUP (not possible with MinGW)"'
+ else
+ COMMAND="kill -HUP `cat $1`"
+ fi
+@@ -595,7 +596,10 @@ STOPPROG() {
+ echo "$COMMAND ($1)" >> $SNMP_TMPDIR/invoked
+ VERBOSE_OUT 0 "$COMMAND ($1)"
+ $COMMAND >/dev/null 2>&1
+- if [ "x$OSTYPE" != "xmsys" ]; then
++ if [ "x$OSTYPE" = "xmsys" ]; then
++ # Wait until $pid and its parent have stopped.
++ sleep 1
++ else
+ WAITFORNOTCOND "ISRUNNING $pid"
+ fi
+ fi
+diff --git a/testing/fulltests/unit-tests/T004snmp_enum_clib.c b/testing/fulltests/unit-tests/T004snmp_enum_clib.c
+index e78ffca..d28b19b 100644
+--- a/testing/fulltests/unit-tests/T004snmp_enum_clib.c
++++ b/testing/fulltests/unit-tests/T004snmp_enum_clib.c
+@@ -1,15 +1,69 @@
+ /* HEADER Testing snmp_enum */
+
++#define CONFIG_TYPE "snmp-enum-unit-test"
+ #define STRING1 "life, and everything"
+ #define STRING2 "restaurant at the end of the universe"
+ #define STRING3 "label3"
++#define LONG_STRING "a-string-of-255-characters-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------"
+
++#define STORE_AND_COMPARE(maj, min, s) \
++ { \
++ FILE *fp; \
++ int read = 0; \
++ char *p, contents[4096]; \
++ \
++ se_store_list(maj, min, CONFIG_TYPE); \
++ fp = fopen(tmp_persist_file, "r"); \
++ if (fp) { \
++ read = fread(contents, 1, sizeof(contents) - 1, fp); \
++ fclose(fp); \
++ } \
++ contents[read > 0 ? read : 0] = '\0'; \
++ for (p = contents; *p; ++p) \
++ if (*p == '\n') \
++ *p = '|'; \
++ OKF(strcmp(contents, (s)) == 0, \
++ ("stored list %s <> %s", (s), contents)); \
++ remove(tmp_persist_file); \
++ }
++
++char tmp_persist_file[256];
+ char *se_find_result;
+
++sprintf(tmp_persist_file, "/tmp/snmp-enum-unit-test-%d", getpid());
++netsnmp_setenv("SNMP_PERSISTENT_FILE", tmp_persist_file, 1);
++
+ init_snmp_enum("snmp");
++
++STORE_AND_COMPARE(1, 1, "enum 1:1|");
++
+ se_add_pair(1, 1, strdup("hi"), 1);
++
++STORE_AND_COMPARE(1, 1, "enum 1:1 1:hi|");
++
+ se_add_pair(1, 1, strdup("there"), 2);
+
++STORE_AND_COMPARE(1, 1, "enum 1:1 1:hi 2:there|");
++
++se_add_pair(1, 1, strdup(LONG_STRING), 3);
++se_add_pair(1, 1, strdup(LONG_STRING), 4);
++se_add_pair(1, 1, strdup(LONG_STRING), 5);
++se_add_pair(1, 1, strdup(LONG_STRING), 6);
++se_add_pair(1, 1, strdup(LONG_STRING), 7);
++se_add_pair(1, 1, strdup(LONG_STRING), 8);
++se_add_pair(1, 1, strdup(LONG_STRING), 9);
++
++STORE_AND_COMPARE(1, 1, "enum 1:1 1:hi 2:there 3:" LONG_STRING " 4:" LONG_STRING
++ " 5:" LONG_STRING " 6:" LONG_STRING " 7:" LONG_STRING
++ " 8:" LONG_STRING " 9:" LONG_STRING "|");
++
++se_add_pair(1, 1, strdup(LONG_STRING), 10);
++
++STORE_AND_COMPARE(1, 1, "enum 1:1 1:hi 2:there 3:" LONG_STRING " 4:" LONG_STRING
++ " 5:" LONG_STRING " 6:" LONG_STRING " 7:" LONG_STRING
++ " 8:" LONG_STRING " 9:" LONG_STRING "|"
++ "enum 1:1 10:" LONG_STRING "|");
++
+ OK(se_find_value(1, 1, "hi") == 1,
+ "lookup by number #1 should be the proper string");
+ OK(strcmp(se_find_label(1, 1, 2), "there") == 0,
+@@ -33,10 +87,10 @@ se_read_conf("enum",
+ OK(se_find_list(2, 3), "list (2, 3) should be present");
+ if (se_find_list(2, 3)) {
+ OK(se_find_value(2, 3, "kiwifruit") == 3,
+- "lookup by string should return the proper value")
++ "lookup by string should return the proper value");
+ se_find_result = se_find_label(2, 3, 2);
+ OK(se_find_result && strcmp(se_find_result, "pear") == 0,
+- "lookup by label should return the proper string")
++ "lookup by label should return the proper string");
+ }
+
+ se_read_conf("enum",
+diff --git a/testing/fulltests/unit-tests/T008asn1_clib.c b/testing/fulltests/unit-tests/T008asn1_clib.c
+index 222ec7a..73a2f73 100644
+--- a/testing/fulltests/unit-tests/T008asn1_clib.c
++++ b/testing/fulltests/unit-tests/T008asn1_clib.c
+@@ -78,6 +78,8 @@ debug_register_tokens("dumpv_recv,dumpv_send,asn");
+ }
+ }
+
++#ifdef NETSNMP_WITH_OPAQUE_SPECIAL_TYPES
++
+ #define TOINT64(c) ((long long)(long)(c).high << 32 | (c).low)
+
+ {
+@@ -128,6 +130,8 @@ debug_register_tokens("dumpv_recv,dumpv_send,asn");
+ }
+ }
+
++#endif
++
+ #define TOUINT64(c) ((unsigned long long)(c).high << 32 | (c).low)
+
+ {
+diff --git a/testing/fulltests/unit-tests/T009large_fd_set_clib.c b/testing/fulltests/unit-tests/T009large_fd_set_clib.c
+index 0951dc2..eee4d41 100644
+--- a/testing/fulltests/unit-tests/T009large_fd_set_clib.c
++++ b/testing/fulltests/unit-tests/T009large_fd_set_clib.c
+@@ -2,7 +2,8 @@
+
+ netsnmp_large_fd_set fds;
+ netsnmp_large_fd_set_init(&fds, 2000);
+-netsnmp_large_fd_set_resize(&fds, 2000);
++OKF(fds.lfs_setsize == 2000, ("initialization"));
++OKF(netsnmp_large_fd_set_resize(&fds, 2000) == 1, ("resizing to 2000"));
+ NETSNMP_LARGE_FD_ZERO(&fds);
+
+ {
+@@ -16,7 +17,7 @@ NETSNMP_LARGE_FD_ZERO(&fds);
+ }
+ }
+
+-netsnmp_large_fd_set_resize(&fds, 3000);
++OKF(netsnmp_large_fd_set_resize(&fds, 3000) == 1, ("resizing to 3000"));
+
+ {
+ int i;
+@@ -29,7 +30,7 @@ netsnmp_large_fd_set_resize(&fds, 3000);
+ }
+ }
+
+-netsnmp_large_fd_set_resize(&fds, 1000);
++OKF(netsnmp_large_fd_set_resize(&fds, 1000) == 1, ("resizing to 1000"));
+
+ {
+ int i;
+diff --git a/testing/fulltests/unit-tests/T011snmp_old_api_registration_cagentlib.c b/testing/fulltests/unit-tests/T011snmp_old_api_registration_cagentlib.c
+new file mode 100644
+index 0000000..6f1d449
+--- /dev/null
++++ b/testing/fulltests/unit-tests/T011snmp_old_api_registration_cagentlib.c
+@@ -0,0 +1,46 @@
++/* HEADER Testing SNMP handler registration via the old API */
++
++static oid Oid[] = { 1, 3, 6, 1, 3, 327 }; /* experimental.327 */
++struct variable var_array[] = {
++ { 0, 0/*type*/, 0/*acl*/, NULL/*findVar*/, 7, { 1, 3, 6, 1, 3, 327, 1 } },
++ { 0, 0/*type*/, 0/*acl*/, NULL/*findVar*/, 7, { 1, 3, 6, 1, 3, 327, 2 } },
++ { 0, 0/*type*/, 0/*acl*/, NULL/*findVar*/, 7, { 1, 3, 6, 1, 3, 327, 3 } },
++};
++netsnmp_session *sess;
++int res;
++
++init_snmp("snmp");
++
++sess = calloc(1, sizeof(*sess));
++snmp_sess_init(sess);
++
++res =
++netsnmp_register_old_api("exp.327.a",
++ var_array,
++ sizeof(var_array[0]),
++ sizeof(var_array)/sizeof(var_array[0]),
++ Oid,
++ sizeof(Oid)/sizeof(Oid[0]),
++ 2, /* priority */
++ 0, /* range_subid */
++ 0, /* range_ubound */
++ sess,
++ "context", 5/*timeout*/, 0/*flags - ignored*/);
++OK(res == SNMPERR_SUCCESS, "Handler registration (1).");
++
++/* Verify that duplicate registration does not cause any havoc. */
++res =
++netsnmp_register_old_api("exp.327.b",
++ var_array,
++ sizeof(var_array[0]),
++ sizeof(var_array)/sizeof(var_array[0]),
++ Oid,
++ sizeof(Oid)/sizeof(Oid[0]),
++ 2, /* priority */
++ 0, /* range_subid */
++ 0, /* range_ubound */
++ sess,
++ "context", 5/*timeout*/, 0/*flags - ignored*/);
++OK(res == SNMPERR_SUCCESS, "Handler registration (2).");
++
++snmp_shutdown("snmp");
+diff --git a/testing/fulltests/unit-tests/T012binary_array_oid_clib.c b/testing/fulltests/unit-tests/T012binary_array_oid_clib.c
+new file mode 100644
+index 0000000..aeeb502
+--- /dev/null
++++ b/testing/fulltests/unit-tests/T012binary_array_oid_clib.c
+@@ -0,0 +1,72 @@
++/* HEADER Testing binary OID array */
++
++static const char test_name[] = "binary-array-of-OIDs-test";
++oid o1 = 1;
++oid o2 = 2;
++oid o3 = 6;
++oid o4 = 8;
++oid o5 = 9;
++oid ox = 7;
++oid oy = 10;
++netsnmp_index i1, i2, i3, i4, i5, ix, iy, *ip;
++const netsnmp_index *const i_last = &i5;
++netsnmp_index *a[] = { &ix, &iy };
++netsnmp_index *b[] = { &i4, &i2, &i3, &i1, &i5 };
++netsnmp_container *c;
++int i;
++
++init_snmp(test_name);
++
++c = netsnmp_container_get_binary_array();
++c->compare = netsnmp_compare_netsnmp_index;
++
++i1.oids = &o1;
++i2.oids = &o2;
++i3.oids = &o3;
++i4.oids = &o4;
++i5.oids = &o5;
++ix.oids = &ox;
++iy.oids = &oy;
++i1.len = i2.len = i3.len = i4.len = i5.len = ix.len = iy.len = 1;
++
++for (i = 0; i < sizeof(b)/sizeof(b[0]); ++i)
++ CONTAINER_INSERT(c, b[i]);
++
++for (ip = CONTAINER_FIRST(c); ip; ip = CONTAINER_NEXT(c, ip)) {
++ for (i = sizeof(b)/sizeof(b[0]) - 1; i >= 0; --i)
++ if (c->compare(ip, b[i]) == 0)
++ break;
++ OKF(i >= 0, ("OID b[%d] = %" NETSNMP_PRIo "d present", i, b[i]->oids[0]));
++}
++
++for (i = 0; i < sizeof(b)/sizeof(b[0]); ++i) {
++ ip = CONTAINER_FIND(c, b[i]);
++ OKF(ip, ("Value b[%d] = %" NETSNMP_PRIo "d present", i, b[i]->oids[0]));
++ ip = CONTAINER_NEXT(c, b[i]);
++ if (c->compare(b[i], i_last) < 0)
++ OKF(ip && c->compare(b[i], ip) < 0,
++ ("Successor of b[%d] = %" NETSNMP_PRIo "d is %" NETSNMP_PRIo "d",
++ i, b[i]->oids[0], ip->oids[0]));
++ else
++ OKF(!ip, ("No successor found for b[%d] = %" NETSNMP_PRIo "d", i,
++ b[i]->oids[0]));
++}
++
++for (i = 0; i < sizeof(a)/sizeof(a[0]); ++i) {
++ ip = CONTAINER_FIND(c, a[i]);
++ OKF(!ip, ("a[%d] = %" NETSNMP_PRIo "d absent", i, a[i]->oids[0]));
++ ip = CONTAINER_NEXT(c, a[i]);
++ if (c->compare(a[i], i_last) < 0)
++ OKF(ip && c->compare(ip, a[i]) > 0,
++ ("Successor of a[%d] = %" NETSNMP_PRIo "d is %" NETSNMP_PRIo "d",
++ i, a[i]->oids[0], ip->oids[0]));
++ else
++ OKF(!ip, ("No successor found for a[%d] = %" NETSNMP_PRIo "d", i,
++ a[i]->oids[0]));
++}
++
++while ((ip = CONTAINER_FIRST(c)))
++ CONTAINER_REMOVE(c, ip);
++CONTAINER_FREE(c);
++
++snmp_shutdown(test_name);
+diff --git a/testing/fulltests/unit-tests/T013binary_array_string_clib.c b/testing/fulltests/unit-tests/T013binary_array_string_clib.c
+new file mode 100644
+index 0000000..cc4361b
+--- /dev/null
++++ b/testing/fulltests/unit-tests/T013binary_array_string_clib.c
+@@ -0,0 +1,59 @@
++/* HEADER Testing binary string array */
++
++static const char test_name[] = "binary-array-of-strings-test";
++const char o1[] = "zebra";
++const char o2[] = "b-two";
++const char o3[] = "b";
++const char o4[] = "cedar";
++const char o5[] = "alpha";
++const char ox[] = "dev";
++const char oy[] = "aa";
++const char* const o_last = o1;
++const char *ip;
++const char *const a[] = { ox, oy };
++const char *const b[] = { o4, o2, o3, o1, o5 };
++netsnmp_container *c;
++int i;
++
++init_snmp(test_name);
++
++c = netsnmp_container_get_binary_array();
++c->compare = (netsnmp_container_compare*)strcmp;
++
++for (i = 0; i < sizeof(b)/sizeof(b[0]); ++i)
++ CONTAINER_INSERT(c, b[i]);
++
++for (ip = CONTAINER_FIRST(c); ip; ip = CONTAINER_NEXT(c, ip)) {
++ for (i = sizeof(b)/sizeof(b[0]) - 1; i >= 0; --i)
++ if (c->compare(ip, b[i]) == 0)
++ break;
++ OKF(i >= 0, ("string b[%d] = \"%s\" present", i, b[i]));
++}
++
++for (i = 0; i < sizeof(b)/sizeof(b[0]); ++i) {
++ ip = CONTAINER_FIND(c, b[i]);
++ OKF(ip, ("b[%d] = \"%s\" present", i, b[i]));
++ ip = CONTAINER_NEXT(c, b[i]);
++ if (c->compare(b[i], o_last) < 0)
++ OKF(ip && c->compare(b[i], ip) < 0,
++ ("Successor of b[%d] = \"%s\" is \"%s\"", i, b[i], ip));
++ else
++ OKF(!ip, ("No successor found for b[%d] = \"%s\"", i, b[i]));
++}
++
++for (i = 0; i < sizeof(a)/sizeof(a[0]); ++i) {
++ ip = CONTAINER_FIND(c, a[i]);
++ OKF(!ip, ("a[%d] = \"%s\" absent", i, a[i]));
++ ip = CONTAINER_NEXT(c, a[i]);
++ if (c->compare(a[i], o_last) < 0)
++ OKF(ip && c->compare(ip, a[i]) > 0,
++ ("Successor of a[%d] = \"%s\" is \"%s\"", i, a[i], ip));
++ else
++ OKF(!ip, ("No successor found for a[%d] = \"%s\"", i, a[i]));
++}
++
++while ((ip = CONTAINER_FIRST(c)))
++ CONTAINER_REMOVE(c, ip);
++CONTAINER_FREE(c);
++
++snmp_shutdown(test_name);
+diff --git a/testing/fulltests/unit-tests/T014gethostbyaddr_clib.c b/testing/fulltests/unit-tests/T014gethostbyaddr_clib.c
+new file mode 100644
+index 0000000..4c633ed
+--- /dev/null
++++ b/testing/fulltests/unit-tests/T014gethostbyaddr_clib.c
+@@ -0,0 +1,55 @@
++/* HEADER Testing netsnmp_gethostbyaddr() */
++
++SOCK_STARTUP;
++
++{
++ int ran_test = 0;
++#ifdef HAVE_GETHOSTBYADDR
++ struct hostent *h;
++ struct in_addr v4loop;
++ struct sockaddr_in sin_addr;
++ int s;
++
++ v4loop.s_addr = htonl(INADDR_LOOPBACK);
++ memset(&sin_addr, 0, sizeof(sin_addr));
++ sin_addr.sin_family = AF_INET;
++ sin_addr.sin_addr = v4loop;
++ s = socket(AF_INET, SOCK_DGRAM, 0);
++ if (s >= 0) {
++ if (bind(s, (struct sockaddr *)&sin_addr, sizeof(sin_addr)) >= 0) {
++ h = netsnmp_gethostbyaddr(&v4loop, sizeof(v4loop), AF_INET);
++ OKF(h && strcmp(h->h_name, "localhost") == 0,
++ ("127.0.0.1 lookup (%s)", h ? h->h_name : "(failed)"));
++ ran_test = 1;
++ }
++ close(s);
++ }
++#endif
++ if (!ran_test)
++ OKF(1, ("Skipped IPv4 test"));
++}
++
++{
++ struct hostent *h;
++ static const struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT;
++ struct sockaddr_in6 sin6_addr;
++ int s, ran_test = 0;
++
++ memset(&sin6_addr, 0, sizeof(sin6_addr));
++ sin6_addr.sin6_family = AF_INET6;
++ sin6_addr.sin6_addr = v6loop;
++ s = socket(AF_INET6, SOCK_DGRAM, 0);
++ if (s >= 0) {
++ if (bind(s, (struct sockaddr*)&sin6_addr, sizeof(sin6_addr)) >= 0) {
++ h = netsnmp_gethostbyaddr(&v6loop, sizeof(v6loop), AF_INET6);
++ OKF(h && strcmp(h->h_name, "localhost") == 0,
++ ("::1 lookup (%s)", h ? h->h_name : "(failed)"));
++ ran_test = 1;
++ }
++ close(s);
++ }
++ if (!ran_test)
++ OKF(1, ("Skipped IPv6 test"));
++}
++
++SOCK_CLEANUP;
+diff --git a/testing/fulltests/unit-tests/T015int64_clib.c b/testing/fulltests/unit-tests/T015int64_clib.c
+new file mode 100644
+index 0000000..5f5f4b6
+--- /dev/null
++++ b/testing/fulltests/unit-tests/T015int64_clib.c
+@@ -0,0 +1,82 @@
++/* HEADER Testing 64-bit integer operations (U64). */
++
++int i, j;
++char buf[22];
++static const int64_t intval[] = {
++ 0,
++ -1,
++ 1,
++ 37,
++ 0x7fffffffUL,
++ 0x80000000UL,
++ 0x99999999UL,
++ 0x7fffffffffffffffULL,
++ 0x8000000000000000ULL,
++};
++
++for (i = 0; i < sizeof(intval)/sizeof(intval[0]); ++i) {
++ U64 a, b;
++ a.low = (uint32_t)intval[i];
++ a.high = (uint32_t)(intval[i] >> 32);
++ printI64(buf, &a);
++ read64(&b, buf);
++ OKF(memcmp(&a, &b, sizeof(a)) == 0,
++ ("[%d]: %" PRId64 " <> %s <> %" PRId64, i, intval[i], buf,
++ ((uint64_t)b.high) << 32 | b.low));
++}
++
++for (i = 0; i < sizeof(intval)/sizeof(intval[0]); ++i) {
++ for (j = i; j < sizeof(intval)/sizeof(intval[0]); ++j) {
++ U64 a, b;
++ uint64_t d;
++ a.low = (uint32_t)intval[i];
++ a.high = (uint32_t)(intval[i] >> 32);
++ b.low = (uint32_t)intval[j];
++ b.high = (uint32_t)(intval[j] >> 32);
++ u64Incr(&a, &b);
++ d = (uint64_t)a.high << 32 | a.low;
++ OKF(intval[i] + intval[j] == d,
++ ("%" PRId64 " + %" PRId64 " = %" PRId64 " <> %" PRId64, intval[i],
++ intval[j], intval[i] + intval[j], d));
++ }
++}
++
++for (i = 0; i < sizeof(intval)/sizeof(intval[0]); ++i) {
++ for (j = i; j < sizeof(intval)/sizeof(intval[0]); ++j) {
++ U64 a, b, c;
++ uint64_t d;
++ a.low = (uint32_t)intval[i];
++ a.high = (uint32_t)(intval[i] >> 32);
++ b.low = (uint32_t)intval[j];
++ b.high = (uint32_t)(intval[j] >> 32);
++ u64Subtract(&a, &b, &c);
++ d = (uint64_t)c.high << 32 | c.low;
++ OKF(intval[i] - intval[j] == d,
++ ("%" PRId64 " - %" PRId64 " = %" PRId64 " <> %" PRId64, intval[i],
++ intval[j], intval[i] - intval[j], d));
++ }
++}
++
++{
++ U64 old_val, new_val;
++ old_val.low = 7;
++ old_val.high = 0;
++ new_val = old_val;
++ OK(netsnmp_c64_check_for_32bit_wrap(&old_val, &new_val, 0) == 0, "cwrap1");
++ new_val.low = 8;
++ OK(netsnmp_c64_check_for_32bit_wrap(&old_val, &new_val, 0) == 0, "cwrap2");
++ new_val.low = 6;
++ OK(netsnmp_c64_check_for_32bit_wrap(&old_val, &new_val, 0) == 32, "cwrap3");
++ OK(netsnmp_c64_check_for_32bit_wrap(&old_val, &new_val, 1) == 32
++ && new_val.low == 6 && new_val.high == 1, "cwrap4");
++ old_val.low = 7;
++ old_val.high = 0xffffffffU;
++ new_val.low = 7;
++ new_val.high = old_val.high;
++ OK(netsnmp_c64_check_for_32bit_wrap(&old_val, &new_val, 0) == 0, "cwrap5");
++ new_val.low = 8;
++ OK(netsnmp_c64_check_for_32bit_wrap(&old_val, &new_val, 0) == 0, "cwrap6");
++ new_val.low = 6;
++ new_val.high = 0;
++ OK(netsnmp_c64_check_for_32bit_wrap(&old_val, &new_val, 0) == 64, "cwrap7");
++}
+diff --git a/testing/fulltests/unit-tests/T016read_config_clib.c b/testing/fulltests/unit-tests/T016read_config_clib.c
+new file mode 100644
+index 0000000..c11a591
+--- /dev/null
++++ b/testing/fulltests/unit-tests/T016read_config_clib.c
+@@ -0,0 +1,82 @@
++/* HEADER Testing read_config_read_octet_string_const(). */
++
++struct read_config_testcase {
++ /*
++ * inputs
++ */
++ const char *(*pf) (const char * readfrom, u_char ** str,
++ size_t * len);
++ const char *readfrom;
++ size_t obuf_len;
++
++ /*
++ * expected outputs
++ */
++ size_t expected_offset;
++ const u_char *expected_output;
++ size_t expected_len;
++};
++
++static const u_char obuf1[] = { 1, 0, 2 };
++static const u_char obuf2[] = { 'a', 'b', 'c', 0 };
++
++static const struct read_config_testcase test_input[] = {
++ { &read_config_read_octet_string_const, "", 1, -1, NULL, 0 },
++ { &read_config_read_octet_string_const, "0x0", 1, -1, NULL, 1 },
++ { &read_config_read_octet_string_const, "0x0 0", 1, -1, NULL, 1 },
++
++ { &read_config_read_octet_string_const, "0x010002", 1, -1, NULL, 0 },
++ { &read_config_read_octet_string_const, "0x010002", 2, -1, NULL, 0 },
++ { &read_config_read_octet_string_const, "0x010002", 3, -1, obuf1, 0 },
++ { &read_config_read_octet_string_const, "0x010002", 4, -1, obuf1, 3 },
++ { &read_config_read_octet_string_const, "0x010002 0", 4, 9, obuf1, 3 },
++ { &read_config_read_octet_string_const, "0x010002", 0, -1, obuf1, 3 },
++
++ { &read_config_read_octet_string_const, "abc", 1, -1, NULL, 0 },
++ { &read_config_read_octet_string_const, "abc z", 1, 4, NULL, 0 },
++ { &read_config_read_octet_string_const, "abc", 2, -1, NULL, 1 },
++ { &read_config_read_octet_string_const, "abc", 3, -1, obuf2, 2 },
++ { &read_config_read_octet_string_const, "abc", 4, -1, obuf2, 3 },
++ { &read_config_read_octet_string_const, "abc z", 4, 4, obuf2, 3 },
++ { &read_config_read_octet_string_const, "abc", 0, -1, obuf2, 3 },
++};
++
++unsigned int i, j, ok;
++
++for (i = 0; i < sizeof(test_input) / sizeof(test_input[0]); i++) {
++ const struct read_config_testcase *const p = &test_input[i];
++ size_t len = p->obuf_len;
++ u_char *str = len > 0 ? malloc(len) : NULL;
++ const char *result;
++ size_t offset;
++
++ fflush(stdout);
++ result = (p->pf) (p->readfrom, &str, &len);
++ offset = result ? result - p->readfrom : -1;
++ OKF(offset == p->expected_offset,
++ ("test %d: expected offset %zd, got offset %" NETSNMP_PRIz "d",
++ i, p->expected_offset, offset));
++ if (offset == p->expected_offset) {
++ OKF(len == p->expected_len,
++ ("test %d: expected length %" NETSNMP_PRIz "d, got length %"
++ NETSNMP_PRIz "d", i, p->expected_len, len));
++ if (len == p->expected_len) {
++ ok = len < 0 || !p->expected_output
++ || memcmp(str, p->expected_output, len) == 0
++ || p->expected_output[len] != 0;
++ OKF(ok, ("test %d: output buffer mismatch", i));
++ if (!ok) {
++ printf("Expected: ");
++ for (j = 0; j < p->expected_len; ++j)
++ printf("%02x ", p->expected_output[j]);
++ printf("\nActual: ");
++ for (j = 0; j < len; ++j)
++ printf("%02x ", str[j]);
++ printf("\n");
++ }
++ }
++ }
++
++ if (str)
++ free(str);
++}
+diff --git a/testing/fulltests/unit-tests/T017strtoull_clib.c b/testing/fulltests/unit-tests/T017strtoull_clib.c
+new file mode 100644
+index 0000000..4ab9cad
+--- /dev/null
++++ b/testing/fulltests/unit-tests/T017strtoull_clib.c
+@@ -0,0 +1,94 @@
++/* HEADER Testing strtoull(). */
++
++#ifdef HAVE_STRTOULL
++
++OK(1, "Skipping strtoull() test because using strtoull() from C library.\n");;
++
++#else
++
++/*
++ * UINT64_C: C99 macro for the suffix for uint64_t constants.
++ */
++#ifndef UINT64_C
++#ifdef _MSC_VER
++#define UINT64_C(c) c##ui64
++#else
++#define UINT64_C(c) c##ULL
++#endif
++#endif
++
++/*
++ * According to the C99 standard, the constant ULLONG_MAX must be defined in
++ * <limits.h>. Define it here for pre-C99 compilers.
++ */
++#ifndef ULLONG_MAX
++#define ULLONG_MAX UINT64_C(0xffffffffffffffff)
++#endif
++
++#ifndef PRIu64
++#ifdef _MSC_VER
++#define PRIu64 "I64u"
++#else
++#define PRIu64 "llu"
++#endif
++#endif
++
++struct strtoull_testcase {
++ /*
++ * inputs
++ */
++ const char *nptr;
++ int base;
++ /*
++ * expected outputs
++ */
++ int expected_errno;
++ int expected_end;
++ uint64_t expected_result;
++};
++
++static const struct strtoull_testcase test_input[] = {
++ {"0x0", 0, 0, 3, 0},
++ {"1", 0, 0, 1, 1},
++ {"0x1", 0, 0, 3, 1},
++ {" -0666", 0, 0, 7, -0666},
++ {" -0x666", 0, 0, 8, -0x666},
++ {"18446744073709551614", 0, 0, 20, UINT64_C(0xfffffffffffffffe)},
++ {"0xfffffffffffffffe", 0, 0, 18, UINT64_C(0xfffffffffffffffe)},
++ {"18446744073709551615", 0, 0, 20, UINT64_C(0xffffffffffffffff)},
++ {"0xffffffffffffffff", 0, 0, 18, UINT64_C(0xffffffffffffffff)},
++ {"18446744073709551616", 0, ERANGE, 20, UINT64_C(0xffffffffffffffff)},
++ {"0x10000000000000000", 0, ERANGE, 19, UINT64_C(0xffffffffffffffff)},
++ {"ff", 16, 0, 2, 255},
++ {"0xff", 16, 0, 4, 255},
++ {" ", 0, 0, 0, 0},
++ {"0x", 0, 0, 1, 0},
++ {"0x", 8, 0, 1, 0},
++ {"0x", 16, 0, 1, 0},
++ {"zyyy", 0, 0, 0, 0},
++ {"0xfffffffffffffffff", 0, ERANGE, 19, ULLONG_MAX},
++ {"0xfffffffffffffffffz", 0, ERANGE, 19, ULLONG_MAX}
++};
++
++unsigned int i;
++
++for (i = 0; i < sizeof(test_input) / sizeof(test_input[0]); i++) {
++ const struct strtoull_testcase *const p = &test_input[i];
++ char *endptr;
++ uint64_t result;
++
++ errno = 0;
++ result = strtoull(p->nptr, &endptr, p->base);
++ OKF(errno == p->expected_errno,
++ ("test %d (input \"%s\"): expected errno %d, got errno %d",
++ i, p->nptr, p->expected_errno, errno));
++ OKF(result == p->expected_result,
++ ("test %d (input \"%s\"): expected result %" PRIu64
++ ", got result %" PRIu64,
++ i, p->nptr, p->expected_result, result));
++ OKF(endptr - p->nptr == p->expected_end,
++ ("test %d (input \"%s\"): expected end %d, got end %d",
++ i, p->nptr, p->expected_end, (int) (endptr - p->nptr)));
++}
++
++#endif
+diff --git a/testing/fulltests/unit-tests/T102pdu_build_clib.c b/testing/fulltests/unit-tests/T102pdu_build_clib.c
+index 088a282..1fba69e 100644
+--- a/testing/fulltests/unit-tests/T102pdu_build_clib.c
++++ b/testing/fulltests/unit-tests/T102pdu_build_clib.c
+@@ -1,4 +1,7 @@
+ /* HEADER PDU building */
++
++SOCK_STARTUP;
++
+ netsnmp_pdu *pdu;
+ u_char *packet;
+ size_t packet_len, offset = 0;
+@@ -60,3 +63,5 @@ rc = snmp_build(&packet, &packet_len, &offset, ss, pdu);
+
+ OKF((rc == SNMPERR_SUCCESS),
+ ("Building an INFORM PDU/packet should have succeed: %d", rc));
++
++SOCK_CLEANUP;
+diff --git a/win32/encode_keychange/encode_keychange.dsp b/win32/encode_keychange/encode_keychange.dsp
+index 5e19366..5a252f5 100644
+--- a/win32/encode_keychange/encode_keychange.dsp
++++ b/win32/encode_keychange/encode_keychange.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/encode_keychange.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/encode_keychange.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "encode_keychange - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/encode_keychange.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/encode_keychange.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/libsnmp/Makefile.in b/win32/libsnmp/Makefile.in
+index 382b329..98d83c8 100644
+--- a/win32/libsnmp/Makefile.in
++++ b/win32/libsnmp/Makefile.in
+@@ -66,6 +66,7 @@ LIB32_OBJS= \
+ "$(INTDIR)\snmp_version.obj" \
+ "$(INTDIR)\snmpusm.obj" \
+ "$(INTDIR)\snmpv3.obj" \
++ "$(INTDIR)\strlcat.obj" \
+ "$(INTDIR)\strlcpy.obj" \
+ "$(INTDIR)\strtok_r.obj" \
+ "$(INTDIR)\strtoull.obj" \
+@@ -468,6 +469,12 @@ SOURCE=..\..\snmplib\snmpv3.c
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
++SOURCE=..\..\snmplib\strlcat.c
++
++"$(INTDIR)\strlcat.obj" : $(SOURCE) "$(INTDIR)"
++ $(CPP) $(CPP_PROJ) $(SOURCE)
++
++
+ SOURCE=..\..\snmplib\strlcpy.c
+
+ "$(INTDIR)\strlcpy.obj" : $(SOURCE) "$(INTDIR)"
+diff --git a/win32/libsnmp/libsnmp.dsp b/win32/libsnmp/libsnmp.dsp
+index 7a34939..2386331 100644
+--- a/win32/libsnmp/libsnmp.dsp
++++ b/win32/libsnmp/libsnmp.dsp
+@@ -313,6 +313,10 @@ SOURCE=..\..\snmplib\snmpv3.c
+ # End Source File
+ # Begin Source File
+
++SOURCE=..\..\snmplib\strlcat.c
++# End Source File
++# Begin Source File
++
+ SOURCE=..\..\snmplib\strlcpy.c
+ # End Source File
+ # Begin Source File
+diff --git a/win32/libsnmp_dll/Makefile.in b/win32/libsnmp_dll/Makefile.in
+index 31279f3..42235d2 100644
+--- a/win32/libsnmp_dll/Makefile.in
++++ b/win32/libsnmp_dll/Makefile.in
+@@ -67,6 +67,7 @@ LINK32_OBJS= \
+ "$(INTDIR)\snmp_version.obj" \
+ "$(INTDIR)\snmpusm.obj" \
+ "$(INTDIR)\snmpv3.obj" \
++ "$(INTDIR)\strlcat.obj" \
+ "$(INTDIR)\strlcpy.obj" \
+ "$(INTDIR)\strtok_r.obj" \
+ "$(INTDIR)\strtoull.obj" \
+@@ -484,6 +485,12 @@ SOURCE=..\..\snmplib\snmpv3.c
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
++SOURCE=..\..\snmplib\strlcat.c
++
++"$(INTDIR)\strlcat.obj" : $(SOURCE) "$(INTDIR)"
++ $(CPP) $(CPP_PROJ) $(SOURCE)
++
++
+ SOURCE=..\..\snmplib\strlcpy.c
+
+ "$(INTDIR)\strlcpy.obj" : $(SOURCE) "$(INTDIR)"
+diff --git a/win32/libsnmp_dll/libsnmp_dll.dsp b/win32/libsnmp_dll/libsnmp_dll.dsp
+index 098c3b9..12c0414 100644
+--- a/win32/libsnmp_dll/libsnmp_dll.dsp
++++ b/win32/libsnmp_dll/libsnmp_dll.dsp
+@@ -320,6 +320,10 @@ SOURCE=..\..\snmplib\snmpv3.c
+ # End Source File
+ # Begin Source File
+
++SOURCE=..\..\snmplib\strlcat.c
++# End Source File
++# Begin Source File
++
+ SOURCE=..\..\snmplib\strlcpy.c
+ # End Source File
+ # Begin Source File
+diff --git a/win32/mib_module_includes.h b/win32/mib_module_includes.h
+index 18a9281..014ade0 100644
+--- a/win32/mib_module_includes.h
++++ b/win32/mib_module_includes.h
+@@ -73,7 +73,6 @@
+ #include "mibgroup/agent/extend.h"
+ #include "mibgroup/ucd-snmp/errormib.h"
+ #include "mibgroup/ucd-snmp/file.h"
+-#include "mibgroup/ucd-snmp/dlmod.h"
+ #include "mibgroup/ucd-snmp/proxy.h"
+ #endif
+
+diff --git a/win32/mib_module_inits.h b/win32/mib_module_inits.h
+index 875fcb9..a4b39bc 100644
+--- a/win32/mib_module_inits.h
++++ b/win32/mib_module_inits.h
+@@ -34,7 +34,6 @@
+ if (should_init("extend")) init_extend();
+ if (should_init("errormib")) init_errormib();
+ if (should_init("file")) init_file();
+- if (should_init("dlmod")) init_dlmod();
+ if (should_init("proxy")) init_proxy();
+ #endif
+ if (should_init("snmpEngine")) init_snmpEngine();
+diff --git a/win32/net-snmp/net-snmp-config.h b/win32/net-snmp/net-snmp-config.h
+index da3c031..f63a83f 100644
+--- a/win32/net-snmp/net-snmp-config.h
++++ b/win32/net-snmp/net-snmp-config.h
+@@ -22,7 +22,9 @@
+ * When compiling with the MSVC workspace, this must be set manually.
+ * See the PACKAGE_VERSION variable in Unix /configure script
+ */
++#ifndef PACKAGE_VERSION
+ #define PACKAGE_VERSION "unknown"
++#endif
+
+ /* Define HAVE_WIN32_PLATFORM_SDK if you have:
+ * Microsoft Visual Studio MSVC 6.0 and the Platform SDK (PSDK)
+@@ -60,7 +62,7 @@
+
+ /* default list of mibs to load */
+
+-#define NETSNMP_DEFAULT_MIBS "IP-MIB;IF-MIB;TCP-MIB;UDP-MIB;HOST-RESOURCES-MIB;SNMPv2-MIB;RFC1213-MIB;NOTIFICATION-LOG-MIB;UCD-SNMP-MIB;UCD-DEMO-MIB;SNMP-TARGET-MIB;NET-SNMP-AGENT-MIB;DISMAN-EVENT-MIB;SNMP-VIEW-BASED-ACM-MIB;SNMP-COMMUNITY-MIB;UCD-DLMOD-MIB;SNMP-FRAMEWORK-MIB;SNMP-MPD-MIB;SNMP-USER-BASED-SM-MIB;SNMP-NOTIFICATION-MIB;SNMPv2-TM"
++#define NETSNMP_DEFAULT_MIBS "IP-MIB;IF-MIB;TCP-MIB;UDP-MIB;HOST-RESOURCES-MIB;SNMPv2-MIB;RFC1213-MIB;NOTIFICATION-LOG-MIB;UCD-SNMP-MIB;UCD-DEMO-MIB;SNMP-TARGET-MIB;NET-SNMP-AGENT-MIB;DISMAN-EVENT-MIB;SNMP-VIEW-BASED-ACM-MIB;SNMP-COMMUNITY-MIB;SNMP-FRAMEWORK-MIB;SNMP-MPD-MIB;SNMP-USER-BASED-SM-MIB;SNMP-NOTIFICATION-MIB;SNMPv2-TM"
+
+ /* default location to look for mibs to load using the above tokens
+ and/or those in the MIBS envrionment variable*/
+@@ -944,13 +946,17 @@
+ /* #undef PACKAGE_BUGREPORT */
+
+ /* Define to the full name of this package. */
++#ifndef PACKAGE_NAME
+ #define PACKAGE_NAME "Net-SNMP"
++#endif
+
+ /* Define to the full name and version of this package. */
+ /* #undef PACKAGE_STRING */
+
+ /* Define to the one symbol short name of this package. */
++#ifndef PACKAGE_TARNAME
+ #define PACKAGE_TARNAME "net-snmp"
++#endif
+
+ /* Define to the version of this package. */
+ /* #undef PACKAGE_VERSION */
+@@ -1358,6 +1364,12 @@
+ /* Define to 1 if you have the <openssl/aes.h> header file. */
+ #define HAVE_OPENSSL_AES_H 1
+
++/* Define to 1 if you have the `EVP_MD_CTX_create' function. */
++#define HAVE_EVP_MD_CTX_CREATE 1
++
++/* Define to 1 if you have the `EVP_MD_CTX_destroy' function. */
++#define HAVE_EVP_MD_CTX_DESTROY 1
++
+ /* Define to 1 if you have the `AES_cfb128_encrypt' function. */
+ #define HAVE_AES_CFB128_ENCRYPT 1
+
+@@ -1570,15 +1582,14 @@ typedef unsigned short mode_t;
+ #ifndef HAVE_STDINT_H
+ typedef unsigned char uint8_t;
+ typedef char int8_t;
+-typedef unsigned short uint16_t;
+-typedef short int16_t;
++typedef unsigned __int16 uint16_t;
++typedef __int16 int16_t;
+ typedef unsigned __int32 uint32_t;
+-typedef long int32_t;
++typedef __int32 int32_t;
+ typedef unsigned __int64 uint64_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int64 uintmax_t;
+ typedef __int64 intmax_t;
+-typedef unsigned short uint16_t;
+ #else /* HAVE_STDINT_H */
+ #include <stdint.h>
+ #endif /* HAVE_STDINT_H */
+@@ -1663,9 +1674,9 @@ enum {
+ #endif /* NETSNMP_USE_DLL */
+
+ /* MSVC OpenSSL linker settings. */
+-#if defined(WIN32) && !defined(mingw32)
++#if defined(_MSC_VER)
+ # if defined(NETSNMP_USE_OPENSSL)
+-# ifdef NETSNMP_USE_DLL
++# ifdef _DLL
+ # ifdef _DEBUG
+ # pragma comment(lib, "libeay32MDd.lib")
+ # else
+@@ -1679,6 +1690,7 @@ enum {
+ # endif
+ # endif
+ # pragma comment(lib, "gdi32.lib")
++# pragma comment(lib, "user32.lib")
+ # endif
+ #endif
+
+diff --git a/win32/net-snmp/net-snmp-config.h.in b/win32/net-snmp/net-snmp-config.h.in
+index 7101702..005e4f9 100644
+--- a/win32/net-snmp/net-snmp-config.h.in
++++ b/win32/net-snmp/net-snmp-config.h.in
+@@ -22,7 +22,9 @@
+ * When compiling with the MSVC workspace, this must be set manually.
+ * See the PACKAGE_VERSION variable in Unix /configure script
+ */
++#ifndef PACKAGE_VERSION
+ #define PACKAGE_VERSION "unknown"
++#endif
+
+ /* Define HAVE_WIN32_PLATFORM_SDK if you have:
+ * Microsoft Visual Studio MSVC 6.0 and the Platform SDK (PSDK)
+@@ -60,7 +62,7 @@
+
+ /* default list of mibs to load */
+
+-#define NETSNMP_DEFAULT_MIBS "IP-MIB;IF-MIB;TCP-MIB;UDP-MIB;HOST-RESOURCES-MIB;SNMPv2-MIB;RFC1213-MIB;NOTIFICATION-LOG-MIB;UCD-SNMP-MIB;UCD-DEMO-MIB;SNMP-TARGET-MIB;NET-SNMP-AGENT-MIB;DISMAN-EVENT-MIB;SNMP-VIEW-BASED-ACM-MIB;SNMP-COMMUNITY-MIB;UCD-DLMOD-MIB;SNMP-FRAMEWORK-MIB;SNMP-MPD-MIB;SNMP-USER-BASED-SM-MIB;SNMP-NOTIFICATION-MIB;SNMPv2-TM"
++#define NETSNMP_DEFAULT_MIBS "IP-MIB;IF-MIB;TCP-MIB;UDP-MIB;HOST-RESOURCES-MIB;SNMPv2-MIB;RFC1213-MIB;NOTIFICATION-LOG-MIB;UCD-SNMP-MIB;UCD-DEMO-MIB;SNMP-TARGET-MIB;NET-SNMP-AGENT-MIB;DISMAN-EVENT-MIB;SNMP-VIEW-BASED-ACM-MIB;SNMP-COMMUNITY-MIB;SNMP-FRAMEWORK-MIB;SNMP-MPD-MIB;SNMP-USER-BASED-SM-MIB;SNMP-NOTIFICATION-MIB;SNMPv2-TM"
+
+ /* default location to look for mibs to load using the above tokens
+ and/or those in the MIBS envrionment variable*/
+@@ -944,13 +946,17 @@
+ /* #undef PACKAGE_BUGREPORT */
+
+ /* Define to the full name of this package. */
++#ifndef PACKAGE_NAME
+ #define PACKAGE_NAME "Net-SNMP"
++#endif
+
+ /* Define to the full name and version of this package. */
+ /* #undef PACKAGE_STRING */
+
+ /* Define to the one symbol short name of this package. */
++#ifndef PACKAGE_TARNAME
+ #define PACKAGE_TARNAME "net-snmp"
++#endif
+
+ /* Define to the version of this package. */
+ /* #undef PACKAGE_VERSION */
+@@ -1358,6 +1364,12 @@
+ /* Define to 1 if you have the <openssl/aes.h> header file. */
+ #define HAVE_OPENSSL_AES_H 1
+
++/* Define to 1 if you have the `EVP_MD_CTX_create' function. */
++#define HAVE_EVP_MD_CTX_CREATE 1
++
++/* Define to 1 if you have the `EVP_MD_CTX_destroy' function. */
++#define HAVE_EVP_MD_CTX_DESTROY 1
++
+ /* Define to 1 if you have the `AES_cfb128_encrypt' function. */
+ #define HAVE_AES_CFB128_ENCRYPT 1
+
+@@ -1570,15 +1582,14 @@ typedef unsigned short mode_t;
+ #ifndef HAVE_STDINT_H
+ typedef unsigned char uint8_t;
+ typedef char int8_t;
+-typedef unsigned short uint16_t;
+-typedef short int16_t;
++typedef unsigned __int16 uint16_t;
++typedef __int16 int16_t;
+ typedef unsigned __int32 uint32_t;
+-typedef long int32_t;
++typedef __int32 int32_t;
+ typedef unsigned __int64 uint64_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int64 uintmax_t;
+ typedef __int64 intmax_t;
+-typedef unsigned short uint16_t;
+ #else /* HAVE_STDINT_H */
+ #include <stdint.h>
+ #endif /* HAVE_STDINT_H */
+@@ -1663,9 +1674,9 @@ enum {
+ #endif /* NETSNMP_USE_DLL */
+
+ /* MSVC OpenSSL linker settings. */
+-#if defined(WIN32) && !defined(mingw32)
++#if defined(_MSC_VER)
+ # if defined(NETSNMP_USE_OPENSSL)
+-# ifdef NETSNMP_USE_DLL
++# ifdef _DLL
+ # ifdef _DEBUG
+ # pragma comment(lib, "libeay32MDd.lib")
+ # else
+@@ -1679,6 +1690,7 @@ enum {
+ # endif
+ # endif
+ # pragma comment(lib, "gdi32.lib")
++# pragma comment(lib, "user32.lib")
+ # endif
+ #endif
+
+diff --git a/win32/netsnmpmibs/Makefile.in b/win32/netsnmpmibs/Makefile.in
+index ed44162..44d0203 100644
+--- a/win32/netsnmpmibs/Makefile.in
++++ b/win32/netsnmpmibs/Makefile.in
+@@ -85,13 +85,13 @@ LIB32_OBJS1= \
+ "$(INTDIR)\mteTriggerThresholdTable.obj" \
+ "$(INTDIR)\example.obj" \
+ "$(INTDIR)\ucdDemoPublic.obj" \
+- "$(INTDIR)\dlmod.obj" \
+ "$(INTDIR)\errormib.obj" \
+ "$(INTDIR)\extensible.obj" \
+ "$(INTDIR)\file.obj"
+ LIB32_OBJS2= \
+ "$(INTDIR)\loadave.obj" \
+ "$(INTDIR)\pass.obj" \
++ "$(INTDIR)\pass_common.obj" \
+ "$(INTDIR)\pass_persist.obj" \
+ "$(INTDIR)\proc.obj" \
+ "$(INTDIR)\proxy.obj" \
+@@ -314,12 +314,6 @@ SOURCE=..\..\agent\mibgroup\examples\ucdDemoPublic.c
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
+-SOURCE="..\..\agent\mibgroup\ucd-snmp\dlmod.c"
+-
+-"$(INTDIR)\dlmod.obj" : $(SOURCE) "$(INTDIR)"
+- $(CPP) $(CPP_PROJ) $(SOURCE)
+-
+-
+ SOURCE="..\..\agent\mibgroup\ucd-snmp\errormib.c"
+
+ "$(INTDIR)\errormib.obj" : $(SOURCE) "$(INTDIR)"
+@@ -350,6 +344,12 @@ SOURCE="..\..\agent\mibgroup\ucd-snmp\pass.c"
+ $(CPP) $(CPP_PROJ) $(SOURCE)
+
+
++SOURCE="..\..\agent\mibgroup\ucd-snmp\pass_common.c"
++
++"$(INTDIR)\pass_common.obj" : $(SOURCE) "$(INTDIR)"
++ $(CPP) $(CPP_PROJ) $(SOURCE)
++
++
+ SOURCE="..\..\agent\mibgroup\ucd-snmp\pass_persist.c"
+
+ "$(INTDIR)\pass_persist.obj" : $(SOURCE) "$(INTDIR)"
+diff --git a/win32/netsnmpmibs/netsnmpmibs.dsp b/win32/netsnmpmibs/netsnmpmibs.dsp
+index 5c88b97..9034eed 100644
+--- a/win32/netsnmpmibs/netsnmpmibs.dsp
++++ b/win32/netsnmpmibs/netsnmpmibs.dsp
+@@ -245,10 +245,6 @@ SOURCE=..\..\agent\mibgroup\examples\ucdDemoPublic.c
+ # PROP Default_Filter ""
+ # Begin Source File
+
+-SOURCE="..\..\agent\mibgroup\ucd-snmp\dlmod.c"
+-# End Source File
+-# Begin Source File
+-
+ SOURCE="..\..\agent\mibgroup\ucd-snmp\errormib.c"
+ # End Source File
+ # Begin Source File
+@@ -269,6 +265,10 @@ SOURCE="..\..\agent\mibgroup\ucd-snmp\pass.c"
+ # End Source File
+ # Begin Source File
+
++SOURCE="..\..\agent\mibgroup\ucd-snmp\pass_common.c"
++# End Source File
++# Begin Source File
++
+ SOURCE="..\..\agent\mibgroup\ucd-snmp\pass_persist.c"
+ # End Source File
+ # Begin Source File
+diff --git a/win32/snmpbulkget/snmpbulkget.dsp b/win32/snmpbulkget/snmpbulkget.dsp
+index fe5e5ae..39599db 100644
+--- a/win32/snmpbulkget/snmpbulkget.dsp
++++ b/win32/snmpbulkget/snmpbulkget.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpbulkget.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpbulkget.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmpbulkget - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpbulkget.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpbulkget.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmpbulkwalk/snmpbulkwalk.dsp b/win32/snmpbulkwalk/snmpbulkwalk.dsp
+index ea8bb0c..91e94d3 100644
+--- a/win32/snmpbulkwalk/snmpbulkwalk.dsp
++++ b/win32/snmpbulkwalk/snmpbulkwalk.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpbulkwalk.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpbulkwalk.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmpbulkwalk - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpbulkwalk.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpbulkwalk.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmpd/snmpd.dsp b/win32/snmpd/snmpd.dsp
+index 5534306..45e2cad 100644
+--- a/win32/snmpd/snmpd.dsp
++++ b/win32/snmpd/snmpd.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib netsnmpagent.lib netsnmpmibs.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpd.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpd.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmpd - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib netsnmpagent.lib netsnmpmibs.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpd.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpd.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmpdelta/snmpdelta.dsp b/win32/snmpdelta/snmpdelta.dsp
+index b17b822..7f5a5d3 100644
+--- a/win32/snmpdelta/snmpdelta.dsp
++++ b/win32/snmpdelta/snmpdelta.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpdelta.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpdelta.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmpdelta - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpdelta.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpdelta.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmpdf/snmpdf.dsp b/win32/snmpdf/snmpdf.dsp
+index 88c3f6d..e2e4b94 100644
+--- a/win32/snmpdf/snmpdf.dsp
++++ b/win32/snmpdf/snmpdf.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpdf.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpdf.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmpdf - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpdf.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpdf.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmpget/snmpget.dsp b/win32/snmpget/snmpget.dsp
+index 64980ed..0603232 100644
+--- a/win32/snmpget/snmpget.dsp
++++ b/win32/snmpget/snmpget.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpget.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpget.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmpget - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpget.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpget.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmpgetnext/snmpgetnext.dsp b/win32/snmpgetnext/snmpgetnext.dsp
+index 233199d..cb63c84 100644
+--- a/win32/snmpgetnext/snmpgetnext.dsp
++++ b/win32/snmpgetnext/snmpgetnext.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpgetnext.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpgetnext.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmpgetnext - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpgetnext.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpgetnext.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmpnetstat/snmpnetstat.dsp b/win32/snmpnetstat/snmpnetstat.dsp
+index 25ec031..35dd7e8 100644
+--- a/win32/snmpnetstat/snmpnetstat.dsp
++++ b/win32/snmpnetstat/snmpnetstat.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpnetstat.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpnetstat.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmpnetstat - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpnetstat.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpnetstat.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmpset/snmpset.dsp b/win32/snmpset/snmpset.dsp
+index fdeca30..ad0f509 100644
+--- a/win32/snmpset/snmpset.dsp
++++ b/win32/snmpset/snmpset.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpset.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpset.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmpset - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpset.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpset.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmpstatus/snmpstatus.dsp b/win32/snmpstatus/snmpstatus.dsp
+index 1b68373..e6a4100 100644
+--- a/win32/snmpstatus/snmpstatus.dsp
++++ b/win32/snmpstatus/snmpstatus.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpstatus.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpstatus.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmpstatus - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpstatus.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpstatus.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmptable/snmptable.dsp b/win32/snmptable/snmptable.dsp
+index 75f964f..1dfc138 100644
+--- a/win32/snmptable/snmptable.dsp
++++ b/win32/snmptable/snmptable.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmptable.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmptable.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmptable - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmptable.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmptable.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmptest/snmptest.dsp b/win32/snmptest/snmptest.dsp
+index dfb0cf1..89c08e9 100644
+--- a/win32/snmptest/snmptest.dsp
++++ b/win32/snmptest/snmptest.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmptest.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmptest.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmptest - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmptest.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmptest.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmptranslate/snmptranslate.dsp b/win32/snmptranslate/snmptranslate.dsp
+index a3ebde5..c3eca02 100644
+--- a/win32/snmptranslate/snmptranslate.dsp
++++ b/win32/snmptranslate/snmptranslate.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmptranslate.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmptranslate.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmptranslate - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmptranslate.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmptranslate.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmptrap/snmptrap.dsp b/win32/snmptrap/snmptrap.dsp
+index 8d27ee1..c34ffd8 100644
+--- a/win32/snmptrap/snmptrap.dsp
++++ b/win32/snmptrap/snmptrap.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmptrap.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmptrap.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmptrap - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmptrap.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmptrap.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmptrapd/snmptrapd.dsp b/win32/snmptrapd/snmptrapd.dsp
+index 503918a..9f49389 100644
+--- a/win32/snmptrapd/snmptrapd.dsp
++++ b/win32/snmptrapd/snmptrapd.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib netsnmpagent.lib netsnmpmibs.lib netsnmptrapd.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmptrapd.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmptrapd.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmptrapd - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib netsnmpagent.lib netsnmpmibs.lib netsnmptrapd.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmptrapd.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmptrapd.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmpusm/snmpusm.dsp b/win32/snmpusm/snmpusm.dsp
+index db43f2e..a1c0124 100644
+--- a/win32/snmpusm/snmpusm.dsp
++++ b/win32/snmpusm/snmpusm.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpusm.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpusm.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmpusm - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpusm.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpusm.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmpvacm/snmpvacm.dsp b/win32/snmpvacm/snmpvacm.dsp
+index 0856832..2fd53fd 100644
+--- a/win32/snmpvacm/snmpvacm.dsp
++++ b/win32/snmpvacm/snmpvacm.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpvacm.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpvacm.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmpvacm - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpvacm.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpvacm.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
+diff --git a/win32/snmpwalk/snmpwalk.dsp b/win32/snmpwalk/snmpwalk.dsp
+index 5d81957..67598f1 100644
+--- a/win32/snmpwalk/snmpwalk.dsp
++++ b/win32/snmpwalk/snmpwalk.dsp
+@@ -50,7 +50,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /machine:I386
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpwalk.exe" /libpath:"../lib/release"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /pdb:none /machine:I386 /out:"../bin/release/snmpwalk.exe" /libpath:"../lib/release"
+
+ !ELSEIF "$(CFG)" == "snmpwalk - Win32 Debug"
+
+@@ -74,7 +74,7 @@ BSC32=bscmake.exe
+ # ADD BSC32 /nologo
+ LINK32=link.exe
+ # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+-# ADD LINK32 netsnmp.lib advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpwalk.exe" /pdbtype:sept /libpath:"../lib/debug"
++# ADD LINK32 advapi32.lib ws2_32.lib kernel32.lib user32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"../bin/debug/snmpwalk.exe" /pdbtype:sept /libpath:"../lib/debug"
+
+ !ENDIF
+
diff --git a/meta-oe/recipes-extended/net-snmp/net-snmp_5.7.1.bb b/meta-oe/recipes-extended/net-snmp/net-snmp_5.7.1.bb
index 59d84077f1..55dd9a6666 100644
--- a/meta-oe/recipes-extended/net-snmp/net-snmp_5.7.1.bb
+++ b/meta-oe/recipes-extended/net-snmp/net-snmp_5.7.1.bb
@@ -1,8 +1,9 @@
require net-snmp.inc
-PR = "${INC_PR}.0"
+PR = "${INC_PR}.1"
LIC_FILES_CHKSUM = "file://README;beginline=3;endline=8;md5=7f7f00ba639ac8e8deb5a622ea24634e"
SRC_URI = "${SOURCEFORGE_MIRROR}/net-snmp/net-snmp-${PV}.tar.gz \
+ file://sync-with-5.7-branch.patch \
file://init \
file://snmpd.conf \
file://snmptrapd.conf"