return rpm_info;
}
+struct rpm_file {
+ char *pkg_name;
+ char *file_name;
+};
+
+GSList* create_tpk_list(rpmts ts)
+{
+ GSList *tpk_list = NULL;
+
+ rpmdbMatchIterator mi = rpmtsInitIterator(ts, RPMTAG_NAME, NULL, 0);
+ if (mi == NULL) {
+ _E("Failed to init rpmdb match iterator");
+ goto end;
+ }
+
+ for (Header h = rpmdbNextIterator(mi); h; h = rpmdbNextIterator(mi)) {
+ const char *pkg_name = headerGetString(h, RPMTAG_NAME);
+ if (pkg_name == NULL)
+ continue;
+ rpmfi fi = rpmfiNew(NULL, h, RPMTAG_FILENAMES, 0);
+
+ while (rpmfiNext(fi) != -1) {
+ const char *file_name = rpmfiFN(fi);
+ size_t file_name_len = strlen(file_name);
+
+ if (file_name_len < 4 ||
+ strcmp(&file_name[file_name_len-4], ".tpk") != 0)
+ continue;
+
+ struct rpm_file *rpm = (struct rpm_file*)malloc(sizeof(rpm));
+ if (rpm == NULL) {
+ _E("malloc() error (%m). Report (*.so_info) may be incomplete.");
+ continue;
+ }
+
+ const char *version = headerGetString(h, RPMTAG_VERSION);
+ const char *release = headerGetString(h, RPMTAG_RELEASE);
+ const char *arch = headerGetString(h, RPMTAG_ARCH);
+
+ if (version == NULL || release == NULL || arch == NULL)
+ continue;
+
+ if (asprintf(&rpm->pkg_name, "%s;%s;%s;%s",
+ pkg_name, version, release, arch) == -1) {
+ _E("asprintf() error: %m");
+ free(rpm);
+ continue;
+ }
+ rpm->file_name = strdup(file_name);
+ if (rpm->file_name == NULL) {
+ _E("strdup() error: %m");
+ free(rpm->pkg_name);
+ free(rpm);
+ continue;
+ }
+ tpk_list = g_slist_append(tpk_list, rpm);
+ }
+ }
+ rpmdbFreeIterator(mi);
+
+ if (tpk_list == NULL)
+ _E("No RPM packages containing *.tpk files found");
+end:
+ return tpk_list;
+}
+
+char* get_app_name_from_path(const char *file_path)
+{
+ static const char *prefix[] = {"/usr/apps/",
+ "/opt/usr/globalapps/",
+ NULL};
+
+ for (size_t i = 0; i < ARRAY_SIZE(prefix); i++) {
+ if (strncmp(file_path, prefix[i], strlen(prefix[i])) != 0)
+ continue;
+
+ const char *app_name = &file_path[strlen(prefix[i])];
+
+ char *end_of_name = strchr(app_name, '/');
+ if (end_of_name != NULL)
+ return strndup(app_name, end_of_name - app_name);
+ }
+ return NULL;
+}
+
+char* get_rpm_info_for_tpk(GSList *tpk_list, const char *file_path)
+{
+ char *app_name = get_app_name_from_path(file_path);
+ if (app_name == NULL)
+ return NULL;
+
+ char *res = NULL;
+
+ for (GSList *iterator = tpk_list; iterator; iterator = iterator->next) {
+ struct rpm_file *rpm_pkg = (struct rpm_file *)iterator->data;
+
+ if (strstr(rpm_pkg->file_name, app_name) != NULL) {
+ res = strdup(rpm_pkg->pkg_name);
+ break;
+ }
+ }
+
+ free(app_name);
+ return res;
+}
+
void get_and_save_so_info(char *map_path, char *out_path)
{
GSList *file_list = get_filepaths(map_path);
+ GSList *tpk_list = NULL;
char *rpm_info;
FILE *f = fopen(out_path, "w");
int fret;
rpm_info = get_rpm_info(ts, file_path);
+ if (rpm_info == NULL) {
+ if (tpk_list == NULL)
+ tpk_list = create_tpk_list(ts);
+ if (tpk_list != NULL)
+ rpm_info = get_rpm_info_for_tpk(tpk_list, file_path);
+ }
if (rpm_info == NULL)
fret = fprintf(f, "%s %s\n", file_path, build_id);
else {
for (GSList *iterator = file_list; iterator; iterator = iterator->next)
free(iterator->data);
+ for (GSList *iterator = tpk_list; iterator; iterator = iterator->next) {
+ struct rpm_file *rpm = (struct rpm_file*)iterator->data;
+ free(rpm->file_name);
+ free(rpm->pkg_name);
+ free(rpm);
+ }
+
g_slist_free(file_list);
+ g_slist_free(tpk_list);
free_rpm(ts);
}