X-Git-Url: https://git.librecmc.org/?p=oweals%2Fopkg-lede.git;a=blobdiff_plain;f=libopkg%2Fpkg.c;h=b01db61d98148a161d861795dc6c359699bfc470;hp=bb3da1e4eaeb36f647f66717de57b53f27ff1b92;hb=b25d96944364269c61835d7a80a9165f0ee95667;hpb=332947f2518b71342ebe3719899e83405a79c15d diff --git a/libopkg/pkg.c b/libopkg/pkg.c index bb3da1e..b01db61 100644 --- a/libopkg/pkg.c +++ b/libopkg/pkg.c @@ -208,21 +208,6 @@ void pkg_deinit(pkg_t *pkg) free(pkg->depends_str); pkg->depends_str = NULL; - for (i = 0; i < pkg->provides_count-1; i++) - free (pkg->provides_str[i]); - free(pkg->provides_str); - pkg->provides_str = NULL; - - for (i = 0; i < pkg->conflicts_count; i++) - free (pkg->conflicts_str[i]); - free(pkg->conflicts_str); - pkg->conflicts_str = NULL; - - for (i = 0; i < pkg->replaces_count; i++) - free (pkg->replaces_str[i]); - free(pkg->replaces_str); - pkg->replaces_str = NULL; - for (i = 0; i < pkg->recommends_count; i++) free (pkg->recommends_str[i]); free(pkg->recommends_str); @@ -315,26 +300,48 @@ void pkg_deinit(pkg_t *pkg) pkg->tags = NULL; } -int pkg_init_from_file(pkg_t *pkg, const char *filename) +int +pkg_init_from_file(pkg_t *pkg, const char *filename) { - int err; - FILE *control_file; + int fd, err = 0; + FILE *control_file; + char *control_path; - err = pkg_init(pkg); - if (err) { return err; } + pkg_init(pkg); - pkg->local_filename = xstrdup(filename); - - control_file = tmpfile(); - err = pkg_extract_control_file_to_stream(pkg, control_file); - if (err) { return err; } + pkg->local_filename = xstrdup(filename); - rewind(control_file); - pkg_parse_from_stream(pkg, control_file, PFM_ALL); + sprintf_alloc(&control_path, "%s.control.XXXXXX", filename); + fd = mkstemp(control_path); + if (fd == -1) { + perror_msg("%s: mkstemp(%s)", __FUNCTION__, control_path); + err = -1; + goto err0; + } - fclose(control_file); + control_file = fdopen(fd, "rw+"); + if (control_file == NULL) { + perror_msg("%s: fdopen", __FUNCTION__, control_path); + close(fd); + err = -1; + goto err1; + } - return 0; + err = pkg_extract_control_file_to_stream(pkg, control_file); + if (err) + goto err2; + + rewind(control_file); + pkg_parse_from_stream(pkg, control_file, PFM_ALL); + +err2: + fclose(control_file); +err1: + unlink(control_path); +err0: + free(control_path); + + return err; } /* Merge any new information in newpkg into oldpkg */ @@ -351,6 +358,9 @@ int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status) return 0; } + if (!oldpkg->auto_installed) + oldpkg->auto_installed = newpkg->auto_installed; + if (!oldpkg->src) oldpkg->src = newpkg->src; if (!oldpkg->dest) @@ -403,9 +413,7 @@ int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status) newpkg->suggests_count = 0; } - if (!oldpkg->provides_str) { - oldpkg->provides_str = newpkg->provides_str; - newpkg->provides_str = NULL; + if (oldpkg->provides_count <= 1) { oldpkg->provides_count = newpkg->provides_count; newpkg->provides_count = 0; @@ -415,9 +423,7 @@ int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status) } } - if (!oldpkg->conflicts_str) { - oldpkg->conflicts_str = newpkg->conflicts_str; - newpkg->conflicts_str = NULL; + if (!oldpkg->conflicts_count) { oldpkg->conflicts_count = newpkg->conflicts_count; newpkg->conflicts_count = 0; @@ -425,9 +431,7 @@ int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status) newpkg->conflicts = NULL; } - if (!oldpkg->replaces_str) { - oldpkg->replaces_str = newpkg->replaces_str; - newpkg->replaces_str = NULL; + if (!oldpkg->replaces_count) { oldpkg->replaces_count = newpkg->replaces_count; newpkg->replaces_count = 0; @@ -509,6 +513,7 @@ void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){ if (fp == NULL) { opkg_message(conf, OPKG_ERROR, "fopen(%s): %s\n", file_name, strerror(errno)); + free(file_name); return; } @@ -523,6 +528,27 @@ void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){ return; } +const char* +constraint_to_str(enum version_constraint c) +{ + switch (c) { + case NONE: + return ""; + case EARLIER: + return "< "; + case EARLIER_EQUAL: + return "<= "; + case EQUAL: + return "= "; + case LATER_EQUAL: + return ">= "; + case LATER: + return "> "; + } + + return ""; +} + void pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field) { int i; @@ -557,16 +583,24 @@ void pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field) fprintf(fp, "Conffiles:\n"); for (iter = nv_pair_list_first(&pkg->conffiles); iter; iter = nv_pair_list_next(&pkg->conffiles, iter)) { if (((conffile_t *)iter->data)->name && ((conffile_t *)iter->data)->value) { - fprintf(fp, "%s %s\n", + fprintf(fp, " %s %s\n", ((conffile_t *)iter->data)->name, ((conffile_t *)iter->data)->value); } } } else if (strcasecmp(field, "Conflicts") == 0) { + struct depend *cdep; if (pkg->conflicts_count) { fprintf(fp, "Conflicts:"); for(i = 0; i < pkg->conflicts_count; i++) { - fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->conflicts_str[i]); + cdep = pkg->conflicts[i].possibilities[0]; + fprintf(fp, "%s %s", i == 0 ? "" : ",", + cdep->pkg->name); + if (cdep->version) { + fprintf(fp, "(%s%s)", + constraint_to_str(cdep->constraint), + cdep->version); + } } fprintf(fp, "\n"); } @@ -635,8 +669,9 @@ void pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field) } else if (strcasecmp(field, "Provides") == 0) { if (pkg->provides_count) { fprintf(fp, "Provides:"); - for(i = 0; i < pkg->provides_count-1; i++) { - fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->provides_str[i]); + for(i = 1; i < pkg->provides_count; i++) { + fprintf(fp, "%s %s", i == 1 ? "" : ",", + pkg->provides[i]->name); } fprintf(fp, "\n"); } @@ -650,7 +685,8 @@ void pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field) if (pkg->replaces_count) { fprintf(fp, "Replaces:"); for (i = 0; i < pkg->replaces_count; i++) { - fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->replaces_str[i]); + fprintf(fp, "%s %s", i == 0 ? "" : ",", + pkg->replaces[i]->name); } fprintf(fp, "\n"); } @@ -968,14 +1004,17 @@ pkg_version_str_alloc(pkg_t *pkg) return version; } -str_list_t *pkg_get_installed_files(pkg_t *pkg) +/* + * XXX: this should be broken into two functions + */ +str_list_t *pkg_get_installed_files(opkg_conf_t *conf, pkg_t *pkg) { - int err; + int err, fd; char *list_file_name = NULL; FILE *list_file = NULL; char *line; char *installed_file_name; - int rootdirlen; + int rootdirlen = 0; pkg->installed_files_ref_cnt++; @@ -996,34 +1035,51 @@ str_list_t *pkg_get_installed_files(pkg_t *pkg) file. In other words, change deb_extract so that it can simply return the file list as a char *[] rather than insisting on writing in to a FILE * as it does now. */ - list_file = tmpfile(); + sprintf_alloc(&list_file_name, "%s/%s.list.XXXXXX", + conf->tmp_dir, pkg->name); + fd = mkstemp(list_file_name); + if (fd == -1) { + opkg_message(conf, OPKG_ERROR, "%s: mkstemp(%s): %s", + __FUNCTION__, list_file_name, strerror(errno)); + free(list_file_name); + return pkg->installed_files; + } + list_file = fdopen(fd, "rw+"); + if (list_file == NULL) { + opkg_message(conf, OPKG_ERROR, "%s: fdopen: %s", + __FUNCTION__, strerror(errno)); + close(fd); + unlink(list_file_name); + free(list_file_name); + return pkg->installed_files; + } err = pkg_extract_data_file_names_to_stream(pkg, list_file); if (err) { + opkg_message(conf, OPKG_ERROR, "%s: Error extracting file list " + "from %s: %s\n", __FUNCTION__, + pkg->local_filename, strerror(err)); fclose(list_file); - fprintf(stderr, "%s: Error extracting file list from %s: %s\n", - __FUNCTION__, pkg->local_filename, strerror(err)); + unlink(list_file_name); + free(list_file_name); return pkg->installed_files; } rewind(list_file); } else { sprintf_alloc(&list_file_name, "%s/%s.list", pkg->dest->info_dir, pkg->name); - if (! file_exists(list_file_name)) { - free(list_file_name); - return pkg->installed_files; - } - list_file = fopen(list_file_name, "r"); if (list_file == NULL) { - fprintf(stderr, "WARNING: Cannot open %s: %s\n", - list_file_name, strerror(errno)); + opkg_message(conf, OPKG_ERROR, "%s: fopen(%s): %s\n", + __FUNCTION__, list_file_name, strerror(errno)); free(list_file_name); return pkg->installed_files; } free(list_file_name); } - rootdirlen = strlen( pkg->dest->root_dir ); + if (conf->offline_root) + rootdirlen = strlen(conf->offline_root); + while (1) { char *file_name; @@ -1034,22 +1090,24 @@ str_list_t *pkg_get_installed_files(pkg_t *pkg) str_chomp(line); file_name = line; - /* Take pains to avoid uglies like "/./" in the middle of file_name. */ - if( strncmp( pkg->dest->root_dir, - file_name, - rootdirlen ) ) { + if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) { if (*file_name == '.') { file_name++; } if (*file_name == '/') { file_name++; } - - /* Freed in pkg_free_installed_files */ - sprintf_alloc(&installed_file_name, "%s%s", pkg->dest->root_dir, file_name); + sprintf_alloc(&installed_file_name, "%s%s", + pkg->dest->root_dir, file_name); } else { - // already contains root_dir as header -> ABSOLUTE - sprintf_alloc(&installed_file_name, "%s", file_name); + if (conf->offline_root && + strncmp(conf->offline_root, file_name, rootdirlen)) { + sprintf_alloc(&installed_file_name, "%s%s", + conf->offline_root, file_name); + } else { + // already contains root_dir as header -> ABSOLUTE + sprintf_alloc(&installed_file_name, "%s", file_name); + } } str_list_append(pkg->installed_files, installed_file_name); free(installed_file_name); @@ -1058,6 +1116,11 @@ str_list_t *pkg_get_installed_files(pkg_t *pkg) fclose(list_file); + if (pkg->state_status == SS_NOT_INSTALLED || pkg->dest == NULL) { + unlink(list_file_name); + free(list_file_name); + } + return pkg->installed_files; } @@ -1190,8 +1253,10 @@ int pkg_run_script(opkg_conf_t *conf, pkg_t *pkg, sprintf_alloc(&cmd, "%s %s", path, args); free(path); - - err = xsystem(cmd); + { + const char *argv[] = {"sh", "-c", cmd, NULL}; + err = xsystem(argv); + } free(cmd); if (err) { @@ -1393,7 +1458,7 @@ int pkg_info_preinstall_check(opkg_conf_t *conf) pkg_hash_fetch_all_installed(pkg_hash, installed_pkgs); for (i = 0; i < installed_pkgs->len; i++) { pkg_t *pkg = installed_pkgs->pkgs[i]; - str_list_t *installed_files = pkg_get_installed_files(pkg); /* this causes installed_files to be cached */ + str_list_t *installed_files = pkg_get_installed_files(conf, pkg); /* this causes installed_files to be cached */ str_list_elt_t *iter, *niter; if (installed_files == NULL) { opkg_message(conf, OPKG_ERROR, "No installed files for pkg %s\n", pkg->name);