BUG #a2537: Support *BSD pkg-ng
diff --git a/agent/mibgroup/host/data_access/swinst_pkginfo.c b/agent/mibgroup/host/data_access/swinst_pkginfo.c
index 7301bfc..e7a4082 100644
--- a/agent/mibgroup/host/data_access/swinst_pkginfo.c
+++ b/agent/mibgroup/host/data_access/swinst_pkginfo.c
@@ -32,6 +32,11 @@
#include <pkginfo.h>
#endif
+#ifdef HAVE_PKG_H
+#define restrict
+#include <pkg.h>
+#endif
+
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/library/container.h>
@@ -97,53 +102,115 @@
size_t date_len;
int i = 1;
netsnmp_swinst_entry *entry;
+#ifdef HAVE_LIBPKG
+ struct pkgdb *db = NULL;
+ struct pkgdb_it *it = NULL;
+ struct pkg *pkg = NULL;
+ char pkgname[ SNMP_MAXPATH ];
+ char pkgdate[ BUFSIZ ];
+ int pkgng = 0;
- if ( !pkg_directory[0] ) {
- return 1; /* Can't report installed packages
- if there isn't a list of them! */
+ if (pkg_init(NULL, NULL)) {
+ snmp_log( LOG_ERR, "SWInst: error initializing pkgng db\n" );
+ return 1;
}
- d = opendir( pkg_directory );
- if (!d)
+
+ if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
+ snmp_log( LOG_ERR, "SWInst: error opening pkgng db\n" );
return 1;
- while ((dp = readdir(d)) != NULL) {
- if ( '.' == dp->d_name[0] )
- continue;
- snprintf( buf, BUFSIZ, "%s/%s", pkg_directory, dp->d_name );
- if (stat( buf, &stat_buf ) < 0)
- continue;
- entry = netsnmp_swinst_entry_create( i++ );
- if (NULL == entry)
- continue; /* error already logged by function */
- CONTAINER_INSERT(container, entry);
+ }
+
+ if (pkg_status(NULL) == PKG_STATUS_ACTIVE) {
+ pkgng = 1;
+ } else {
+ snmp_log( LOG_INFO, "SWInst: not a pkgng system\n" );
+ }
+
+ // if we are using FreeBSD's pkgng
+ if (pkgng) {
+ if ((it = pkgdb_query(db, NULL, MATCH_ALL)) == NULL) {
+ snmp_log( LOG_ERR, "SWInst: error querying pkgng db\n" );
+ return 1;
+ }
+
+ while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) {
+ pkg_snprintf(pkgname, sizeof(pkgname), "%n-%v", pkg, pkg);
+ pkg_snprintf(pkgdate, sizeof(pkgdate), "%t", pkg);
+
+ entry = netsnmp_swinst_entry_create( i++ );
+
+ if (NULL == entry)
+ continue; /* error already logged by function */
+
+ CONTAINER_INSERT(container, entry);
+
+ entry->swName_len = snprintf( entry->swName, sizeof(entry->swName),
+ "%s", pkgname );
+ if (entry->swName_len >= sizeof(entry->swName))
+ entry->swName_len = sizeof(entry->swName)-1;
+
+ install_time = atoi(pkgdate);
+ cp = date_n_time( &install_time, &date_len );
+ memcpy( entry->swDate, cp, date_len );
+ entry->swDate_len = date_len;
+ }
+
+ pkgdb_it_free(it);
+ pkgdb_close(db);
+ pkg_shutdown();
+ } else {
+#endif /* HAVE_LIBPKG */
+ if ( !pkg_directory[0] ) {
+ return 1; /* Can't report installed packages
+ if there isn't a list of them! */
+ }
+
+ d = opendir( pkg_directory );
+ if (!d)
+ return 1;
+
+ while ((dp = readdir(d)) != NULL) {
+ if ( '.' == dp->d_name[0] )
+ continue;
+ snprintf( buf, BUFSIZ, "%s/%s", pkg_directory, dp->d_name );
+ if (stat( buf, &stat_buf ) < 0)
+ continue;
+ entry = netsnmp_swinst_entry_create( i++ );
+ if (NULL == entry)
+ continue; /* error already logged by function */
+ CONTAINER_INSERT(container, entry);
#ifdef HAVE_PKGINFO
- v = pkgparam( dp->d_name, "VERSION" );
- c = pkgparam( dp->d_name, "CATEGORY" );
+ v = pkgparam( dp->d_name, "VERSION" );
+ c = pkgparam( dp->d_name, "CATEGORY" );
- entry->swName_len = snprintf( entry->swName, sizeof(entry->swName),
- "%s-%s", dp->d_name, v );
- if (entry->swName_len >= sizeof(entry->swName))
- entry->swName_len = sizeof(entry->swName)-1;
- entry->swType = (NULL != strstr( c, "system"))
- ? 2 /* operatingSystem */
- : 4; /* application */
+ entry->swName_len = snprintf( entry->swName, sizeof(entry->swName),
+ "%s-%s", dp->d_name, v );
+ if (entry->swName_len >= sizeof(entry->swName))
+ entry->swName_len = sizeof(entry->swName)-1;
+ entry->swType = (NULL != strstr( c, "system"))
+ ? 2 /* operatingSystem */
+ : 4; /* application */
- /* Do we need to free 'v' & 'c' ??? */
+ /* Do we need to free 'v' & 'c' ??? */
#else
- entry->swName_len = snprintf( entry->swName, sizeof(entry->swName),
- "%s", dp->d_name );
- if (entry->swName_len >= sizeof(entry->swName))
- entry->swName_len = sizeof(entry->swName)-1;
+ entry->swName_len = snprintf( entry->swName, sizeof(entry->swName),
+ "%s", dp->d_name );
+ if (entry->swName_len >= sizeof(entry->swName))
+ entry->swName_len = sizeof(entry->swName)-1;
- /* no information about O/S vs application packages ??? */
+ /* no information about O/S vs application packages ??? */
#endif
- install_time = stat_buf.st_mtime;
- cp = date_n_time( &install_time, &date_len );
- memcpy( entry->swDate, cp, date_len );
- entry->swDate_len = date_len;
+ install_time = stat_buf.st_mtime;
+ cp = date_n_time( &install_time, &date_len );
+ memcpy( entry->swDate, cp, date_len );
+ entry->swDate_len = date_len;
+ }
+ closedir( d );
+#ifdef HAVE_LIBPKG
}
- closedir( d );
+#endif
DEBUGMSGTL(("swinst:load:arch"," loaded %d entries\n",
(int)CONTAINER_SIZE(container)));
diff --git a/configure b/configure
index dab97ed..34eb25c 100755
--- a/configure
+++ b/configure
@@ -17031,6 +17031,197 @@
done
+for ac_header in pkg.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "pkg.h" "ac_cv_header_pkg_h" "$ac_includes_default"
+if test "x$ac_cv_header_pkg_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_PKG_H 1
+_ACEOF
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pkg_init" >&5
+$as_echo_n "checking for library containing pkg_init... " >&6; }
+if ${netsnmp_cv_func_pkg_init_LIBS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ netsnmp_func_search_save_LIBS="$LIBS"
+ netsnmp_target_val="$LIBS"
+ netsnmp_temp_LIBS=" ${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 pkg_init ();
+int
+main ()
+{
+return pkg_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ netsnmp_result="none required"
+else
+ for netsnmp_cur_lib in pkg ; 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 pkg_init ();
+int
+main ()
+{
+return pkg_init ();
+ ;
+ 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_pkg_init_LIBS="${netsnmp_result}"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $netsnmp_cv_func_pkg_init_LIBS" >&5
+$as_echo "$netsnmp_cv_func_pkg_init_LIBS" >&6; }
+ if test "${netsnmp_cv_func_pkg_init_LIBS}" != "no" ; then
+ if test "${netsnmp_cv_func_pkg_init_LIBS}" != "none required" ; then
+ LIBS="${netsnmp_result} ${netsnmp_target_val}"
+ fi
+
+$as_echo "#define HAVE_LIBPKG 1" >>confdefs.h
+
+
+ fi
+
+fi
+
+done
+
+
+if test $ac_cv_header_pkg_h = no
+then
+ unset ac_cv_header_pkg_h
+ netsnmp_save_CPPFLAGS="$CPPFLAGS"
+ netsnmp_save_LD_FLAGS="$LDFLAGS"
+ CPPFLAGS="$CPPFLAGS -I/usr/local/include"
+ LDFLAGS="$LDFLAGS -L/usr/local/lib"
+ for ac_header in pkg.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "pkg.h" "ac_cv_header_pkg_h" "$ac_includes_default"
+if test "x$ac_cv_header_pkg_h" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_PKG_H 1
+_ACEOF
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pkg_init" >&5
+$as_echo_n "checking for library containing pkg_init... " >&6; }
+if ${netsnmp_cv_func_pkg_init_LIBS+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ netsnmp_func_search_save_LIBS="$LIBS"
+ netsnmp_target_val="$LIBS"
+ netsnmp_temp_LIBS=" ${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 pkg_init ();
+int
+main ()
+{
+return pkg_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ netsnmp_result="none required"
+else
+ for netsnmp_cur_lib in pkg ; 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 pkg_init ();
+int
+main ()
+{
+return pkg_init ();
+ ;
+ 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_pkg_init_LIBS="${netsnmp_result}"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $netsnmp_cv_func_pkg_init_LIBS" >&5
+$as_echo "$netsnmp_cv_func_pkg_init_LIBS" >&6; }
+ if test "${netsnmp_cv_func_pkg_init_LIBS}" != "no" ; then
+ if test "${netsnmp_cv_func_pkg_init_LIBS}" != "none required" ; then
+ LIBS="${netsnmp_result} ${netsnmp_target_val}"
+ fi
+
+$as_echo "#define HAVE_LIBPKG 1" >>confdefs.h
+
+
+ fi
+
+fi
+
+done
+
+ if test $ac_cv_header_pkg_h = no
+ then
+ CPPFLAGS="$netsnmp_save_CPPFLAGS"
+ LDFLAGS="$netsnmp_save_LDFLAGS"
+ fi
+fi
+
case $target_os in
aix*)
# for CPU/memory statistics (AIX)
diff --git a/configure.d/config_os_headers b/configure.d/config_os_headers
index d8127ca..def3bce 100644
--- a/configure.d/config_os_headers
+++ b/configure.d/config_os_headers
@@ -473,6 +473,27 @@
NETSNMP_SEARCH_LIBS(pkginfo, adm,
AC_DEFINE(HAVE_PKGINFO, 1, [define if you have pkginfo]),,,LMIBLIBS))
+AC_CHECK_HEADERS(pkg.h,
+ NETSNMP_SEARCH_LIBS(pkg_init, pkg,
+ AC_DEFINE(HAVE_LIBPKG, 1, [define if you have BSD pkg-ng])))
+
+if test $ac_cv_header_pkg_h = no
+then
+ unset ac_cv_header_pkg_h
+ netsnmp_save_CPPFLAGS="$CPPFLAGS"
+ netsnmp_save_LD_FLAGS="$LDFLAGS"
+ CPPFLAGS="$CPPFLAGS -I/usr/local/include"
+ LDFLAGS="$LDFLAGS -L/usr/local/lib"
+ AC_CHECK_HEADERS(pkg.h,
+ NETSNMP_SEARCH_LIBS(pkg_init, pkg,
+ AC_DEFINE(HAVE_LIBPKG, 1, [define if you have BSD pkg-ng])))
+ if test $ac_cv_header_pkg_h = no
+ then
+ CPPFLAGS="$netsnmp_save_CPPFLAGS"
+ LDFLAGS="$netsnmp_save_LDFLAGS"
+ fi
+fi
+
case $target_os in
aix*)
# for CPU/memory statistics (AIX)
diff --git a/include/net-snmp/net-snmp-config.h.in b/include/net-snmp/net-snmp-config.h.in
index 84af89a..1db0237 100644
--- a/include/net-snmp/net-snmp-config.h.in
+++ b/include/net-snmp/net-snmp-config.h.in
@@ -362,6 +362,9 @@
/* Define to 1 if you have the `pkcs11' library (-lpkcs11). */
#undef HAVE_LIBPKCS11
+/* define if you have BSD pkg-ng */
+#undef HAVE_LIBPKG
+
/* Define to 1 if you have the `pthread' library (-lpthread). */
#undef HAVE_LIBPTHREAD
@@ -629,6 +632,9 @@
/* Define to 1 if you have the <pkglocs.h> header file. */
#undef HAVE_PKGLOCS_H
+/* Define to 1 if you have the <pkg.h> header file. */
+#undef HAVE_PKG_H
+
/* Define to 1 if you have the `poll' function. */
#undef HAVE_POLL