static void
extract (int fd)
{
  struct archive *a;
  struct archive *ext;
  struct archive_entry *entry;
  int r;

  a = archive_read_new ();
  ext = archive_write_disk_new ();
  archive_read_support_format_tar (a);
  archive_read_support_filter_xz (a);
  archive_read_support_filter_gzip (a);

  if ((r = archive_read_open_fd (a, fd, 16*1024)))
    die_with_libarchive (a, "archive_read_open_fd: %s");

  while (1)
    {
      r = archive_read_next_header (a, &entry);
      if (r == ARCHIVE_EOF)
        break;

      if (r != ARCHIVE_OK)
        die_with_libarchive (a, "archive_read_next_header: %s");

      if (!should_extract (entry))
        continue;

      r = archive_write_header (ext, entry);
      if (r != ARCHIVE_OK)
        die_with_libarchive (ext, "archive_write_header: %s");
      else
        {
          copy_archive (a, ext);
          r = archive_write_finish_entry (ext);
          if (r != ARCHIVE_OK)
            die_with_libarchive (ext, "archive_write_finish_entry: %s");
        }
    }

  archive_read_close (a);
  archive_read_free (a);

  archive_write_close (ext);
  archive_write_free (ext);
}
Ejemplo n.º 2
0
int
do_extract_mtree(char *mtree, const char *prefix)
{
	struct archive *a = NULL;
	struct archive_entry *ae;
	char path[MAXPATHLEN];
	const char *fpath;
	int retcode = EPKG_OK;
	int ret;

	if (mtree == NULL || *mtree == '\0')
		return EPKG_OK;

	a = archive_read_new();
	archive_read_support_filter_none(a);
	archive_read_support_format_mtree(a);

	if (archive_read_open_memory(a, mtree, strlen(mtree)) != ARCHIVE_OK) {
		pkg_emit_error("Fail to extract the mtree: %s",
		    archive_error_string(a));
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	while ((ret = archive_read_next_header(a, &ae)) != ARCHIVE_EOF) {
		if (ret != ARCHIVE_OK) {
			pkg_emit_error("Skipping unsupported mtree line: %s",
			    archive_error_string(a));
			continue;
		}
		fpath = archive_entry_pathname(ae);

		if (*fpath != '/') {
			snprintf(path, sizeof(path), "%s/%s", prefix, fpath);
			archive_entry_set_pathname(ae, path);
		}

		/* Ignored failed extraction on purpose */
		archive_read_extract(a, ae, EXTRACT_ARCHIVE_FLAGS);
	}

cleanup:
	if (a != NULL)
		archive_read_free(a);

	return (retcode);
}
Ejemplo n.º 3
0
GBytes *file_type_archive_data_loader(file_t *file, GError **error_pointer) {/*{{{*/
	const file_loader_delegate_archive_t *archive_data = g_bytes_get_data(file->file_data, NULL);

	GBytes *data = buffered_file_as_bytes(archive_data->source_archive, NULL, error_pointer);
	if(!data) {
		g_printerr("Failed to load archive %s: %s\n", file->display_name, error_pointer && *error_pointer ? (*error_pointer)->message : "Unknown error");
		g_clear_error(error_pointer);
		return NULL;
	}

	struct archive *archive = file_type_archive_gen_archive(data);
	if(!archive) {
		buffered_file_unref(file);
		return NULL;
	}

	// Find the proper entry
	size_t entry_size = 0;
	void *entry_data = NULL;

	struct archive_entry *entry;
	while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
		if(archive_data->entry_name && strcmp(archive_data->entry_name, archive_entry_pathname(entry)) == 0) {
			entry_size = archive_entry_size(entry);
			entry_data = g_malloc(entry_size);

			if(archive_read_data(archive, entry_data, entry_size) != (ssize_t)entry_size) {
				archive_read_free(archive);
				buffered_file_unref(file);
				*error_pointer = g_error_new(g_quark_from_static_string("pqiv-archive-error"), 1, "The file had an unexpected size");
				return NULL;
			}

			break;
		}
	}

	archive_read_free(archive);
	buffered_file_unref(archive_data->source_archive);
	if(!entry_size) {
		*error_pointer = g_error_new(g_quark_from_static_string("pqiv-archive-error"), 1, "The file has gone within the archive");
		return NULL;
	}

	return g_bytes_new_take(entry_data, entry_size);
}/*}}}*/
Ejemplo n.º 4
0
static int
append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
{
    struct archive_entry *in_entry;
    int e;

    while (ARCHIVE_OK == (e = archive_read_next_header(ina, &in_entry))) {
        if (archive_match_excluded(bsdtar->matching, in_entry))
            continue;
        if (bsdtar->option_interactive &&
                !yes("copy '%s'", archive_entry_pathname(in_entry)))
            continue;
        if (bsdtar->verbose > 1) {
            safe_fprintf(stderr, "a ");
            list_item_verbose(bsdtar, stderr, in_entry);
        } else if (bsdtar->verbose > 0)
            safe_fprintf(stderr, "a %s",
                         archive_entry_pathname(in_entry));
        if (need_report())
            report_write(bsdtar, a, in_entry, 0);

        e = archive_write_header(a, in_entry);
        if (e != ARCHIVE_OK) {
            if (!bsdtar->verbose)
                lafe_warnc(0, "%s: %s",
                           archive_entry_pathname(in_entry),
                           archive_error_string(a));
            else
                fprintf(stderr, ": %s", archive_error_string(a));
        }
        if (e == ARCHIVE_FATAL)
            exit(1);

        if (e >= ARCHIVE_WARN) {
            if (archive_entry_size(in_entry) == 0)
                archive_read_data_skip(ina);
            else if (copy_file_data_block(bsdtar, a, ina, in_entry))
                exit(1);
        }

        if (bsdtar->verbose)
            fprintf(stderr, "\n");
    }

    return (e == ARCHIVE_EOF ? ARCHIVE_OK : e);
}
Ejemplo n.º 5
0
static void verifyEmpty(void)
{
	struct archive_entry *ae;
	struct archive *a;

	assert((a = archive_read_new()) != NULL);
	assertA(0 == archive_read_support_filter_all(a));
	assertA(0 == archive_read_support_format_all(a));
	assertA(0 == archive_read_open_memory(a, archiveEmpty, 512));
	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
	assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
	assertEqualString(archive_filter_name(a, 0), "none");
	failure("512 zero bytes should be recognized as a tar archive.");
	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR);

	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
