improvements to HOST-RESOURCES-MIB::hrSWInstalled on debian systems - add Install Date information instead of bogus 0-1-1 - include Arch in package names, like rpm output does - use debian native separators `_` for package components, not rpm ones: `-` to test: snmpbulkwalk localhost HOST-RESOURCES-MIB::hrSWInstalled Signed-Off-By: Elan Ruusamäe --- net-snmp-5.7.3/agent/mibgroup/host/data_access/swinst_apt.c~ 2016-04-23 17:40:44.000000000 +0300 +++ net-snmp-5.7.3/agent/mibgroup/host/data_access/swinst_apt.c 2016-04-23 17:40:49.740392789 +0300 @@ -22,6 +22,7 @@ #ifdef HAVE_FCNTL_H #include #endif +#include #include #include @@ -29,8 +30,11 @@ #include #include +netsnmp_feature_require(date_n_time) + char pkg_directory[SNMP_MAXBUF]; static char apt_fmt[SNMP_MAXBUF]; +static char file[SNMP_MAXBUF]; /* --------------------------------------------------------------------- */ @@ -38,8 +42,8 @@ netsnmp_swinst_arch_init(void) { strlcpy(pkg_directory, "/var/lib/dpkg/info", sizeof(pkg_directory)); - snprintf(apt_fmt, SNMP_MAXBUF, "%%%d[^#]#%%%d[^#]#%%%d[^#]#%%%d[^#]#%%%d[^#]#%%%ds", - SNMP_MAXBUF-1, SNMP_MAXBUF-1, SNMP_MAXBUF-1, + snprintf(apt_fmt, SNMP_MAXBUF, "%%%d[^#]#%%%d[^#]#%%%d[^#]#%%%d[^#]#%%%d[^#]#%%%d[^#]#%%%ds", + SNMP_MAXBUF-1, SNMP_MAXBUF-1, SNMP_MAXBUF-1, SNMP_MAXBUF-1, SNMP_MAXBUF-1, SNMP_MAXBUF-1, SNMP_MAXBUF-1); } @@ -55,15 +59,19 @@ int netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags) { - FILE *p = popen("dpkg-query --show --showformat '${Package}#${Version}#${Section}#${Priority}#${Essential}#${Status}\n'", "r"); + FILE *p = popen("dpkg-query --show --showformat '${Package}#${Version}#${Section}#${Priority}#${Essential}#${Architecture}#${Status}\n'", "r"); char package[SNMP_MAXBUF]; char version[SNMP_MAXBUF]; char section[SNMP_MAXBUF]; char priority[SNMP_MAXBUF]; char essential[SNMP_MAXBUF]; + char arch[SNMP_MAXBUF]; char status[SNMP_MAXBUF]; char buf[BUFSIZ]; + struct stat stat_buf; netsnmp_swinst_entry *entry; + u_char *date_buf; + size_t date_len; int i = 0; if (p == NULL) { @@ -78,20 +86,39 @@ continue; /* error already logged by function */ CONTAINER_INSERT(container, entry); - sscanf(buf, apt_fmt, package, version, section, priority, essential, status); + sscanf(buf, apt_fmt, package, version, section, priority, essential, arch, status); if (strstr(status, "not-installed")) continue; entry->swName_len = snprintf( entry->swName, sizeof(entry->swName), - "%s-%s", package, version); + "%s_%s_%s", package, version, arch); if (entry->swName_len >= sizeof(entry->swName)) entry->swName_len = sizeof(entry->swName)-1; entry->swType = (strcmp(essential, "yes") == 0) ? 2 /* operatingSystem */ : 4; /* application */ - entry->swDate_len = 8; - memcpy(entry->swDate, "\0\0\1\1\0\0\0\0", 8); + /* get the last mod date */ + snprintf(file, sizeof(file), "%s/%s.list", pkg_directory, package); + if(stat(file, &stat_buf) != -1) { + date_buf = date_n_time(&stat_buf.st_mtime, &date_len); + entry->swDate_len = date_len; + memcpy(entry->swDate, date_buf, entry->swDate_len); + } else { + /* somewhy some files include :arch in .list name */ + snprintf(file, sizeof(file), "%s/%s:%s.list", pkg_directory, package, arch); + if(stat(file, &stat_buf) != -1) { + date_buf = date_n_time(&stat_buf.st_mtime, &date_len); + entry->swDate_len = date_len; + memcpy(entry->swDate, date_buf, entry->swDate_len); + } + } + /* FIXME, or fallback to whatever nonsesnse was here before, or leave it uninitialied? + else { + entry->swDate_len = 8; + memcpy(entry->swDate, "\0\0\1\1\0\0\0\0", 8); + } + */ } pclose(p); DEBUGMSGTL(("swinst:load:arch"," loaded %d entries\n",