diff options
author | Otavio Salvador <otavio@ossystems.com.br> | 2012-02-08 15:27:28 +0000 |
---|---|---|
committer | Koen Kooi <koen@dominion.thruhere.net> | 2012-02-20 22:22:02 +0100 |
commit | 675da0c58afe0926f9e614acb49b9e6c5d30d413 (patch) | |
tree | e4ebd31422a44c335e664796783ecea35f61a393 /meta-oe/recipes-extended | |
parent | 6f371fa946d094c1b03d98692383aac803ae2fe0 (diff) | |
download | meta-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.patch | 19998 | ||||
-rw-r--r-- | meta-oe/recipes-extended/net-snmp/net-snmp_5.7.1.bb | 3 |
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(¤t, NULL); +- NETSNMP_TIMERSUB(¤t, 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, ¤t_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 *) ð_strings->data[i * ETH_GSTRING_LEN], +- ETH_GSTRING_LEN); ++ strlcpy(s, (const char *) ð_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 *) ð_strings->data[i * ETH_GSTRING_LEN], +- ETH_GSTRING_LEN); ++ strlcpy(s, (const char *) ð_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, ¬_argc, ¬_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 > ChangeLog.add</command> +- <command>perl dist/changelogfix < ChangeLog.add > ChangeLog.reallyadd</command> ++ <command>git log --no-merges {LASTVERSIONTAGNAME}..HEAD > 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, <sys/time.h></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" |