Ejemplo n.º 6
0
 std::string next_with_data(char** data_out, size_t* data_size)
 {
     if (archive_read_next_header(mArchive, &mEntry) == ARCHIVE_OK)
     {
         std::string entryName = archive_entry_pathname(mEntry);
         size_t size = archive_entry_size(mEntry);
         if (size > mSize)
         {
             mSize = size;
             mData = (char*)realloc(mData, mSize);
         }
         archive_read_data(mArchive, mData, size); 
         *data_out = mData;
         *data_size = size;
         return entryName;
     }
     return std::string("");
 }
Ejemplo n.º 7
0
static xbps_dictionary_t
repo_get_dict(struct xbps_repo *repo)
{
	struct archive_entry *entry;
	int rv;

	if (repo->ar == NULL)
		return NULL;

	rv = archive_read_next_header(repo->ar, &entry);
	if (rv != ARCHIVE_OK) {
		xbps_dbg_printf(repo->xhp,
		    "%s: read_next_header %s\n", repo->uri,
		    archive_error_string(repo->ar));
		return NULL;
	}
	return xbps_archive_get_dictionary(repo->ar, entry);
}
Ejemplo n.º 8
0
static void
mode_list(struct cpio *cpio)
{
	struct archive *a;
	struct archive_entry *entry;
	int r;

	a = archive_read_new();
	if (a == NULL)
		lafe_errc(1, 0, "Couldn't allocate archive object");
	archive_read_support_filter_all(a);
	archive_read_support_format_all(a);

	if (archive_read_open_filename(a, cpio->filename,
					cpio->bytes_per_block))
		lafe_errc(1, archive_errno(a),
		    "%s", archive_error_string(a));
	for (;;) {
		r = archive_read_next_header(a, &entry);
		if (r == ARCHIVE_EOF)
			break;
		if (r != ARCHIVE_OK) {
			lafe_errc(1, archive_errno(a),
			    "%s", archive_error_string(a));
		}
		if (archive_match_path_excluded(cpio->matching, entry))
			continue;
		if (cpio->verbose)
			list_item_verbose(cpio, entry);
		else
			fprintf(stdout, "%s\n", archive_entry_pathname(entry));
	}
	r = archive_read_close(a);
	if (r != ARCHIVE_OK)
		lafe_errc(1, 0, "%s", archive_error_string(a));
	if (!cpio->quiet) {
		int64_t blocks = (archive_filter_bytes(a, 0) + 511)
			      / 512;
		fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
		    blocks == 1 ? "block" : "blocks");
	}
	archive_read_free(a);
	exit(0);
}
Ejemplo n.º 9
0
// Iterate entries. The first call establishes the first entry. Returns false
// if no entry found, otherwise returns true and sets mpa->entry/entry_filename.
bool mp_archive_next_entry(struct mp_archive *mpa)
{
    mpa->entry = NULL;
    talloc_free(mpa->entry_filename);
    mpa->entry_filename = NULL;

    if (!mpa->arch)
        return false;

    locale_t oldlocale = uselocale(mpa->locale);
    bool success = false;

    while (!mp_cancel_test(mpa->primary_src->cancel)) {
        struct archive_entry *entry;
        int r = archive_read_next_header(mpa->arch, &entry);
        if (r == ARCHIVE_EOF)
            break;
        if (r < ARCHIVE_OK)
            MP_ERR(mpa, "%s\n", archive_error_string(mpa->arch));
        if (r < ARCHIVE_WARN) {
            MP_FATAL(mpa, "could not read archive entry\n");
            mp_archive_check_fatal(mpa, r);
            break;
        }
        if (archive_entry_filetype(entry) != AE_IFREG)
            continue;
        // Some archives may have no filenames, or libarchive won't return some.
        const char *fn = archive_entry_pathname(entry);
        char buf[64];
        if (!fn || bstr_validate_utf8(bstr0(fn)) < 0) {
            snprintf(buf, sizeof(buf), "mpv_unknown#%d", mpa->entry_num);
            fn = buf;
        }
        mpa->entry = entry;
        mpa->entry_filename = talloc_strdup(mpa, fn);
        mpa->entry_num += 1;
        success = true;
        break;
    }

    uselocale(oldlocale);

    return success;
}
Ejemplo n.º 10
0
Archivo: cpio.c Proyecto: marccodes/lfl
static void
mode_list(struct cpio *cpio)
{
	struct archive *a;
	struct archive_entry *entry;
	unsigned long blocks;
	int r;

	a = archive_read_new();
	if (a == NULL)
		cpio_errc(1, 0, "Couldn't allocate archive object");
	archive_read_support_compression_all(a);
	archive_read_support_format_all(a);

	if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
		cpio_errc(1, archive_errno(a),
		    archive_error_string(a));
	for (;;) {
		r = archive_read_next_header(a, &entry);
		if (r == ARCHIVE_EOF)
			break;
		if (r != ARCHIVE_OK) {
			cpio_errc(1, archive_errno(a),
			    archive_error_string(a));
		}
		if (excluded(cpio, archive_entry_pathname(entry)))
			continue;
		if (cpio->verbose)
			list_item_verbose(cpio, entry);
		else
			fprintf(stdout, "%s\n", archive_entry_pathname(entry));
	}
	r = archive_read_close(a);
	if (r != ARCHIVE_OK)
		cpio_errc(1, 0, archive_error_string(a));
	if (!cpio->quiet) {
		blocks = (archive_position_uncompressed(a) + 511)
			      / 512;
		fprintf(stderr, "%lu %s\n", blocks,
		    blocks == 1 ? "block" : "blocks");
	}
	archive_read_finish(a);
	exit(0);
}
Ejemplo n.º 11
0
int
pkg_full_signature_check(const char *archive_name, struct archive **archive)
{
	struct archive_entry *entry = NULL;
	char *pkgname;
	int r;

	if (pkg_verify_signature(archive_name, archive, &entry, &pkgname))
		return -1;
	if (pkgname == NULL)
		return 0;

	/* XXX read PLIST and compare pkgname */
	while ((r = archive_read_next_header(*archive, &entry)) == ARCHIVE_OK)
		archive_read_data_skip(*archive);

	free(pkgname);
	return r == ARCHIVE_EOF ? 0 : -1;
}
Ejemplo n.º 12
0
size_t LIBARCHIVEgetEntry(char *name, char *contentFile, char **ptr) {
  struct mydata *mydata;
  struct archive *a;
  struct archive_entry *entry;
  char *buf;
  size_t size = 0;

  mydata = (struct mydata*)malloc(sizeof(struct mydata));
  a = archive_read_new();
  mydata->name = name;
  archive_read_support_format_all(a);
  archive_read_support_compression_all(a);
  if (archive_read_open(a, mydata, myopen, myread, myclose) == ARCHIVE_FATAL) {
    fprintf(stderr, "failed to open %s\n", mydata->name);
    free(mydata->name);
    free(mydata);
    return 0;
  }

  while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
    if( 0 == strcmp(archive_entry_pathname(entry), contentFile)) {
      o_log(DEBUGM, "%s", (char *)archive_compression_name(a));
      o_log(DEBUGM, "%s", (char *)archive_format_name(a));
      o_log(DEBUGM, "%s", (char *)archive_entry_pathname(entry));
      size = archive_entry_size(entry);
      if(size <= 0)
        o_log(DEBUGM, "zero size");
      if ((buf = (char *)malloc(size+1)) == NULL)
        o_log(ERROR, "cannot allocate memory");
      if ((size_t)archive_read_data(a, buf, size) != size)
        o_log(DEBUGM, "cannot read data");
      buf[size] = '\0';
      *ptr = buf;
    }
    else
      archive_read_data_skip(a);
  }

  archive_read_close(a);
  archive_read_finish(a);
  free(mydata);
  return size;
}
Ejemplo n.º 13
0
int load_package(pkg_t *pkg, int fd)
{
    struct archive *archive;
    struct file_t file;

    if (file_from_fd(&file, fd) < 0) {
        return -1;
    }

    archive = archive_read_new();
    archive_read_support_filter_all(archive);
    archive_read_support_format_all(archive);

    if (archive_read_open_memory(archive, file.mmap, file.st.st_size) != ARCHIVE_OK) {
        archive_read_free(archive);
        return -1;
    }

    bool found_pkginfo = false;
    struct archive_entry *entry;
    while (archive_read_next_header(archive, &entry) == ARCHIVE_OK && !found_pkginfo) {
        const char *entry_name = archive_entry_pathname(entry);
        const mode_t mode = archive_entry_mode(entry);

        if (S_ISREG(mode) && streq(entry_name, ".PKGINFO")) {
            read_pkginfo(archive, pkg);
            found_pkginfo = true;
        }
    }

    archive_read_close(archive);
    archive_read_free(archive);

    if (found_pkginfo) {
        pkg->size = file.st.st_size;
        pkg->mtime = file.st.st_mtime;
        pkg->name_hash = _alpm_hash_sdbm(pkg->name);
        return 0;
    }

    return -1;
}
Ejemplo n.º 14
0
static DEB_RESULT
process_meta_file_contents(struct archive *controlarchive, DEB_FILE *file)
{
    struct archive_entry *entry = NULL;
    int control_file_found = 0;

    while(archive_read_next_header(controlarchive, &entry) == ARCHIVE_OK) {
        /* +2 because all file names start with './' */
		const char *filename = archive_entry_pathname(entry) + 2;

        if(strstartswith(filename, DEB_CONTROL_FILE_NAME)) {
            parse_control_file(controlarchive, entry, file);
            control_file_found = 1;            
        } else {

        }
    }

    return DEB_RESULT_OK;
}
Ejemplo n.º 15
0
static struct pkg_vulnerabilities *
read_pkg_vulnerabilities_archive(struct archive *a, int check_sum)
{
	struct archive_entry *ae;
	struct pkg_vulnerabilities *pv;
	char *buf;
	size_t buf_len, off;
	ssize_t r;

	if (archive_read_next_header(a, &ae) != ARCHIVE_OK)
		errx(EXIT_FAILURE, "Cannot read pkg_vulnerabilities: %s",
		    archive_error_string(a));

	off = 0;
	buf_len = 65536;
	buf = xmalloc(buf_len + 1);

	for (;;) {
		r = archive_read_data(a, buf + off, buf_len - off);
		if (r <= 0)
			break;
		off += r;
		if (off == buf_len) {
			buf_len *= 2;
			if (buf_len < off)
				errx(EXIT_FAILURE, "pkg_vulnerabilties too large");
			buf = xrealloc(buf, buf_len + 1);
		}
	}

	if (r != ARCHIVE_OK)
		errx(EXIT_FAILURE, "Cannot read pkg_vulnerabilities: %s",
		    archive_error_string(a));

	archive_read_close(a);

	buf[off] = '\0';
	pv = parse_pkg_vuln(buf, off, check_sum);
	free(buf);
	return pv;
}
Ejemplo n.º 16
0
/* 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;
}
Ejemplo n.º 17
0
bool archive_exists(const std::string &filename,
                    std::vector<exists_info> &files)
{
    if (files.empty()) {
        return false;
    }

    autoclose::archive in(archive_read_new(), archive_read_free);

    if (!in) {
        LOGE("Out of memory");
        return false;
    }

    archive_entry *entry;
    int ret;

    for (exists_info &info : files) {
        info.exists = false;
    }

    if (!set_up_input(in.get(), filename)) {
        return false;
    }

    while ((ret = archive_read_next_header(in.get(), &entry)) == ARCHIVE_OK) {
        for (exists_info &info : files) {
            if (info.path == archive_entry_pathname(entry)) {
                info.exists = true;
            }
        }
    }

    if (ret != ARCHIVE_EOF) {
        LOGE("Archive extraction ended without reaching EOF: %s",
             archive_error_string(in.get()));
        return false;
    }

    return true;
}
Ejemplo n.º 18
0
static gboolean
http_archive_read_callback (gpointer user_data)
{
    FetchData *fetch_data = (FetchData *) user_data;

    gint r;
    struct archive_entry *entry;
    gchar *newPath = NULL;

    r = archive_read_next_header(fetch_data->a, &entry);
    if (r == ARCHIVE_EOF) {
        g_idle_add (archive_finish_callback, fetch_data);
        return FALSE;
    }

    if (r != ARCHIVE_OK) {
        g_set_error(&fetch_data->error, RESTRAINT_FETCH_LIBARCHIVE_ERROR, r,
                "archive_read_next_header failed: %s", archive_error_string(fetch_data->a));
        g_idle_add (archive_finish_callback, fetch_data);
        return FALSE;
    }

    if (fetch_data->archive_entry_callback) {
        fetch_data->archive_entry_callback (archive_entry_pathname (entry),
                                            fetch_data->user_data);
    }

    // Update pathname
    newPath = g_build_filename (fetch_data->base_path, archive_entry_pathname( entry ), NULL);
    archive_entry_set_pathname( entry, newPath );
    g_free(newPath);

    r = archive_read_extract2(fetch_data->a, entry, fetch_data->ext);
    if (r != ARCHIVE_OK) {
        g_set_error(&fetch_data->error, RESTRAINT_FETCH_LIBARCHIVE_ERROR, r,
                "archive_read_extract2 failed: %s", archive_error_string(fetch_data->ext));
        g_idle_add (archive_finish_callback, fetch_data);
        return FALSE;
    }
    return TRUE;
}
static void
test_empty_tarfile(void)
{
	struct archive* a = archive_read_new();
	struct archive_entry* e;

	/* Try opening an empty file with raw and empty handlers. */
	assertEqualInt(ARCHIVE_OK, archive_read_support_format_tar(a));
	assertEqualInt(0, archive_errno(a));
	assertEqualString(NULL, archive_error_string(a));

	assertEqualInt(ARCHIVE_OK, archive_read_open_filename(a, "empty.tar", 0));
	assertEqualInt(0, archive_errno(a));
	assertEqualString(NULL, archive_error_string(a));

	assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &e));
	assertEqualInt(0, archive_errno(a));
	assertEqualString(NULL, archive_error_string(a));

	archive_read_free(a);
}
Ejemplo n.º 20
0
static void verifyEmpty(void)
{
	struct archive_entry *ae;
	struct archive *a;

	assert((a = archive_read_new()) != NULL);
	assertA(0 == archive_read_support_compression_all(a));
	assertA(0 == archive_read_support_format_all(a));
	assertA(0 == archive_read_open_memory(a, archiveEmpty, 512));
	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
	assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_NONE);
	failure("512 zero bytes should be recognized as a tar archive.");
	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR);

	assert(0 == archive_read_close(a));
