/* Open an outer archive with the given filename. */ static struct archive *open_outer(const char *filename) { struct archive *outer; int r; outer = archive_read_new(); if (!outer) { opkg_msg(ERROR, "Failed to create outer archive object.\n"); return NULL; } /* Outer package is in 'ar' format, uncompressed. */ r = archive_read_support_format_ar(outer); if (r != ARCHIVE_OK) { opkg_msg(ERROR, "Ar format not supported: %s\n", archive_error_string(outer)); goto err_cleanup; } r = archive_read_open_filename(outer, filename, EXTRACT_BUFFER_LEN); if (r != ARCHIVE_OK) { opkg_msg(ERROR, "Failed to open package '%s': %s\n", filename, archive_error_string(outer)); goto err_cleanup; } return outer; err_cleanup: archive_read_free(outer); return NULL; }
int pkg_src_download_signature(pkg_src_t * src) { int err = 0; char *url; char *sigfile; const char *sigext; if (strcmp(opkg_config->signature_type, "gpg-asc") == 0) sigext = "asc"; else sigext = "sig"; sprintf_alloc(&sigfile, "%s/%s.%s", opkg_config->lists_dir, src->name, sigext); /* get the url for the sig file */ if (src->extra_data) /* debian style? */ sprintf_alloc(&url, "%s/%s/Packages.%s", src->value, src->extra_data, sigext); else sprintf_alloc(&url, "%s/Packages.%s", src->value, sigext); err = opkg_download(url, sigfile, NULL, NULL); if (err) { opkg_msg(ERROR, "Failed to download signature for %s.\n", src->name); goto cleanup; } opkg_msg(DEBUG, "Downloaded signature for %s.\n", src->name); cleanup: free(sigfile); free(url); return err; }
int conffile_has_been_modified(conffile_t * conffile) { char *md5sum; char *filename = conffile->name; char *root_filename; int ret = 1; if (conffile->value == NULL) { opkg_msg(NOTICE, "Conffile %s has no md5sum.\n", conffile->name); return 1; } root_filename = root_filename_alloc(filename); md5sum = file_md5sum_alloc(root_filename); if (md5sum && (ret = strcmp(md5sum, conffile->value))) { opkg_msg(INFO, "Conffile %s:\n\told md5=%s\n\tnew md5=%s\n", conffile->name, md5sum, conffile->value); } free(root_filename); if (md5sum) free(md5sum); return ret; }
int pkg_extract_control_files_to_dir_with_prefix(pkg_t * pkg, const char *dir, const char *prefix) { int r = -1; char *dir_with_prefix; struct opkg_ar *ar; sprintf_alloc(&dir_with_prefix, "%s/%s", dir, prefix); ar = ar_open_pkg_control_archive(pkg->local_filename); if (!ar) { opkg_msg(ERROR, "Failed to extract control.tar.gz from package '%s'.\n", pkg->local_filename); goto cleanup; } r = ar_extract_all(ar, dir_with_prefix); if (r < 0) opkg_msg(ERROR, "Failed to extract all control files from package '%s'.\n", pkg->local_filename); cleanup: free(dir_with_prefix); if (ar) ar_close(ar); return r; }
enum version_constraint str_to_constraint(const char **str) { if (strncmp(*str, "<<", 2) == 0) { *str += 2; return EARLIER; } else if (strncmp(*str, "<=", 2) == 0) { *str += 2; return EARLIER_EQUAL; } else if (strncmp(*str, ">=", 2) == 0) { *str += 2; return LATER_EQUAL; } else if (strncmp(*str, ">>", 2) == 0) { *str += 2; return LATER; } else if (strncmp(*str, "=", 1) == 0) { *str += 1; return EQUAL; } /* should these be here to support deprecated designations; dpkg does */ else if (strncmp(*str, "<", 1) == 0) { *str += 1; opkg_msg(NOTICE, "Deprecated version constraint '<' was used with the same " "meaning as '<='. Use '<<' for EARLIER constraint.\n"); return EARLIER_EQUAL; } else if (strncmp(*str, ">", 1) == 0) { *str += 1; opkg_msg(NOTICE, "Deprecated version constraint '>' was used with the same " "meaning as '>='. Use '>>' for LATER constraint.\n"); return LATER_EQUAL; } else { return NONE; } }
/* Extract an entry to disk, returns 0 on success or <0 on error. */ static int extract_entry(struct archive *a, struct archive_entry *entry, struct archive *disk) { int r; int retries = 0; retry: r = archive_read_extract2(a, entry, disk); switch (r) { case ARCHIVE_OK: break; case ARCHIVE_WARN: opkg_msg(NOTICE, "Warning when extracting archive entry: %s\n", archive_error_string(a)); break; case ARCHIVE_RETRY: opkg_msg(ERROR, "Failed to extract archive entry '%s': %s\n", archive_entry_pathname(entry), archive_error_string(a)); if (retries++ < 3) { opkg_msg(NOTICE, "Retrying...\n"); goto retry; } else return -1; default: opkg_msg(ERROR, "Failed to extract archive entry '%s': %s\n", archive_entry_pathname(entry), archive_error_string(a)); return -1; } return 0; }
/* * Find and remove packages that were autoinstalled and are orphaned * by the removal of pkg. */ static int remove_autoinstalled(pkg_t * pkg) { int i, j; int err = 0; int n_deps; pkg_t *p; struct compound_depend *cdep; abstract_pkg_t **dependents; int r; int count = pkg->pre_depends_count + pkg->depends_count + pkg->recommends_count + pkg->suggests_count; for (i = 0; i < count; i++) { cdep = &pkg->depends[i]; /* Only remove dependency types which would normally be autoinstalled, * namely the types PREDEPEND, DEPEND and RECOMMEND. We don't consider * SUGGEST which are not normally autoinstalled and we don't consider * CONFLICTS or GREEDY_DEPEND either. */ int uninteresting = cdep->type != PREDEPEND && cdep->type != DEPEND && cdep->type != RECOMMEND; if (uninteresting) continue; for (j = 0; j < cdep->possibility_count; j++) { p = pkg_hash_fetch_installed_by_name(cdep->possibilities[j]->pkg-> name); /* If the package is not installed, this could have * been a circular dependency and the package has * already been removed. */ if (!p) return -1; if (!p->auto_installed) continue; n_deps = pkg_has_installed_dependents(p, &dependents); if (n_deps == 0) { opkg_msg(NOTICE, "%s was autoinstalled and is " "now orphaned, removing.\n", p->name); r = opkg_remove_pkg(p); if (r != 0) err = -1; } else opkg_msg(INFO, "%s was autoinstalled and is " "still required by %d " "installed packages.\n", p->name, n_deps); free(dependents); } } return err; }
static int opkg_download_cache(const char *src, const char *dest_file_name, curl_progress_func cb, void *data) { char *cache_name = xstrdup(src); char *cache_location, *p; int err = 0; if (!conf->cache || str_starts_with(src, "file:")) { err = opkg_download(src, dest_file_name, cb, data, 0); goto out1; } if(!file_is_dir(conf->cache)){ opkg_msg(ERROR, "%s is not a directory.\n", conf->cache); err = 1; goto out1; } for (p = cache_name; *p; p++) if (*p == '/') *p = ','; /* looks nicer than | or # */ sprintf_alloc(&cache_location, "%s/%s", conf->cache, cache_name); if (file_exists(cache_location)) opkg_msg(NOTICE, "Copying %s.\n", cache_location); else { /* cache file with funky name not found, try simple name */ free(cache_name); char *filename = strrchr(dest_file_name,'/'); if (filename) cache_name = xstrdup(filename+1); // strip leading '/' else cache_name = xstrdup(dest_file_name); free(cache_location); sprintf_alloc(&cache_location, "%s/%s", conf->cache, cache_name); if (file_exists(cache_location)) opkg_msg(NOTICE, "Copying %s.\n", cache_location); else { err = opkg_download(src, cache_location, cb, data, 0); if (err) { (void) unlink(cache_location); goto out2; } } } err = file_copy(cache_location, dest_file_name); out2: free(cache_location); out1: free(cache_name); return err; }
static X509_STORE * setup_verify(char *CAfile, char *CApath) { X509_STORE *store = NULL; X509_LOOKUP *lookup = NULL; if(!(store = X509_STORE_new())){ // Something bad is happening... goto end; } // adds the X509 file lookup method lookup = X509_STORE_add_lookup(store,X509_LOOKUP_file()); if (lookup == NULL){ goto end; } // Autenticating against one CA file if (CAfile) { if(!X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM)) { // Invalid CA => Bye bye opkg_msg(ERROR, "Error loading file %s.\n", CAfile); goto end; } } else { X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT); } // Now look into CApath directory if supplied lookup = X509_STORE_add_lookup(store,X509_LOOKUP_hash_dir()); if (lookup == NULL){ goto end; } if (CApath) { if(!X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM)) { opkg_msg(ERROR, "Error loading directory %s.\n", CApath); goto end; } } else { X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT); } // All right ! ERR_clear_error(); return store; end: X509_STORE_free(store); return NULL; }
/* Print destination paths at DEBUG level. */ static void print_paths(struct archive_entry *entry) { const char *path = archive_entry_pathname(entry); const char *hardlink = archive_entry_hardlink(entry); const char *symlink = archive_entry_symlink(entry); if (hardlink) opkg_msg(DEBUG, "Extracting '%s', hardlink to '%s'.\n", path, hardlink); else if (symlink) opkg_msg(DEBUG, "Extracting '%s', symlink to '%s'.\n", path, symlink); else opkg_msg(DEBUG, "Extracting '%s'.\n", path); }
/* Open an inner archive at the current position within the given outer archive. */ static struct archive *open_inner(struct archive *outer) { struct archive *inner; struct inner_data *data; int r; inner = archive_read_new(); if (!inner) { opkg_msg(ERROR, "Failed to create inner archive object.\n"); return NULL; } data = (struct inner_data *)xmalloc(sizeof(struct inner_data)); data->buffer = xmalloc(EXTRACT_BUFFER_LEN); data->outer = outer; /* Inner package is in 'tar' format, gzip compressed. */ r = archive_read_support_filter_gzip(inner); if (r == ARCHIVE_WARN) { /* libarchive returns ARCHIVE_WARN if the filter is provided by * an external program. */ opkg_msg(INFO, "Gzip support provided by external program.\n"); } else if (r != ARCHIVE_OK) { opkg_msg(ERROR, "Gzip format not supported.\n"); goto err_cleanup; } r = archive_read_support_format_tar(inner); if (r != ARCHIVE_OK) { opkg_msg(ERROR, "Tar format not supported: %s\n", archive_error_string(outer)); goto err_cleanup; } r = archive_read_open(inner, data, NULL, inner_read, inner_close); if (r != ARCHIVE_OK) { opkg_msg(ERROR, "Failed to open inner archive: %s\n", archive_error_string(inner)); goto err_cleanup; } return inner; err_cleanup: archive_read_free(inner); free(data->buffer); free(data); return NULL; }
static int copy_to_stream(struct archive *a, FILE * stream) { void *buffer; size_t sz_out, sz_in; int eof; size_t len = EXTRACT_BUFFER_LEN; buffer = xmalloc(len); while (1) { sz_in = read_data(a, buffer, len, &eof); if (eof) { free(buffer); return 0; } if (sz_in == 0) goto err_cleanup; /* Now write data to the output stream. */ sz_out = fwrite(buffer, 1, sz_in, stream); if (sz_out < sz_in) { opkg_msg(ERROR, "Failed to write data to stream: %s\n", strerror(errno)); goto err_cleanup; } } err_cleanup: free(buffer); return -1; }
pkg_vec_t *pkg_hash_fetch_conflicts(pkg_t * pkg) { pkg_vec_t *installed_conflicts; abstract_pkg_t *ab_pkg; /* * this is a setup to check for redundant/cyclic dependency checks, * which are marked at the abstract_pkg level */ ab_pkg = pkg->parent; if (!ab_pkg) { opkg_msg(ERROR, "Internal error: %s not in hash table\n", pkg->name); return (pkg_vec_t *) NULL; } installed_conflicts = pkg_vec_alloc(); __pkg_hash_fetch_conflicts(pkg, installed_conflicts); __pkg_hash_fetch_conflictees(pkg, installed_conflicts); if (installed_conflicts->len) return installed_conflicts; pkg_vec_free(installed_conflicts); return (pkg_vec_t *) NULL; }
/* Transform all path components of the given entry. This includes hardlink and * symlink paths as well as the destination path. * * Returns 0 on success, 1 where the file does not need to be extracted and <0 * on error. */ static int transform_all_paths(struct archive_entry *entry, const char *dest) { char *path; const char *filename; int r; r = transform_dest_path(entry, dest); if (r) return r; /* Next transform hardlink and symlink destinations. */ filename = archive_entry_hardlink(entry); if (filename) { /* Apply the same transform to the hardlink path as was applied * to the destination path. */ path = join_paths(dest, filename); if (!path) { opkg_msg(ERROR, "Not extracting '%s': Hardlink to nowhere.\n", archive_entry_pathname(entry)); return 1; } archive_entry_set_hardlink(entry, path); free(path); } /* Currently no transform to perform for symlinks. */ return 0; }
int file_decompress(const char *in, const char *out) { int r; struct opkg_ar *ar; FILE *f; ar = ar_open_compressed_file(in); if (!ar) return -1; /* Open output file. */ f = fopen(out, "w"); if (!f) { opkg_msg(ERROR, "Failed to open output file '%s': %s\n", out, strerror(errno)); r = -1; goto cleanup; } /* Copy decompressed data. */ r = ar_copy_to_stream(ar, f); if (r < 0) goto cleanup; /* Success */ r = 0; cleanup: ar_close(ar); if (f) fclose(f); return r; }
static int copy_file_data(FILE * src_file, FILE * dst_file) { size_t nread, nwritten; char buffer[BUFSIZ]; while (1) { nread = fread(buffer, 1, BUFSIZ, src_file); if (nread != BUFSIZ && ferror(src_file)) { opkg_perror(ERROR, "read"); return -1; } /* Check for EOF. */ if (nread == 0) return 0; nwritten = fwrite(buffer, 1, nread, dst_file); if (nwritten != nread) { if (ferror(dst_file)) opkg_perror(ERROR, "write"); else opkg_msg(ERROR, "Unable to write all data.\n"); return -1; } } }
static struct archive *open_compressed_file(const char *filename) { struct archive *ar; int r; ar = archive_read_new(); if (!ar) { opkg_msg(ERROR, "Failed to create archive object for compressed file.\n"); return NULL; } /* Support raw data in gzip compression format. */ r = archive_read_support_filter_gzip(ar); if (r == ARCHIVE_WARN) { /* libarchive returns ARCHIVE_WARN if the filter is provided by * an external program. */ opkg_msg(INFO, "Gzip support provided by external program.\n"); } else if (r != ARCHIVE_OK) { opkg_msg(ERROR, "Gzip format not supported: %s\n", archive_error_string(ar)); goto err_cleanup; } r = archive_read_support_format_raw(ar); if (r != ARCHIVE_OK) { opkg_msg(ERROR, "Raw format not supported: %s\n", archive_error_string(ar)); goto err_cleanup; } /* Open input file and prepare for reading. */ r = archive_read_open_filename(ar, filename, EXTRACT_BUFFER_LEN); if (r != ARCHIVE_OK) { opkg_msg(ERROR, "Failed to open compressed file '%s': %s\n", filename, archive_error_string(ar)); goto err_cleanup; } return ar; err_cleanup: archive_read_free(ar); return NULL; }
/* Read data from an archive into a buffer. Returns 0 on error as the return * value is an unsigned size_t. If an eof pointer is provided, it will be set to * 1 on EOF or 0 otherwise. */ static size_t read_data(struct archive *a, void *buffer, size_t len, int *eof) { ssize_t r; int retries = 0; if (eof) *eof = 0; retry: /* Read data into buffer. */ r = archive_read_data(a, buffer, len); if (r > 0) { /* We got good data. */ return (size_t) r; } switch (r) { case 0: /* We reached EOF. */ if (eof) *eof = 1; return 0; case ARCHIVE_WARN: /* We don't know the size read so we have to treat this * as an error. */ opkg_msg(ERROR, "Warning when reading data from archive: %s\n", archive_error_string(a)); return 0; case ARCHIVE_RETRY: opkg_msg(ERROR, "Failed to read data from archive: %s\n", archive_error_string(a)); if (retries++ < 3) { opkg_msg(NOTICE, "Retrying..."); goto retry; } else return 0; default: opkg_msg(ERROR, "Failed to read data from archive: %s\n", archive_error_string(a)); return 0; } }
int pkg_src_download(pkg_src_t * src) { int err = 0; char *url; char *feed; const char *url_filename; sprintf_alloc(&feed, "%s/%s", opkg_config->lists_dir, src->name); url_filename = src->gzip ? "Packages.gz" : "Packages"; if (src->extra_data) /* debian style? */ sprintf_alloc(&url, "%s/%s/%s", src->value, src->extra_data, url_filename); else sprintf_alloc(&url, "%s/%s", src->value, url_filename); if (src->gzip) { char *cache_location; cache_location = opkg_download_cache(url, NULL, NULL); if (!cache_location) { err = -1; goto cleanup; } err = file_decompress(cache_location, feed); free(cache_location); if (err) { opkg_msg(ERROR, "Couldn't decompress feed for source %s.", src->name); goto cleanup; } } else { err = opkg_download(url, feed, NULL, NULL); if (err) goto cleanup; } opkg_msg(DEBUG, "Downloaded package list for %s.\n", src->name); cleanup: free(feed); free(url); return err; }
/** * pkg_breaks_reverse_dep returns 1 if pkg does not satisfy the version * constraints of the packages which depend upon pkg and otherwise returns 0. */ int pkg_breaks_reverse_dep(pkg_t * pkg) { /* We consider only the abstract_pkg_t to which pkg belongs (ie. that which * shares its name) not the abstract pkgs which it provides as dependence on * a virtual package should never involve a version constraint. */ abstract_pkg_t *rev_dep; abstract_pkg_t *apkg = pkg->parent; unsigned int i = 0; unsigned int j, k, m; unsigned int n_rev_deps; n_rev_deps = apkg->depended_upon_by->len; for (i = 0; i < n_rev_deps; i++) { rev_dep = apkg->depended_upon_by->pkgs[i]; unsigned int npkgs = rev_dep->pkgs->len; for (j = 0; j < npkgs; j++) { pkg_t *cmp_pkg = rev_dep->pkgs->pkgs[j]; compound_depend_t *cdeps = cmp_pkg->depends; unsigned int ncdeps = cmp_pkg->depends_count; /* Only check dependencies of a package which either will be * installed or will remain installed. */ if (cmp_pkg->state_want != SW_INSTALL) continue; /* Find the dependence on apkg. */ for (k = 0; k < ncdeps; k++) { depend_t **deps = cdeps[k].possibilities; unsigned int ndeps = cdeps[k].possibility_count; /* Skip recommends and suggests. */ if (cdeps[k].type != PREDEPEND && cdeps[k].type != DEPEND) continue; for (m = 0; m < ndeps; m++) { /* Is this the dependence on apkg? */ if (deps[m]->pkg != apkg) continue; if (!version_constraints_satisfied(deps[m], pkg)) { opkg_msg(DEBUG, "Installing %s %s would break reverse dependency from %s.\n", pkg->name, pkg->version, cmp_pkg->name); return 1; } } } } } return 0; }
int pkg_extract_data_files_to_dir(pkg_t * pkg, const char *dir) { int r; struct opkg_ar *ar; ar = ar_open_pkg_data_archive(pkg->local_filename); if (!ar) { opkg_msg(ERROR, "Failed to extract data.tar.gz from package '%s'.\n", pkg->local_filename); return -1; } r = ar_extract_all(ar, dir); if (r < 0) opkg_msg(ERROR, "Failed to extract data files from package '%s'.\n", pkg->local_filename); ar_close(ar); return r; }
int pkg_extract_control_file_to_stream(pkg_t * pkg, FILE * stream) { int r; struct opkg_ar *ar; ar = ar_open_pkg_control_archive(pkg->local_filename); if (!ar) { opkg_msg(ERROR, "Failed to extract control.tar.gz from package '%s'.\n", pkg->local_filename); return -1; } r = ar_extract_file_to_stream(ar, "control", stream); if (r < 0) opkg_msg(ERROR, "Failed to extract control file from package '%s'.\n", pkg->local_filename); ar_close(ar); return r; }
int pkg_src_verify(pkg_src_t * src) { int err = 0; char *feed; char *sigfile; const char *sigext; if (strcmp(opkg_config->signature_type, "gpg-asc") == 0) sigext = "asc"; else sigext = "sig"; sprintf_alloc(&feed, "%s/%s", opkg_config->lists_dir, src->name); sprintf_alloc(&sigfile, "%s.%s", feed, sigext); if (!file_exists(sigfile)) { opkg_msg(ERROR, "Signature file is missing for %s. " "Perhaps you need to run 'opkg update'?\n", src->name); err = -1; goto cleanup; } err = opkg_verify_signature(feed, sigfile); if (err) { opkg_msg(ERROR, "Signature verification failed for %s.\n", src->name); goto cleanup; } opkg_msg(DEBUG, "Signature verification passed for %s.\n", src->name); cleanup: if (err) { /* Remove incorrect files. */ unlink(feed); unlink(sigfile); } free(sigfile); free(feed); return err; }
/* Like system(3), but with error messages printed if the fork fails or if the child process dies due to an uncaught signal. Also, the return value is a bit simpler: -1 if there was any problem Otherwise, the 8-bit return value of the program ala WEXITSTATUS as defined in <sys/wait.h>. */ int xsystem(const char *argv[]) { int status; pid_t pid; pid = vfork(); switch (pid) { case -1: opkg_perror(ERROR, "%s: vfork", argv[0]); return -1; case 0: /* child */ execvp(argv[0], (char*const*)argv); _exit(-1); default: /* parent */ break; } if (waitpid(pid, &status, 0) == -1) { opkg_perror(ERROR, "%s: waitpid", argv[0]); return -1; } if (WIFSIGNALED(status)) { opkg_msg(ERROR, "%s: Child killed by signal %d.\n", argv[0], WTERMSIG(status)); return -1; } if (!WIFEXITED(status)) { /* shouldn't happen */ opkg_msg(ERROR, "%s: Your system is broken: got status %d " "from waitpid.\n", argv[0], status); return -1; } return WEXITSTATUS(status); }
/* Read a header from the given archive object and handle all possible outcomes. * The returned pointer is managed by libarchive and should not be freed by the * caller. * * If the caller needs to know whether EOF was hit without an error, they can * pass an eof pointer which will be set to 1 in this case or 0 otherwise. */ static struct archive_entry *read_header(struct archive *ar, int *eof) { struct archive_entry *entry; int r; int retries = 0; if (eof) *eof = 0; retry: r = archive_read_next_header(ar, &entry); switch (r) { case ARCHIVE_OK: break; case ARCHIVE_WARN: opkg_msg(NOTICE, "Warning when reading ar archive header: %s\n", archive_error_string(ar)); break; case ARCHIVE_EOF: if (eof) *eof = 1; return NULL; case ARCHIVE_RETRY: opkg_msg(ERROR, "Failed to read archive header: %s\n", archive_error_string(ar)); if (retries++ < 3) goto retry; else return NULL; default: opkg_msg(ERROR, "Failed to read archive header: %s\n", archive_error_string(ar)); return NULL; } return entry; }
/* * Downloads file from url, installs in package database, return package name. */ int opkg_prepare_url_for_install(const char *url, char **namep) { int err = 0; pkg_t *pkg; pkg = pkg_new(); if (str_starts_with(url, "http://") || str_starts_with(url, "ftp://")) { char *tmp_file; char *file_basec = xstrdup(url); char *file_base = basename(file_basec); sprintf_alloc(&tmp_file, "%s/%s", conf->tmp_dir, file_base); err = opkg_download(url, tmp_file, NULL, NULL, 0); if (err) return err; err = pkg_init_from_file(pkg, tmp_file); if (err) return err; free(tmp_file); free(file_basec); } else if (strcmp(&url[strlen(url) - 4], OPKG_PKG_EXTENSION) == 0 || strcmp(&url[strlen(url) - 4], IPKG_PKG_EXTENSION) == 0 || strcmp(&url[strlen(url) - 4], DPKG_PKG_EXTENSION) == 0) { err = pkg_init_from_file(pkg, url); if (err) return err; opkg_msg(DEBUG2, "Package %s provided by hand (%s).\n", pkg->name, pkg->local_filename); pkg->provided_by_hand = 1; } else { pkg_deinit(pkg); free(pkg); return 0; } pkg->dest = conf->default_dest; pkg->state_want = SW_INSTALL; pkg->state_flag |= SF_PREFER; hash_insert_pkg(pkg, 1); if (namep) { *namep = pkg->name; } return 0; }
int pkg_extract_data_file_names_to_stream(pkg_t * pkg, FILE * stream) { int r; struct opkg_ar *ar; ar = ar_open_pkg_data_archive(pkg->local_filename); if (!ar) { opkg_msg(ERROR, "Failed to extract data.tar.gz from package '%s'.\n", pkg->local_filename); return -1; } r = ar_extract_paths_to_stream(ar, stream); if (r < 0) opkg_msg(ERROR, "Failed to extract data file names from package '%s'.\n", pkg->local_filename); ar_close(ar); return r; }
int file_copy(const char *src, const char *dest) { int err; err = copy_file(src, dest, FILEUTILS_FORCE | FILEUTILS_PRESERVE_STATUS); if (err) opkg_msg(ERROR, "Failed to copy file %s to %s.\n", src, dest); return err; }
/* * this is an open table keyed by strings */ void hash_table_init(const char *name, hash_table_t * hash, int len) { if (hash->entries != NULL) { opkg_msg(ERROR, "Internal error: non empty hash table.\n"); return; } memset(hash, 0, sizeof(hash_table_t)); hash->name = name; hash->n_buckets = len; hash->entries = xcalloc(hash->n_buckets, sizeof(hash_entry_t)); }
static struct archive *open_disk(int flags) { struct archive *disk; int r; disk = archive_write_disk_new(); if (!disk) { opkg_msg(ERROR, "Failed to create disk archive object.\n"); return NULL; } r = archive_write_disk_set_options(disk, flags); if (r == ARCHIVE_WARN) opkg_msg(NOTICE, "Warning when setting disk options: %s\n", archive_error_string(disk)); else if (r != ARCHIVE_OK) { opkg_msg(ERROR, "Failed to set disk options: %s\n", archive_error_string(disk)); goto err_cleanup; } r = archive_write_disk_set_standard_lookup(disk); if (r == ARCHIVE_WARN) opkg_msg(NOTICE, "Warning when setting user/group lookup functions: %s\n", archive_error_string(disk)); else if (r != ARCHIVE_OK) { opkg_msg(ERROR, "Failed to set user/group lookup functions: %s\n", archive_error_string(disk)); goto err_cleanup; } return disk; err_cleanup: archive_write_free(disk); return NULL; }