X-Git-Url: https://git.librecmc.org/?p=oweals%2Fopkg-lede.git;a=blobdiff_plain;f=libopkg%2Fpkg.c;h=5d705c7bb147c0d436ff611a61c4deb57821b434;hp=3b1f21bd366575a816ca9961569af374eda73788;hb=7aeac5e4c5468c7b10e90eb70fcd520ebf8f510f;hpb=6e59ec90af245ddf2d2534981fa0eb7804a8686d diff --git a/libopkg/pkg.c b/libopkg/pkg.c index 3b1f21b..5d705c7 100644 --- a/libopkg/pkg.c +++ b/libopkg/pkg.c @@ -315,34 +315,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; - char **raw, **raw_start; - 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); - raw = raw_start = read_raw_pkgs_from_stream(control_file); - pkg_parse_raw(pkg, &raw, NULL, NULL); + 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; + } - raw = raw_start; - while (*raw) { - free(*raw++); - } - free(raw_start); + err = pkg_extract_control_file_to_stream(pkg, control_file); + if (err) + goto err2; - return 0; + 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 */ @@ -417,8 +431,10 @@ int pkg_merge(pkg_t *oldpkg, pkg_t *newpkg, int set_status) oldpkg->provides_count = newpkg->provides_count; newpkg->provides_count = 0; - oldpkg->provides = newpkg->provides; - newpkg->provides = NULL; + if (!oldpkg->provides) { + oldpkg->provides = newpkg->provides; + newpkg->provides = NULL; + } } if (!oldpkg->conflicts_str) { @@ -506,47 +522,33 @@ int abstract_pkg_init(abstract_pkg_t *ab_pkg) } void set_flags_from_control(opkg_conf_t *conf, pkg_t *pkg){ - char * temp_str; - char **raw =NULL; - char **raw_start=NULL; + char *file_name; + FILE *fp; - size_t str_size = strlen(pkg->dest->info_dir)+strlen(pkg->name)+12; - temp_str = (char *) alloca (str_size); - memset(temp_str, 0 , str_size); - - if (temp_str == NULL ){ - opkg_message(conf, OPKG_INFO, "Out of memory in %s\n", __FUNCTION__); - return; - } - sprintf( temp_str,"%s/%s.control",pkg->dest->info_dir,pkg->name); - - raw = raw_start = read_raw_pkgs_from_file(temp_str); - if (raw == NULL ){ - opkg_message(conf, OPKG_ERROR, "Unable to open the control file in %s\n", __FUNCTION__); - return; - } + sprintf_alloc(&file_name,"%s/%s.control", pkg->dest->info_dir, pkg->name); - while(*raw){ - if (!pkg_valorize_other_field(pkg, &raw ) == 0) { - opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name); - } - } - raw = raw_start; - while (*raw) { - if (raw!=NULL) - free(*raw++); + fp = fopen(file_name, "r"); + if (fp == NULL) { + opkg_message(conf, OPKG_ERROR, "fopen(%s): %s\n", + file_name, strerror(errno)); + free(file_name); + return; } - free(raw_start); + free(file_name); - return ; + if (pkg_parse_from_stream(pkg, fp, PFM_ESSENTIAL)) { + opkg_message(conf, OPKG_DEBUG, "unable to read control file for %s. May be empty\n", pkg->name); + } + fclose(fp); + + return; } void pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field) { int i; - int flag_provide_false = 0; if (strlen(field) < PKG_MINIMUM_FIELD_NAME_LEN) { goto UNKNOWN_FMT_FIELD; @@ -578,7 +580,7 @@ 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); } @@ -655,23 +657,11 @@ void pkg_formatted_field(FILE *fp, pkg_t *pkg, const char *field) fprintf(fp, "Priority: %s\n", pkg->priority); } else if (strcasecmp(field, "Provides") == 0) { if (pkg->provides_count) { - /* Here we check if the opkg_internal_use_only is used, and we discard it.*/ - for ( i=0; i < pkg->provides_count; i++ ){ - if (strstr(pkg->provides_str[i],"opkg_internal_use_only")!=NULL) { - memset (pkg->provides_str[i],'\x0',strlen(pkg->provides_str[i])); /* Pigi clear my trick flag, just in case */ - flag_provide_false = 1; - } - } - if ( !flag_provide_false || /* Pigi there is not my trick flag */ - ((flag_provide_false) && (pkg->provides_count > 1))){ /* Pigi There is, but we also have others Provides */ - fprintf(fp, "Provides:"); - for(i = 0; i < pkg->provides_count; i++) { - if (strlen(pkg->provides_str[i])>0) { - fprintf(fp, "%s %s", i == 1 ? "" : ",", pkg->provides_str[i]); - } - } - fprintf(fp, "\n"); + fprintf(fp, "Provides:"); + for(i = 0; i < pkg->provides_count-1; i++) { + fprintf(fp, "%s %s", i == 0 ? "" : ",", pkg->provides_str[i]); } + fprintf(fp, "\n"); } } else { goto UNKNOWN_FMT_FIELD; @@ -978,42 +968,40 @@ int abstract_pkg_name_compare(const void *p1, const void *p2) } -char *pkg_version_str_alloc(pkg_t *pkg) +char * +pkg_version_str_alloc(pkg_t *pkg) { - char *complete_version; - char *epoch_str; - char *revision_str; - - if (pkg->epoch) { - sprintf_alloc(&epoch_str, "%d:", pkg->epoch); - } else { - epoch_str = xstrdup(""); - } - - if (pkg->revision && strlen(pkg->revision)) { - sprintf_alloc(&revision_str, "-%s", pkg->revision); - } else { - revision_str = xstrdup(""); - } - - - sprintf_alloc(&complete_version, "%s%s%s", - epoch_str, pkg->version, revision_str); - - free(epoch_str); - free(revision_str); + char *version; + + if (pkg->epoch) { + if (pkg->revision) + sprintf_alloc(&version, "%d:%s-%s", + pkg->epoch, pkg->version, pkg->revision); + else + sprintf_alloc(&version, "%d:%s", + pkg->epoch, pkg->version); + } else { + if (pkg->revision) + sprintf_alloc(&version, "%s-%s", + pkg->version, pkg->revision); + else + version = xstrdup(pkg->version); + } - return complete_version; + 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++; @@ -1034,34 +1022,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; @@ -1072,22 +1077,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); @@ -1096,6 +1103,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; } @@ -1228,8 +1240,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) { @@ -1431,7 +1445,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);