#if ARCHIVE_API_VERSION > 1
	assert(0 == archive_read_finish(a));
#else
	archive_read_finish(a);
#endif
}
int main() {
    struct archive *a = archive_read_new();
    archive_read_support_filter_all(a);
    archive_read_support_format_all(a);
    int r = archive_read_open_filename(a, "test.tar", 10240);
    if (r != ARCHIVE_OK)
        return 1;

    struct archive_entry *entry;
    while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
        printf("%s\\n",archive_entry_pathname(entry));
        int64_t offset = archive_read_current_position(a);
        archive_read_data_skip(a);
    }

    r = archive_read_free(a);
    if (r != ARCHIVE_OK)
        return 1;

    return 0;
}
Ejemplo n.º 22
0
static int ReadDir( stream_directory_t* p_directory, input_item_node_t* p_node )
{
    private_sys_t* p_sys = p_directory->p_sys;
    libarchive_t* p_arc = p_sys->p_archive;

    struct vlc_readdir_helper rdh;
    vlc_readdir_helper_init( &rdh, p_directory, p_node);
    struct archive_entry* entry;
    int archive_status;

    while( !( archive_status = archive_read_next_header( p_arc, &entry ) ) )
    {
        if( archive_entry_filetype( entry ) == AE_IFDIR )
            continue;

        char const* path = archive_entry_pathname( entry );

        if( unlikely( !path ) )
            break;

        char*       mrl  = vlc_stream_extractor_CreateMRL( p_directory, path );

        if( unlikely( !mrl ) )
            break;

        if( vlc_readdir_helper_additem( &rdh, mrl, path, NULL, ITEM_TYPE_FILE,
                                        ITEM_LOCAL ) )
        {
            free( mrl );
            break;
        }
        free( mrl );

        if( archive_read_data_skip( p_arc ) )
            break;
    }

    vlc_readdir_helper_finish( &rdh, archive_status == ARCHIVE_EOF );
    return archive_status == ARCHIVE_EOF ? VLC_SUCCESS : VLC_EGENERIC;
}
Ejemplo n.º 23
0
static int repack_repo_data(const struct repo_t *repo) {
  struct archive_conv conv = {};
  int r = 0;

  if (archive_conv_open(&conv, repo) < 0) {
    return -1;
  }

  while (archive_read_next_header(conv.in, &conv.ae) == ARCHIVE_OK) {
    const char *entryname = archive_entry_pathname(conv.ae);

    /* ignore everything but the /files metadata */
    if (endswith(entryname, "/files")) {
      r = write_cpio_entry(&conv, entryname);
      if (r < 0) {
        break;
      }
    }
  }

  archive_conv_close(&conv);

  if (r < 0) {
    /* oh noes! */
    if (unlink(conv.tmpfile) < 0 && errno != ENOENT) {
      fprintf(stderr, "error: failed to unlink temporary file: %s: %s\n",
              conv.tmpfile, strerror(errno));
    }
    return -1;
  }

  if (rename(conv.tmpfile, repo->diskfile) != 0) {
    fprintf(stderr, "error: failed to rotate new repo for %s into place: %s\n",
            repo->name, strerror(errno));
    return -1;
  }

  return 0;
}
Ejemplo n.º 24
0
static VALUE rb_libarchive_reader_next_header(VALUE self) {
  struct rb_libarchive_archive_container *p;
  struct archive_entry *ae;
  int r;
  Data_Get_Struct(self, struct rb_libarchive_archive_container, p);
  Check_Archive(p);

  if (p->eof) {
    return Qnil;
  }

  r = archive_read_next_header(p->ar, &ae);

  if (r == ARCHIVE_EOF) {
    p->eof = 1;
    return Qnil;
  } else if (r != ARCHIVE_OK) {
    rb_raise(rb_eArchiveError, "Fetch entry failed: %s", archive_error_string(p->ar));
  }

  return rb_libarchive_entry_new(ae, 0);
}
Ejemplo n.º 25
0
	bool next_frame()
	{
		png_structp png_ptr;
		png_infop info_ptr;
		struct archive_entry *ae;
		int res;

read_data:
		res = archive_read_next_header(this->archive, &ae); 
		if (res != ARCHIVE_OK || res == ARCHIVE_EOF) {
			if (play_mode == LOOP) {
				/* Go to the first archive entry and read it. */
				close();
				open();
				goto read_data;
			} else {
				printf("Animation finished.\n");
				return false;
			}
		} else if (res == ARCHIVE_FATAL || res == ARCHIVE_WARN || res == ARCHIVE_RETRY) {
			printf("Failed to read next header.\n");
			return false;
		} else if (res == 0) {
			/* At the end of the archive check the loop flag to see if we
			 * restart. */
			if (read_png(&png_ptr, &info_ptr, this->archive) == 1) {
				fprintf(stderr, "Problem reading PNG.\n");
				return false;
			}	
			/* Store the image data into the framebuffer. */
			set_framebuffer(png_ptr, info_ptr, framebuffer);
			png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
		} else {
			fprintf(stderr, "archive_read_next_header resulted in an unknown error.\n");
			return false;
		}	
		return true;
	}
