#include <stdarg.h>
#include <unistd.h>
#include <glib.h>
+#include <rpm/rpmdb.h>
+#include <rpm/rpmts.h>
+#include <rpm/rpmlib.h>
+#include <rpm/header.h>
#include "shared/log.h"
#include "shared/util.h"
#define BID_SNAME ".note.gnu.build-id"
-#define CMD_RPM "rpm -qf %s --qf '%%{NAME};%%{VERSION};%%{RELEASE};%%{ARCH}'"
-#define CMD_RPM_LEN sizeof(CMD_RPM)
-
-#define RPM_INFO_MAXLEN PATH_MAX
-
static unsigned char *map_file(const char *filename, int64_t *size)
{
return file_list;
}
-int get_rpm_info(char *filename, char *rpm_info)
+rpmts init_rpm()
{
- if (!filename) {
- _E("Invalid filename");
- return -1;
+ rpmts ts = rpmtsCreate();
+ if (rpmReadConfigFiles(NULL, NULL) < 0) {
+ _E("rpmReadConfigFiles failed\n");
+ rpmtsFree(ts);
+ return NULL;
+ }
+ return ts;
+}
+
+void free_rpm(rpmts ts)
+{
+ if (ts != NULL) {
+ rpmtsFree(ts);
+ rpmFreeRpmrc();
}
+}
- char *args[] = {"rpm", "-qf", filename, "--qf", "%{NAME};%{VERSION};%{RELEASE};%{ARCH}", NULL};
+char* get_rpm_info_as_string(Header h)
+{
+ const char *name, *version, *release, *arch;
- int readed;
- if ((readed = run_command_write_fd_timeout("rpm", args, NULL, 0, rpm_info, RPM_INFO_MAXLEN, 60)) < 0) {
- _E("Failed to get information about rpm installed packages");
- return -1;
- } else {
- rpm_info[readed] = 0;
+ name = headerGetString(h, RPMTAG_NAME);
+ version = headerGetString(h, RPMTAG_VERSION);
+ release = headerGetString(h, RPMTAG_RELEASE);
+ arch = headerGetString(h, RPMTAG_ARCH);
+
+ int info_len = strlen(name) + strlen(version) +
+ strlen(release) + strlen(arch) + 3;
+
+ char *res = (char *)malloc(info_len + 1);
+ if (res == NULL) {
+ _E("Failed to allocate memory: %m");
+ return NULL;
}
+ snprintf(res, info_len, "%s;%s;%s;%s", name, version, release, arch);
- return 0;
+ return res;
+}
+
+char* get_rpm_info(rpmts ts, const char* filename)
+{
+ char *rpm_info = NULL;
+
+ if (ts == NULL)
+ return NULL;
+
+ rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMDBI_INSTFILENAMES, filename, 0);
+ if (mi == NULL) {
+ _E("Not found RPM package for %s\n", filename);
+ return NULL;
+ }
+
+ Header h = rpmdbNextIterator(mi);
+
+ if (h != NULL)
+ rpm_info = get_rpm_info_as_string(h);
+ else {
+ _E("rpmdbNextIterator error\n");
+ rpm_info = NULL;
+ }
+ rpmdbFreeIterator(mi);
+ return rpm_info;
}
void get_and_save_so_info(char *map_path, char *out_path)
{
GSList *file_list = get_filepaths(map_path);
- char rpm_info[RPM_INFO_MAXLEN+1];
+ char *rpm_info;
FILE *f = fopen(out_path, "w");
+ rpmts ts = init_rpm();
+
if (f == NULL) {
_E("Failed to open file for writing %s: %m", out_path);
} else {
int fret;
- if (get_rpm_info(file_path, rpm_info) != 0)
+ rpm_info = get_rpm_info(ts, file_path);
+ if (rpm_info == NULL)
fret = fprintf(f, "%s %s\n", file_path, build_id);
- else
+ else {
fret = fprintf(f, "%s %s %s\n", file_path, build_id, rpm_info);
+ free(rpm_info);
+ }
free(build_id);
free(iterator->data);
g_slist_free(file_list);
+
+ free_rpm(ts);
}