1 /*
2 * swinst_rpm.c:
3 * hrSWInstalledTable data access:
4 */
5 #include <net-snmp/net-snmp-config.h>
6 #include <net-snmp/net-snmp-features.h>
7
8 #include <stdio.h>
9 #ifdef HAVE_STDLIB_H
10 #include <stdlib.h>
11 #endif
12 #ifdef HAVE_UNISTD_H
13 #include <unistd.h>
14 #endif
15 #ifdef HAVE_SYS_TYPES_H
16 #include <sys/types.h>
17 #endif
18 #ifdef HAVE_STRING_H
19 #include <string.h>
20 #else
21 #include <strings.h>
22 #endif
23 #ifdef HAVE_FCNTL_H
24 #include <fcntl.h>
25 #endif
26
27 #ifdef HAVE_RPM_RPMLIB_H
28 #include <rpm/rpmlib.h>
29 #endif
30 #ifdef HAVE_RPM_RPMLIB_H
31 #include <rpm/header.h>
32 #endif
33 #ifdef HAVE_RPMGETPATH /* HAVE_RPM_RPMMACRO_H */
34 #include <rpm/rpmmacro.h>
35 #endif
36 #ifdef HAVE_RPM_RPMTS_H
37 #include <rpm/rpmts.h>
38 #include <rpm/rpmdb.h>
39 #endif
40
41 #include <net-snmp/net-snmp-includes.h>
42 #include <net-snmp/agent/net-snmp-agent-includes.h>
43 #include <net-snmp/library/container.h>
44 #include <net-snmp/library/snmp_debug.h>
45 #include <net-snmp/data_access/swinst.h>
46 #include "swinst_private.h"
47
48 netsnmp_feature_require(date_n_time);
49
50 /*
51 * Location of RPM package directory.
52 * Used for:
53 * - reporting hrSWInstalledLast* objects
54 * - detecting when the cached contents are out of date.
55 */
56 char pkg_directory[SNMP_MAXPATH];
57
58 /* ---------------------------------------------------------------------
59 */
60 void
netsnmp_swinst_arch_init(void)61 netsnmp_swinst_arch_init(void)
62 {
63 char *rpmdbpath = NULL;
64 const char *dbpath;
65 struct stat stat_buf;
66
67 #ifdef HAVE_RPMGETPATH
68 rpmReadConfigFiles( NULL, NULL );
69 rpmdbpath = rpmGetPath( "%{_dbpath}", NULL );
70 dbpath = rpmdbpath;
71 #else
72 dbpath = "/var/lib/rpm"; /* Most likely */
73 #endif
74
75 snprintf( pkg_directory, SNMP_MAXPATH, "%s/Packages", dbpath );
76 SNMP_FREE(rpmdbpath);
77 dbpath = NULL;
78 if (-1 == stat( pkg_directory, &stat_buf )) {
79 snmp_log(LOG_ERR, "Can't find directory of RPM packages");
80 pkg_directory[0] = '\0';
81 }
82 }
83
84 void
netsnmp_swinst_arch_shutdown(void)85 netsnmp_swinst_arch_shutdown(void)
86 {
87 /* Nothing to do */
88 return;
89 }
90
91 /* ---------------------------------------------------------------------
92 */
93 int
netsnmp_swinst_arch_load(netsnmp_container * container,u_int flags)94 netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags)
95 {
96 rpmts ts;
97
98 rpmdbMatchIterator mi;
99 Header h;
100 #if HAVE_HEADERGET
101 const char *g;
102 rpmtd td_name, td_version, td_release, td_group, td_time;
103 #else
104 char *n, *v, *r, *g;
105 int32_t *t;
106 #endif
107 time_t install_time;
108 size_t date_len;
109 int i = 1;
110 netsnmp_swinst_entry *entry;
111
112 #if HAVE_HEADERGET
113 td_name = rpmtdNew();
114 td_version = rpmtdNew();
115 td_release = rpmtdNew();
116 td_group = rpmtdNew();
117 td_time = rpmtdNew();
118 #endif
119 ts = rpmtsCreate();
120 rpmtsSetVSFlags( ts, (_RPMVSF_NOSIGNATURES|_RPMVSF_NODIGESTS));
121
122 mi = rpmtsInitIterator( ts, RPMDBI_PACKAGES, NULL, 0);
123 if (mi == NULL)
124 NETSNMP_LOGONCE((LOG_ERR, "rpmdbOpen() failed\n"));
125
126 while (NULL != (h = rpmdbNextIterator( mi )))
127 {
128 const u_char *dt;
129
130 entry = netsnmp_swinst_entry_create( i++ );
131 if (NULL == entry)
132 continue; /* error already logged by function */
133 CONTAINER_INSERT(container, entry);
134
135 h = headerLink( h );
136 #if HAVE_HEADERGET
137 headerGet(h, RPMTAG_NAME, td_name, HEADERGET_EXT);
138 headerGet(h, RPMTAG_VERSION, td_version, HEADERGET_EXT);
139 headerGet(h, RPMTAG_RELEASE, td_release, HEADERGET_EXT);
140 headerGet(h, RPMTAG_GROUP, td_group, HEADERGET_EXT);
141 headerGet(h, RPMTAG_INSTALLTIME, td_time, HEADERGET_EXT);
142 entry->swName_len = snprintf( entry->swName, sizeof(entry->swName),
143 "%s-%s-%s", rpmtdGetString(td_name),
144 rpmtdGetString(td_version),
145 rpmtdGetString(td_release));
146 install_time = rpmtdGetNumber(td_time);
147 g = rpmtdGetString(td_group);
148 #else
149 headerGetEntry( h, RPMTAG_NAME, NULL, (void**)&n, NULL);
150 headerGetEntry( h, RPMTAG_VERSION, NULL, (void**)&v, NULL);
151 headerGetEntry( h, RPMTAG_RELEASE, NULL, (void**)&r, NULL);
152 headerGetEntry( h, RPMTAG_GROUP, NULL, (void**)&g, NULL);
153 headerGetEntry( h, RPMTAG_INSTALLTIME, NULL, (void**)&t, NULL);
154 entry->swName_len = snprintf( entry->swName, sizeof(entry->swName),
155 "%s-%s-%s", n, v, r);
156 install_time = *t;
157 #endif
158 entry->swType = (g && NULL != strstr( g, "System Environment"))
159 ? 2 /* operatingSystem */
160 : 4; /* application */
161 if (entry->swName_len > sizeof(entry->swName))
162 entry->swName_len = sizeof(entry->swName);
163
164 dt = date_n_time( &install_time, &date_len );
165 if (date_len != 8 && date_len != 11) {
166 snmp_log(LOG_ERR, "Bogus length from date_n_time for %s", entry->swName);
167 entry->swDate_len = 0;
168 }
169 else {
170 entry->swDate_len = date_len;
171 memcpy(entry->swDate, dt, entry->swDate_len);
172 }
173
174 #if HAVE_HEADERGET
175 rpmtdFreeData(td_name);
176 rpmtdFreeData(td_version);
177 rpmtdFreeData(td_release);
178 rpmtdFreeData(td_group);
179 rpmtdFreeData(td_time);
180 #endif
181 headerFree( h );
182 }
183 rpmdbFreeIterator( mi );
184 rpmtsFree( ts );
185 #if HAVE_HEADERGET
186 rpmtdFree(td_name);
187 rpmtdFree(td_version);
188 rpmtdFree(td_release);
189 rpmtdFree(td_group);
190 rpmtdFree(td_time);
191 #endif
192
193 DEBUGMSGTL(("swinst:load:arch", "loaded %d entries\n",
194 (int)CONTAINER_SIZE(container)));
195
196 return 0;
197 }
198