Ejemplo n.º 26
0
extern int
lparchive_extract(lparchive_t *handle, char *path)
{
     char cwd[1024];
     unsigned int i;
     struct archive_entry *entry;
     struct archive *archive = handle->archive;

     if ( getcwd(cwd, 1024) == NULL )
          return -1;

     if ( chdir(path) == -1 )
          return -1;

     for (i=0; archive_read_next_header(archive, &entry) == ARCHIVE_OK; ++i) {
          if ( archive_read_extract(archive, entry, 0) != ARCHIVE_OK )
               return -1;
     }
     if ( chdir(cwd) == -1 )
          return -1;
     
     return 0;
}
Ejemplo n.º 27
0
int pkg_archive_file_count(const char *path){
	struct archive *a;
	struct archive_entry *entry;
	int files,
	    r;
	
	a = pkg_archive_open(path);
	
	if(a == NULL)
		return -1;
	
	for(files = 0;;files++){
		r = archive_read_next_header(a, &entry);
		if(r == ARCHIVE_EOF)
			break;
		if(r != ARCHIVE_OK){
			RETURN_P_LARCHIVE(-1, a);
		}
	}
	
	pkg_archive_close(a);
	
	return files;
}
Ejemplo n.º 28
0
static void
test1(void)
{
	struct archive_entry *ae;
	struct archive *a;
	const char *name = "test_read_format_iso.iso.Z";

	extract_reference_file(name);

	assert((a = archive_read_new()) != NULL);
	assertEqualIntA(a, ARCHIVE_OK,
	    archive_read_support_compression_all(a));
	assertEqualIntA(a, ARCHIVE_OK,
	    archive_read_support_format_all(a));
	assertEqualIntA(a, ARCHIVE_OK,
	    archive_read_open_filename(a, name, 512));
	assertEqualIntA(a, ARCHIVE_OK,
	    archive_read_next_header(a, &ae));
	assertEqualInt(archive_compression(a),
	    ARCHIVE_COMPRESSION_COMPRESS);
	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660);
	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
}
Ejemplo n.º 29
0
Installer::ProceedState RomInstaller::on_checked_device()
{
    // /sbin is not going to be populated with anything useful in a normal boot
    // image. We can almost guarantee that a recovery image is going to be
    // installed though, so we'll open the recovery partition with libmbp and
    // extract its /sbin with libarchive into the chroot's /sbin.

    std::string block_dev(_recovery_block_dev);
    mbp::BootImage bi;
    mbp::CpioFile innerCpio;
    const unsigned char *ramdisk_data;
    std::size_t ramdisk_size;
    bool using_boot = false;

    // Check if the device has a combined boot/recovery partition. If the
    // FOTAKernel partition is listed, it will be used instead of the combined
    // ramdisk from the boot image
    bool combined = mb_device_flags(_device)
            & FLAG_HAS_COMBINED_BOOT_AND_RECOVERY;
    if (combined && block_dev.empty()) {
        block_dev = _boot_block_dev;
        using_boot = true;
    }

    if (block_dev.empty()) {
        display_msg("Could not determine the recovery block device");
        return ProceedState::Fail;
    }

    if (!bi.loadFile(block_dev)) {
        display_msg("Failed to load recovery partition image");
        return ProceedState::Fail;
    }

    // Load ramdisk
    bi.ramdiskImageC(&ramdisk_data, &ramdisk_size);

    if (using_boot) {
        if (!innerCpio.load(ramdisk_data, ramdisk_size)) {
            display_msg("Failed to load ramdisk from combined boot image");
            return ProceedState::Fail;
        }

        if (!innerCpio.contentsC("sbin/ramdisk-recovery.cpio",
                                 &ramdisk_data, &ramdisk_size)) {
            display_msg("Could not find recovery ramdisk in combined boot image");
            return ProceedState::Fail;
        }
    }

    autoclose::archive in(archive_read_new(), archive_read_free);
    autoclose::archive out(archive_write_disk_new(), archive_write_free);

    if (!in || !out) {
        LOGE("Out of memory");
        return ProceedState::Fail;
    }

    archive_entry *entry;

    // Set up input
    archive_read_support_filter_gzip(in.get());
    archive_read_support_filter_lzop(in.get());
    archive_read_support_filter_lz4(in.get());
    archive_read_support_filter_lzma(in.get());
    archive_read_support_filter_xz(in.get());
    archive_read_support_format_cpio(in.get());

    int ret = archive_read_open_memory(in.get(),
            const_cast<unsigned char *>(ramdisk_data), ramdisk_size);
    if (ret != ARCHIVE_OK) {
        LOGW("Failed to open recovery ramdisk: %s",
             archive_error_string(in.get()));
        return ProceedState::Fail;
    }

    // Set up output
    archive_write_disk_set_options(out.get(),
                                   ARCHIVE_EXTRACT_ACL |
                                   ARCHIVE_EXTRACT_FFLAGS |
                                   ARCHIVE_EXTRACT_PERM |
                                   ARCHIVE_EXTRACT_SECURE_NODOTDOT |
                                   ARCHIVE_EXTRACT_SECURE_SYMLINKS |
                                   ARCHIVE_EXTRACT_TIME |
                                   ARCHIVE_EXTRACT_UNLINK |
                                   ARCHIVE_EXTRACT_XATTR);

    while ((ret = archive_read_next_header(in.get(), &entry)) == ARCHIVE_OK) {
        std::string path = archive_entry_pathname(entry);

        if (path == "default.prop") {
            path = "default.recovery.prop";
        } else if (!util::starts_with(path, "sbin/")) {
            continue;
        }

        LOGE("Copying from recovery: %s", path.c_str());

        archive_entry_set_pathname(entry, in_chroot(path).c_str());

        if (util::libarchive_copy_header_and_data(
                in.get(), out.get(), entry) != ARCHIVE_OK) {
            return ProceedState::Fail;
        }

        archive_entry_set_pathname(entry, path.c_str());
    }

    if (ret != ARCHIVE_EOF) {
        LOGE("Archive extraction ended without reaching EOF: %s",
             archive_error_string(in.get()));
        return ProceedState::Fail;
    }

    // Create fake /etc/fstab file to please installers that read the file
    std::string etc_fstab(in_chroot("/etc/fstab"));
    if (access(etc_fstab.c_str(), R_OK) < 0 && errno == ENOENT) {
        autoclose::file fp(autoclose::fopen(etc_fstab.c_str(), "w"));
        if (fp) {
            auto system_devs = mb_device_system_block_devs(_device);
            auto cache_devs = mb_device_cache_block_devs(_device);
            auto data_devs = mb_device_data_block_devs(_device);

            // Set block device if it's provided and non-empty
            const char *system_dev =
                    system_devs && system_devs[0] && system_devs[0][0]
                    ? system_devs[0] : "dummy";
            const char *cache_dev =
                    cache_devs && cache_devs[0] && cache_devs[0][0]
                    ? cache_devs[0] : "dummy";
            const char *data_dev =
                    data_devs && data_devs[0] && data_devs[0][0]
                    ? data_devs[0] : "dummy";

            fprintf(fp.get(), "%s /system ext4 rw 0 0\n", system_dev);
            fprintf(fp.get(), "%s /cache ext4 rw 0 0\n", cache_dev);
            fprintf(fp.get(), "%s /data ext4 rw 0 0\n", data_dev);
        }
    }

    // Load recovery properties
    util::file_get_all_properties(
            in_chroot("/default.recovery.prop"), &_recovery_props);

    return ProceedState::Continue;
}
Ejemplo n.º 30
0
static void
test_filename(const char *prefix, int dlen, int flen)
{
	char buff[8192];
	char filename[400];
	char dirname[400];
	struct archive_entry *ae;
	struct archive *a;
	size_t used;
	int separator = 0;
	int i = 0;

	if (prefix != NULL) {
		strcpy(filename, prefix);
		i = (int)strlen(prefix);
	}
	if (dlen > 0) {
		for (; i < dlen; i++)
			filename[i] = 'a';
		filename[i++] = '/';
		separator = 1;
	}
	for (; i < dlen + flen + separator; i++)
		filename[i] = 'b';
	filename[i] = '\0';

	strcpy(dirname, filename);

	/* Create a new archive in memory. */
	assert((a = archive_write_new()) != NULL);
	assertA(0 == archive_write_set_format_ustar(a));
	assertA(0 == archive_write_add_filter_none(a));
	assertA(0 == archive_write_set_bytes_per_block(a,0));
	assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));

	/*
	 * Write a file to it.
	 */
	assert((ae = archive_entry_new()) != NULL);
	archive_entry_copy_pathname(ae, filename);
	archive_entry_set_mode(ae, S_IFREG | 0755);
	failure("dlen=%d, flen=%d", dlen, flen);
	if (flen > 100) {
		assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae));
	} else {
		assertEqualIntA(a, 0, archive_write_header(a, ae));
	}
	archive_entry_free(ae);

	/*
	 * Write a dir to it (without trailing '/').
	 */
	assert((ae = archive_entry_new()) != NULL);
	archive_entry_copy_pathname(ae, dirname);
	archive_entry_set_mode(ae, S_IFDIR | 0755);
	failure("dlen=%d, flen=%d", dlen, flen);
	if (flen >= 100) {
		assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae));
	} else {
		assertEqualIntA(a, 0, archive_write_header(a, ae));
	}
	archive_entry_free(ae);

	/* Tar adds a '/' to directory names. */
	strcat(dirname, "/");

	/*
	 * Write a dir to it (with trailing '/').
	 */
	assert((ae = archive_entry_new()) != NULL);
	archive_entry_copy_pathname(ae, dirname);
	archive_entry_set_mode(ae, S_IFDIR | 0755);
	failure("dlen=%d, flen=%d", dlen, flen);
	if (flen >= 100) {
		assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae));
	} else {
		assertEqualIntA(a, 0, archive_write_header(a, ae));
	}
	archive_entry_free(ae);

	/* Close out the archive. */
	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/*
	 * Now, read the data back.
	 */
	assert((a = archive_read_new()) != NULL);
	assertA(0 == archive_read_support_format_all(a));
	assertA(0 == archive_read_support_filter_all(a));
	assertA(0 == archive_read_open_memory(a, buff, used));

	if (flen <= 100) {
		/* Read the file and check the filename. */
		assertA(0 == archive_read_next_header(a, &ae));
		failure("dlen=%d, flen=%d", dlen, flen);
		assertEqualString(filename, archive_entry_pathname(ae));
		assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
	}

	/*
	 * Read the two dirs and check the names.
	 *
	 * Both dirs should read back with the same name, since
	 * tar should add a trailing '/' to any dir that doesn't
	 * already have one.
	 */
	if (flen <= 99) {
		assertA(0 == archive_read_next_header(a, &ae));
		assert((S_IFDIR | 0755) == archive_entry_mode(ae));
		failure("dlen=%d, flen=%d", dlen, flen);
		assertEqualString(dirname, archive_entry_pathname(ae));
	}

	if (flen <= 99) {
		assertA(0 == archive_read_next_header(a, &ae));
		assert((S_IFDIR | 0755) == archive_entry_mode(ae));
		assertEqualString(dirname, archive_entry_pathname(ae));
	}

	/* Verify the end of the archive. */
	failure("This fails if entries were written that should not have been written.  dlen=%d, flen=%d", dlen, flen);
	assertEqualInt(1, archive_read_next_header(a, &ae));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}