Пример #1
0
bool CgCompressCreator::create( const QString& path, int, int, QImage& img ){
	qCDebug(LOG) << "Trying to read image" << path;
	QFile file(path);
	if( !file.open( QIODevice::ReadOnly ) )
		return false;
	
	archive* a = archive_read_new();
	archive_read_support_format_zip(a);
	
	ReadingData data( file );
	if( archive_read_open( a, &data, nullptr, stream_read, stream_close ) )
		qCWarning(LOG) << "couldn't open:" << archive_error_string(a);
	else{
		QString name;
		while( !(name = next_file( a )).isNull() ){
			if( name.startsWith( "Thumbnails/thumbnail." ) || name.startsWith("thumb.") ){
				qCDebug(LOG) << "Found thumbnail!";
				QString suffix = QFileInfo(name).suffix();
				img = read_image( a, suffix.toLocal8Bit().constData() );
				break;
			}
		}
	}
	
	archive_read_close( a );
	archive_read_free( a );
	
	if( img.isNull() )
		qCWarning(LOG) << "No thumbnail found!";
	return !img.isNull();
}
Пример #2
0
/*
 * Verify that we skip junk between entries.  The compat_zip_2.zip file
 * has several bytes of junk between 'file1' and 'file2'.  Such
 * junk is routinely introduced by some Zip writers when they manipulate
 * existing zip archives.
 */
static void
test_compat_zip_2(void)
{
	char name[] = "test_compat_zip_2.zip";
	struct archive_entry *ae;
	struct archive *a;

	assert((a = archive_read_new()) != NULL);
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
	extract_reference_file(name);
	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));

	/* Read first entry. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("file1", archive_entry_pathname(ae));

	/* Read first entry. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("file2", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
Пример #3
0
struct mp_archive *mp_archive_new(struct mp_log *log, struct stream *src,
                                  int flags)
{
    struct mp_archive *mpa = talloc_zero(NULL, struct mp_archive);
    mpa->log = log;
    mpa->locale = newlocale(LC_ALL_MASK, "C.UTF-8", (locale_t)0);
    if (!mpa->locale)
        goto err;
    mpa->arch = archive_read_new();
    mpa->primary_src = src;
    if (!mpa->arch)
        goto err;

    // first volume is the primary streame
    if (!add_volume(log ,mpa, src, src->url))
        goto err;

    // try to open other volumes
    char** volumes = find_volumes(src);
    for (int i = 0; volumes[i]; i++) {
        if (!add_volume(log, mpa, NULL, volumes[i])) {
            talloc_free(volumes);
            goto err;
        }
    }
    talloc_free(volumes);

    locale_t oldlocale = uselocale(mpa->locale);

    archive_read_support_format_7zip(mpa->arch);
    archive_read_support_format_iso9660(mpa->arch);
    archive_read_support_format_rar(mpa->arch);
    archive_read_support_format_zip(mpa->arch);
    archive_read_support_filter_bzip2(mpa->arch);
    archive_read_support_filter_gzip(mpa->arch);
    archive_read_support_filter_xz(mpa->arch);
    if (flags & MP_ARCHIVE_FLAG_UNSAFE) {
        archive_read_support_format_gnutar(mpa->arch);
        archive_read_support_format_tar(mpa->arch);
    }

    archive_read_set_read_callback(mpa->arch, read_cb);
    archive_read_set_skip_callback(mpa->arch, skip_cb);
    archive_read_set_switch_callback(mpa->arch, switch_cb);
    archive_read_set_open_callback(mpa->arch, open_cb);
    archive_read_set_close_callback(mpa->arch, close_cb);
    if (mpa->primary_src->seekable)
        archive_read_set_seek_callback(mpa->arch, seek_cb);
    bool fail = archive_read_open1(mpa->arch) < ARCHIVE_OK;

    uselocale(oldlocale);

    if (fail)
        goto err;
    return mpa;

err:
    mp_archive_free(mpa);
    return NULL;
}
Пример #4
0
/*
 * Read a zip file that has a zip comment in the end of the central
 * directory record.
 */
static void
verify(const char *refname)
{
	char *p;
	size_t s;
	struct archive *a;
	struct archive_entry *ae;

	extract_reference_file(refname);
	p = slurpfile(&s, refname);

	/* Symlinks can only be extracted with the seeking reader. */
	assert((a = archive_read_new()) != NULL);
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
	assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("file0", archive_entry_pathname(ae));
	assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("build.sh", archive_entry_pathname(ae));
	assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
	assertEqualInt(23, archive_entry_size(ae));

	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
}
static void
test_symlink(void)
{
	const char *refname = "test_read_format_zip_symlink.zip";
	char *p;
	size_t s;
	struct archive *a;
	struct archive_entry *ae;

	extract_reference_file(refname);
	p = slurpfile(&s, refname);

	/* Symlinks can only be extracted with the seeking reader. */
	assert((a = archive_read_new()) != NULL);
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
	assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("file", archive_entry_pathname(ae));
	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
	assertEqualInt(archive_entry_is_encrypted(ae), 0);
	assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("symlink", archive_entry_pathname(ae));
	assertEqualInt(AE_IFLNK, archive_entry_filetype(ae));
	assertEqualInt(0, archive_entry_size(ae));
	assertEqualString("file", archive_entry_symlink(ae));
	assertEqualInt(archive_entry_is_encrypted(ae), 0);
	assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);

	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
}
Пример #6
0
//********************************************************************************************************
void list_archive(const char* const infile) {
  // Adapted from:
  // https://github.com/libarchive/libarchive/wiki/Examples#List_contents_of_Archive_stored_in_File
  // Note - this function will always be "chatty"; make sure to flush the stdout before using it...
  // TODO: Write a function which *returns* the list of files
  //       (by writing it into a char** supplied by the caller)

  fprintf(stderr, "Opening archive '%s' for listing...\n",infile);

  struct archive* a = archive_read_new();
  archive_read_support_format_zip(a);
  int err = archive_read_open_filename(a, infile,10240);//Note: Blocksize isn't neccessarilly adhered to
  if (err != ARCHIVE_OK) {
    fprintf(stderr, "CRITICAL ERROR in list_archive(): When opening archive '%s', err=%i\n",infile,err);
    fprintf(stderr, "CRITICAL ERROR in list_archive(): %s\n",archive_error_string(a));
    exit(EXIT_FAILURE);
  }

  struct archive_entry* entry;
  while (archive_read_next_header(a,&entry)==ARCHIVE_OK){
    printf("Found file: '%s'\n",archive_entry_pathname(entry));
    archive_read_data_skip(a);
  }

  archive_read_close(a);
  err = archive_read_free(a);
  if (err != ARCHIVE_OK){
    fprintf(stderr, "CRITICAL ERROR in list_archive(): Error when calling archive_read_free(), '%s', err=%i\n",infile,err);
    fprintf(stderr, "CRITICAL ERROR in list_archive(): %s\n",archive_error_string(a));
    exit(EXIT_FAILURE);
  }
}
Пример #7
0
/*
 * Issue 226: Try to reproduce hang when reading archives where the
 * length-at-end marker ends exactly on a block boundary.
 */
static void
test_compat_zip_7(void)
{
	const char *refname = "test_compat_zip_7.xps";
	struct archive *a;
	struct archive_entry *ae;
	void *p;
	size_t s;
	int i;

	extract_reference_file(refname);
	p = slurpfile(&s, refname);

	for (i = 1; i < 1000; ++i) {
		assert((a = archive_read_new()) != NULL);
		assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
		assertEqualIntA(a, ARCHIVE_OK, read_open_memory_minimal(a, p, s, i));

		assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
		assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
		assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
		assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
		assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
		assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));
		assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
		assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));

		assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
	}
	free(p);
}
static char *
file_get_zipped_contents (const char   *filename,
			  GCompareFunc  func,
			  gpointer      user_data,
			  gsize        *length)
{
	struct archive *a;
	struct archive_entry *entry;
	char *ret = NULL;
	int r;

	*length = 0;

	a = archive_read_new ();
	archive_read_support_format_zip (a);
	r = archive_read_open_filename (a, filename, 10240);
	if (r != ARCHIVE_OK) {
		g_print ("Failed to open archive %s\n", filename);
		return NULL;
	}

	while (1) {
		const char *name;

		r = archive_read_next_header(a, &entry);

		if (r != ARCHIVE_OK) {
			if (r != ARCHIVE_EOF && r == ARCHIVE_FATAL)
				g_warning ("Fatal error handling archive: %s", archive_error_string (a));
			break;
		}

		name = archive_entry_pathname (entry);
		if (func (name, user_data) == 0) {
			size_t size = archive_entry_size (entry);
			char *buf;
			ssize_t read;

			buf = g_malloc (size);
			read = archive_read_data (a, buf, size);
			if (read <= 0) {
				g_free (buf);
				if (read < 0)
					g_warning ("Fatal error reading '%s' in archive: %s", name, archive_error_string (a));
				else
					g_warning ("Read an empty file from the archive");
			} else {
				ret = buf;
				*length = size;
			}
			break;
		}
		archive_read_data_skip(a);
	}
	archive_read_free(a);

	return ret;
}
Пример #9
0
int
archive_read_support_format_all(struct archive *a)
{
	archive_check_magic(a, ARCHIVE_READ_MAGIC,
	    ARCHIVE_STATE_NEW, "archive_read_support_format_all");

	/* TODO: It would be nice to compute the ordering
	 * here automatically so that people who enable just
	 * a few formats can still get the benefits.  That
	 * may just require the format registration to include
	 * a "maximum read-ahead" value (anything that uses seek
	 * would be essentially infinite read-ahead).  The core
	 * bid management can then sort the bidders before calling
	 * them.
	 *
	 * If you implement the above, please return the list below
	 * to alphabetic order.
	 */

	/*
	 * These bidders are all pretty cheap; they just examine a
	 * small initial part of the archive.  If one of these bids
	 * high, we can maybe avoid running any of the more expensive
	 * bidders below.
	 */
	archive_read_support_format_ar(a);
	archive_read_support_format_cpio(a);
	archive_read_support_format_empty(a);
	archive_read_support_format_lha(a);
	archive_read_support_format_mtree(a);
	archive_read_support_format_tar(a);
	archive_read_support_format_xar(a);

	/*
	 * Install expensive bidders last.  By doing them last, we
	 * increase the chance that a high bid from someone else will
	 * make it unnecessary for these to do anything at all.
	 */
	/* These three have potentially large look-ahead. */
	archive_read_support_format_7zip(a);
	archive_read_support_format_cab(a);
	archive_read_support_format_rar(a);
	archive_read_support_format_iso9660(a);
	/* Seek is really bad, since it forces the read-ahead
	 * logic to discard buffered data. */
	archive_read_support_format_zip(a);

	/* Note: We always return ARCHIVE_OK here, even if some of the
	 * above return ARCHIVE_WARN.  The intent here is to enable
	 * "as much as possible."  Clients who need specific
	 * compression should enable those individually so they can
	 * verify the level of support. */
	/* Clear any warning messages set by the above functions. */
	archive_clear_error(a);
	return (ARCHIVE_OK);
}
Пример #10
0
void load_examples(const void *data, size_t len, example_list_t *examples)
{
	example_patch_t *patch;
	struct archive *arch;
	struct archive_entry *ent;
	const char *path;
	FILE *fp;
	char *buf;
	size_t size;
	char block[4096];
	ssize_t count;
	int ret;

	assert(data != NULL);
	arch = archive_read_new();
	assert(arch != NULL);
	if (archive_read_support_format_zip(arch))
		abort();
	if (archive_read_open_memory(arch, (void *) data, len))
		abort();
	while (!(ret = archive_read_next_header(arch, &ent))) {
		if (!S_ISREG(archive_entry_filetype(ent)))
			continue;
		path = archive_entry_pathname(ent);
		if (strncmp(path, EXAMPLE_DIR "/", strlen(EXAMPLE_DIR) + 1))
			continue;
		/* archive_entry_size() is not reliable for Zip files */
		fp = open_memstream(&buf, &size);
		if (fp == NULL)
			abort();
		while ((count = archive_read_data(arch, block,
					sizeof(block))) > 0)
			if (fwrite(block, 1, count, fp) != (size_t) count)
				abort();
		if (count < 0) {
			fprintf(stderr, "%s\n", archive_error_string(arch));
			abort();
		}
		fclose(fp);
		patch = malloc(sizeof(*patch));
		patch->image = read_rgb_image(buf, size);
		if (patch->image == NULL) {
			fprintf(stderr, "Couldn't decode example %s\n", path);
			abort();
		}
		TAILQ_INSERT_TAIL(examples, patch, link);
		free(buf);
	}
	assert(ret == ARCHIVE_EOF);
	if (archive_read_finish(arch))
		abort();
}
int
archive_read_support_format_all(struct archive *a)
{
	archive_read_support_format_ar(a);
	archive_read_support_format_cpio(a);
	archive_read_support_format_empty(a);
	archive_read_support_format_iso9660(a);
	archive_read_support_format_mtree(a);
	archive_read_support_format_tar(a);
	archive_read_support_format_xar(a);
	archive_read_support_format_zip(a);
	return (ARCHIVE_OK);
}
Пример #12
0
int dbp_meta_package_open(const char *path, struct DBPMetaPackage *mp) {
	struct archive *a;
	struct archive_entry *ae;
	int errid, found, size;
	char *data;
	struct stat statbuf;

	mp->df = NULL;

	if (!(a = archive_read_new()))
		return DBP_ERROR_NO_MEMORY;
	archive_read_support_format_zip(a);
	if (archive_read_open_filename(a, path, 512) != ARCHIVE_OK) {
		errid = (stat(path, &statbuf) || S_ISREG(statbuf.st_mode)) ? DBP_ERROR_NO_PKG_ACCESS : DBP_ERROR_BAD_META;
		goto error;
	}

	for (found = 0; archive_read_next_header(a, &ae) == ARCHIVE_OK; )
		if (!strcmp("meta/default.desktop", archive_entry_pathname(ae))) {
			found = 1;
			break;
		}
	
	if (!found) {
		errid = DBP_ERROR_NO_DEFAULTD;
		goto error;
	}

	size = archive_entry_size(ae);
	if (!(data = malloc(size + 1))) {
		errid = DBP_ERROR_NO_MEMORY;
		goto error;
	}

	archive_read_data(a, data, size);
	data[size] = 0;

	mp->df = dbp_desktop_parse(data);
	free(data);
	archive_read_free(a);

	mp->section = "Package Entry";
	return 0;

	error:

	archive_read_free(a);
	return errid;
	
}
Пример #13
0
void list_archive_get(const char* const infile, char** filenames, int* nfiles, const int buffsize) {
  //printf("In list_archive_get\n");
  //fflush(stdout);

  struct archive* a = archive_read_new();
  archive_read_support_format_zip(a);
  int err = archive_read_open_filename(a, infile,10240);//Note: Blocksize isn't neccessarilly adhered to
  if (err != ARCHIVE_OK) {
    fprintf(stderr, "CRITICAL ERROR in list_archive_get(): When opening archive '%s', err=%i\n",infile,err);
    fprintf(stderr, "CRITICAL ERROR in list_archive_get(): %s\n",archive_error_string(a));
    exit(EXIT_FAILURE);
  }

  const int nfiles_max = *nfiles;
  *nfiles = 0;

  struct archive_entry* entry;
  while (archive_read_next_header(a,&entry)==ARCHIVE_OK){
    //printf("Found file: '%s'\n",archive_entry_pathname(entry));
    //fflush(stdout);
    int buff_used = 0;
    buff_used = snprintf(filenames[*nfiles],buffsize,"%s",archive_entry_pathname(entry));
    if (buff_used >= buffsize) {
      fprintf(stderr, "CRITICAL ERROR in list_archive_get(): When reading file '%s' from archive '%s':\n",filenames[*nfiles],infile);
      fprintf(stderr, "CRITICAL ERROR in list_archive_get(): Buffer too small by %i characters\n",buff_used-buffsize+1);
      exit(EXIT_FAILURE);
    }
    else if (buff_used < 0) {
      fprintf(stderr, "CRITICAL ERROR in list_archive_get(): When reading file '%s' from archive '%s':\n",filenames[*nfiles],infile);
      fprintf(stderr, "CRITICAL ERROR in list_archive_get(): Error in snprintf.\n");
      exit(EXIT_FAILURE);
    }

    archive_read_data_skip(a);

    if(++(*nfiles) >= nfiles_max) {
      fprintf(stderr, "CRITICAL ERROR in list_archive_get(): Number of files greater than nfiles_max=%i",nfiles_max);
      exit(EXIT_FAILURE);
    }
  }

  archive_read_close(a);
  err = archive_read_free(a);
  if (err != ARCHIVE_OK){
    fprintf(stderr, "CRITICAL ERROR in list_archive_get(): Error when calling archive_read_free(), '%s', err=%i\n",infile,err);
    fprintf(stderr, "CRITICAL ERROR in list_archive_get(): %s\n",archive_error_string(a));
    exit(EXIT_FAILURE);
  }
}
Пример #14
0
static bool set_up_input(archive *in, const std::string &filename)
{
    // Add more as needed
    //archive_read_support_format_all(in);
    //archive_read_support_filter_all(in);
    //archive_read_support_format_tar(in);
    archive_read_support_format_zip(in);
    //archive_read_support_filter_xz(in);

    if (archive_read_open_filename(in, filename.c_str(), 10240) != ARCHIVE_OK) {
        LOGE("%s: Failed to open archive: %s",
             filename.c_str(), archive_error_string(in));
        return false;
    }

    return true;
}
Пример #15
0
/* Copy this function for each test file and adjust it accordingly. */
static void
test_compat_zip_1(void)
{
	char name[] = "test_compat_zip_1.zip";
	struct archive_entry *ae;
	struct archive *a;
	int r;

	assert((a = archive_read_new()) != NULL);
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
	extract_reference_file(name);
	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));

	/* Read first entry. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("META-INF/MANIFEST.MF", archive_entry_pathname(ae));

	/* Read second entry. */
	r = archive_read_next_header(a, &ae);
	if (r != ARCHIVE_OK) {
		if (strcmp(archive_error_string(a),
		    "libarchive compiled without deflate support (no libz)") == 0) {
			skipping("Skipping ZIP compression check: %s",
			    archive_error_string(a));
			goto finish;
		}
	}
	assertEqualIntA(a, ARCHIVE_OK, r);
	assertEqualString("tmp.class", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));

	assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_NONE);
	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ZIP);

	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
finish:
#if ARCHIVE_VERSION_NUMBER < 2000000
	archive_read_finish(a);
#else
	assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
#endif
}
Пример #16
0
static struct archive *file_type_archive_gen_archive(GBytes *data) {/*{{{*/
	struct archive *archive = archive_read_new();
	archive_read_support_format_zip(archive);
	archive_read_support_format_rar(archive);
	archive_read_support_format_7zip(archive);
	archive_read_support_format_tar(archive);
	archive_read_support_filter_all(archive);

	gsize data_size;
	char *data_ptr = (char *)g_bytes_get_data(data, &data_size);

	if(archive_read_open_memory(archive, data_ptr, data_size) != ARCHIVE_OK) {
		g_printerr("Failed to load archive: %s\n", archive_error_string(archive));
		archive_read_free(archive);
		return NULL;
	}

	return archive;
}/*}}}*/
int
archive_read_support_format_by_code(struct archive *a, int format_code)
{
	archive_check_magic(a, ARCHIVE_READ_MAGIC,
	    ARCHIVE_STATE_NEW, "archive_read_support_format_by_code");

	switch (format_code & ARCHIVE_FORMAT_BASE_MASK) {
	case ARCHIVE_FORMAT_7ZIP:
		return archive_read_support_format_7zip(a);
		break;
	case ARCHIVE_FORMAT_AR:
		return archive_read_support_format_ar(a);
		break;
	case ARCHIVE_FORMAT_CAB:
		return archive_read_support_format_cab(a);
		break;
	case ARCHIVE_FORMAT_CPIO:
		return archive_read_support_format_cpio(a);
		break;
	case ARCHIVE_FORMAT_ISO9660:
		return archive_read_support_format_iso9660(a);
		break;
	case ARCHIVE_FORMAT_LHA:
		return archive_read_support_format_lha(a);
		break;
	case ARCHIVE_FORMAT_MTREE:
		return archive_read_support_format_mtree(a);
		break;
	case ARCHIVE_FORMAT_RAR:
		return archive_read_support_format_rar(a);
		break;
	case ARCHIVE_FORMAT_TAR:
		return archive_read_support_format_tar(a);
		break;
	case ARCHIVE_FORMAT_XAR:
		return archive_read_support_format_xar(a);
		break;
	case ARCHIVE_FORMAT_ZIP:
		return archive_read_support_format_zip(a);
		break;
	}
	return (ARCHIVE_FATAL);
}
Пример #18
0
/* Copy this function for each test file and adjust it accordingly. */
static void
test_compat_zip_1(void)
{
	char name[] = "test_compat_zip_1.zip";
	struct archive_entry *ae;
	struct archive *a;
	int r;

	assert((a = archive_read_new()) != NULL);
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
	extract_reference_file(name);
	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 10240));

	/* Read first entry. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("META-INF/MANIFEST.MF", archive_entry_pathname(ae));

	/* Read second entry. */
	r = archive_read_next_header(a, &ae);
	if (r == ARCHIVE_FATAL && !libz_enabled) {
		skipping("Skipping ZIP compression check: %s",
			archive_error_string(a));
		goto finish;
	}
	assertEqualIntA(a, ARCHIVE_OK, r);
	assertEqualString("tmp.class", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));

	assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ZIP);

finish:
	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
Пример #19
0
/**
 * @brief Verify that the firmware archive is ok
 * @param input_filename the firmware update filename
 * @param public_keys the public keys if authentication check
 * @return 0 if successful
 */
int fwup_verify(const char *input_filename, unsigned char * const *public_keys)
{
    unsigned char *meta_conf_signature = NULL;
    struct resource_list *all_resources = NULL;
    cfg_t *cfg = NULL;
    int rc = 0;

    struct archive *a = archive_read_new();
    archive_read_support_format_zip(a);

    if (!input_filename)
        ERR_CLEANUP_MSG("Specify an input firmware file");

    rc = fwup_archive_open_filename(a, input_filename);
    if (rc != ARCHIVE_OK)
        ERR_CLEANUP_MSG("%s", archive_error_string(a));

    struct archive_entry *ae;
    rc = archive_read_next_header(a, &ae);
    if (rc != ARCHIVE_OK)
        ERR_CLEANUP_MSG("%s", archive_error_string(a));

    if (strcmp(archive_entry_pathname(ae), "meta.conf.ed25519") == 0) {
        off_t total_size;
        if (archive_read_all_data(a, ae, (char **) &meta_conf_signature, crypto_sign_BYTES, &total_size) < 0)
            ERR_CLEANUP_MSG("Error reading meta.conf.ed25519 from archive.\n"
                            "Check for file corruption or libarchive built without zlib support");

        if (total_size != crypto_sign_BYTES)
            ERR_CLEANUP_MSG("Unexpected meta.conf.ed25519 size: %d", total_size);

        rc = archive_read_next_header(a, &ae);
        if (rc != ARCHIVE_OK)
            ERR_CLEANUP_MSG("Expecting more than meta.conf.ed25519 in archive");
    }
    if (strcmp(archive_entry_pathname(ae), "meta.conf") != 0)
        ERR_CLEANUP_MSG("Expecting meta.conf to be at the beginning of %s", input_filename);

    OK_OR_CLEANUP(cfgfile_parse_fw_ae(a, ae, &cfg, meta_conf_signature, public_keys));

    OK_OR_CLEANUP(rlist_get_all(cfg, &all_resources));

    while (archive_read_next_header(a, &ae) == ARCHIVE_OK) {
        const char *filename = archive_entry_pathname(ae);
        char resource_name[FWFILE_MAX_ARCHIVE_PATH];

        OK_OR_CLEANUP(archive_filename_to_resource(filename, resource_name, sizeof(resource_name)));
        OK_OR_CLEANUP(check_resource(all_resources, resource_name, a, ae));
    }

    // Check that all resources have been validated
    for (struct resource_list *r = all_resources; r != NULL; r = r->next) {
        if (!r->processed)
            ERR_CLEANUP_MSG("Resource %s not found in archive", cfg_title(r->resource));
    }

    const char *success_message;
    if (*public_keys && meta_conf_signature)
        success_message = "Valid archive with a good signature\n";
    else if (!*public_keys && meta_conf_signature)
        success_message = "Valid archive with an unverified signature. Specify a public key to authenticate.\n";
    else
        success_message = "Valid archive without a signature\n";

    fwup_output(FRAMING_TYPE_SUCCESS, 0, success_message);

cleanup:
    rlist_free(all_resources);
    archive_read_close(a);
    archive_read_free(a);

    if (meta_conf_signature)
        free(meta_conf_signature);

    if (cfg)
        cfgfile_free(cfg);

    return rc;
}
Пример #20
0
//********************************************************************************************************
void read_archive(const char* const infile, const char* const extractFolder){
  // Strongly inspired by
  // https://github.com/libarchive/libarchive/wiki/Examples#A_Complete_Extractor

  //printf("Opening archive '%s' for extracting to folder '%s'...\n",infile,extractFolder);

  //Check that the archive exists

  //Check that the folder exists, if not then create it

  struct archive* a = archive_read_new();
  archive_read_support_format_zip(a);
  struct archive* ext = archive_write_disk_new();
  archive_write_disk_set_options(ext,ARCHIVE_EXTRACT_TIME|ARCHIVE_EXTRACT_PERM|ARCHIVE_EXTRACT_ACL|ARCHIVE_EXTRACT_FFLAGS);
  archive_write_disk_set_standard_lookup(ext);

  int err;
  err = archive_read_open_filename(a, infile, 10240);
  if (err != ARCHIVE_OK) {
    fprintf(stderr, "CRITICAL ERROR in read_archive(): When opening archive '%s', err=%i\n",infile,err);
    fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a));
    exit(EXIT_FAILURE);
  }

  struct archive_entry *entry;

  const int fcount_max = 1000;
  char fcompleted=0; //C-Boolean
  for(int fcount=0; fcount<fcount_max;fcount++){
    err = archive_read_next_header(a,&entry);
    if (err == ARCHIVE_EOF){
      fcompleted=1;
      break;
    }
    else if (err != ARCHIVE_OK){
      fprintf(stderr, "CRITICAL ERROR in read_archive(): When reading archive, err=%i\n",err);
      fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a));
      exit(EXIT_FAILURE);
    }
    //printf("Found file: '%s'\n",archive_entry_pathname(entry));

    //Avoid clobbering files in current directory - solution from
    // http://stackoverflow.com/questions/4496001/libarchive-to-extract-to-a-specified-folder
    char newPath[PATH_MAX];
    int buff_used = snprintf(newPath, PATH_MAX, "%s/%s",extractFolder,archive_entry_pathname(entry));
    if (buff_used >= PATH_MAX || buff_used < 0){
      fprintf(stderr, "CRITICAL ERROR in read_archive(): Buffer overflow or other error when creating the path.\n");
      fprintf(stderr, "CRITICAL ERROR in read_archive(): buff_used=%i\n",buff_used);
      exit(EXIT_FAILURE);
    }
    archive_entry_set_pathname(entry,newPath);

    err = archive_write_header(ext, entry);
    if (err != ARCHIVE_OK){
      fprintf(stderr, "CRITICAL ERROR in read_archive(): when extracting archive (creating new file), err=%i\n",err);
      fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(ext));
      exit(EXIT_FAILURE);
    }

    //Write the data!
    const void* buff;
    size_t size;
    la_int64_t offset;

    const int bcount_max = 100000000;
    char bcompleted = 0; //C boolean
    for (int bcount=0; bcount<bcount_max;bcount++){
      err = archive_read_data_block(a,&buff,&size, &offset);
      if ( err == ARCHIVE_EOF ) {
	bcompleted=1;
	break;
      }
      else if (err != ARCHIVE_OK){
	fprintf(stderr, "CRITICAL ERROR in read_archive(): When extracting archive (reading data), err=%i\n",err);
	fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a));
	exit(EXIT_FAILURE);
      }

      err = archive_write_data_block(ext,buff,size,offset);
      if (err != ARCHIVE_OK){
	fprintf(stderr, "CRITICAL ERROR in read_archive(): When extracting archive (writing data), err=%i\n",err);
	fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a));
	exit(EXIT_FAILURE);
      }
    }
    if (!bcompleted){
      fprintf(stderr, "CRITICAL ERROR in read_archive(): The file writing block loop was aborted by the infinite loop guard\n");
      exit(EXIT_FAILURE);
    }

    err=archive_write_finish_entry(ext);
    if (err != ARCHIVE_OK) {
      fprintf(stderr, "CRITICAL ERROR in read_archive(): When extracting archive (closing new file), err=%i\n",err);
      fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(ext));
      exit(EXIT_FAILURE);
    }
  }

  archive_read_close(a);
  err=archive_read_free(a);
  if (err != ARCHIVE_OK){
    fprintf(stderr, "CRITICAL ERROR in read_archive(): When calling archive_read_free(a), err=%i\n",err);
    fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a));
    exit(EXIT_FAILURE);
  }
  archive_write_close(ext);
  err = archive_write_free(ext);
  if (err != ARCHIVE_OK){
    fprintf(stderr, "CRITICAL ERROR in read_archive(): When calling archive_read_free(ext), err=%i\n",err);
    fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a));
    exit(EXIT_FAILURE);
  }

  if (!fcompleted) {
    fprintf(stderr, "CRITICAL ERROR in read_archive(): The file header loop was aborted by the infinite loop guard\n");
    exit(EXIT_FAILURE);
  }
}
Пример #21
0
static bool extract_theme(const std::string &path, const std::string &target,
                          const std::string &theme_name)
{
    mb::autoclose::archive in(archive_read_new(), archive_read_free);
    if (!in) {
        LOGE("%s: Out of memory when creating archive reader", __FUNCTION__);
        return false;
    }
    mb::autoclose::archive out(archive_write_disk_new(), archive_write_free);
    if (!out) {
        LOGE("%s: Out of memory when creating disk writer", __FUNCTION__);
        return false;
    }

    archive_read_support_format_zip(in.get());

    // Set up disk writer parameters. We purposely don't extract any file
    // metadata
    int flags = ARCHIVE_EXTRACT_SECURE_SYMLINKS
            | ARCHIVE_EXTRACT_SECURE_NODOTDOT;

    archive_write_disk_set_standard_lookup(out.get());
    archive_write_disk_set_options(out.get(), flags);

    if (archive_read_open_filename(in.get(), path.c_str(), 10240) != ARCHIVE_OK) {
        LOGE("%s: Failed to open file: %s",
             path.c_str(), archive_error_string(in.get()));
        return false;
    }

    archive_entry *entry;
    int ret;
    std::string target_path;

    std::string common_prefix("theme/common/");
    std::string theme_prefix("theme/");
    theme_prefix += theme_name;
    theme_prefix += '/';

    while (true) {
        ret = archive_read_next_header(in.get(), &entry);
        if (ret == ARCHIVE_EOF) {
            break;
        } else if (ret == ARCHIVE_RETRY) {
            LOGW("%s: Retrying header read", path.c_str());
            continue;
        } else if (ret != ARCHIVE_OK) {
            LOGE("%s: Failed to read header: %s",
                 path.c_str(), archive_error_string(in.get()));
            return false;
        }

        const char *path = archive_entry_pathname(entry);
        if (!path || !*path) {
            LOGE("%s: Header has null or empty filename", path);
            return false;
        }

        const char *suffix;

        if (mb::util::starts_with(path, common_prefix)) {
            suffix = path + common_prefix.size();
        } else if (mb::util::starts_with(path, theme_prefix)) {
            suffix = path + theme_prefix.size();
        } else {
            LOGV("Skipping: %s", path);
            continue;
        }

        // Build path
        target_path = target;
        if (target_path.back() != '/' && *suffix != '/') {
            target_path += '/';
        }
        target_path += suffix;

        LOGV("Extracting: %s -> %s", path, target_path.c_str());

        archive_entry_set_pathname(entry, target_path.c_str());

        // Extract file
        ret = archive_read_extract2(in.get(), entry, out.get());
        if (ret != ARCHIVE_OK) {
            LOGE("%s: %s", archive_entry_pathname(entry),
                 archive_error_string(in.get()));
            return false;
        }
    }

    if (archive_read_close(in.get()) != ARCHIVE_OK) {
        LOGE("%s: Failed to close file: %s",
             path.c_str(), archive_error_string(in.get()));
        return false;
    }

    return true;
}
Пример #22
0
/*
 * Main loop: open the zipfile, iterate over its contents and decide what
 * to do with each entry.
 */
static void
unzip(const char *fn)
{
	struct archive *a;
	struct archive_entry *e;
	int ret;
	uintmax_t total_size, file_count, error_count;

	if ((a = archive_read_new()) == NULL)
		error("archive_read_new failed");

	ac(archive_read_support_format_zip(a));
	ac(archive_read_open_filename(a, fn, 8192));

	if (!zipinfo_mode) {
		if (!p_opt && !q_opt)
			printf("Archive:  %s\n", fn);
		if (v_opt == 1) {
			printf("  Length     Date   Time    Name\n");
			printf(" --------    ----   ----    ----\n");
		} else if (v_opt == 2) {
			printf(" Length   Method    Size  Ratio   Date   Time   CRC-32    Name\n");
			printf("--------  ------  ------- -----   ----   ----   ------    ----\n");
		}
	}

	total_size = 0;
	file_count = 0;
	error_count = 0;
	for (;;) {
		ret = archive_read_next_header(a, &e);
		if (ret == ARCHIVE_EOF)
			break;
		ac(ret);
		if (!zipinfo_mode) {
			if (t_opt)
				error_count += test(a, e);
			else if (v_opt)
				list(a, e);
			else if (p_opt || c_opt)
				extract_stdout(a, e);
			else
				extract(a, e);
		} else {
			if (Z1_opt)
				list(a, e);
		}

		total_size += archive_entry_size(e);
		++file_count;
	}

	if (zipinfo_mode) {
		if (v_opt == 1) {
			printf(" --------                   -------\n");
			printf(" %8ju                   %ju file%s\n",
			    total_size, file_count, file_count != 1 ? "s" : "");
		} else if (v_opt == 2) {
			printf("--------          -------  ---                            -------\n");
			printf("%8ju          %7ju   0%%                            %ju file%s\n",
			    total_size, total_size, file_count,
			    file_count != 1 ? "s" : "");
		}
	}

	ac(archive_read_close(a));
	(void)archive_read_free(a);

	if (t_opt) {
		if (error_count > 0) {
			errorx("%d checksum error(s) found.", error_count);
		}
		else {
			printf("No errors detected in compressed data of %s.\n",
			       fn);
		}
	}
}
Пример #23
0
bool extract_archive(const char *filename, const char *target)
{
    struct archive *in = NULL;
    struct archive *out = NULL;
    struct archive_entry *entry;
    int ret;
    char *cwd = NULL;

    if (!(in = archive_read_new())) {
        LOGE("Out of memory");
        goto error;
    }

    // Add more as needed
    //archive_read_support_format_all(in);
    //archive_read_support_filter_all(in);
    archive_read_support_format_tar(in);
    archive_read_support_format_zip(in);
    archive_read_support_filter_xz(in);

    if (archive_read_open_filename(in, filename, 10240) != ARCHIVE_OK) {
        LOGE("%s: Failed to open archive: %s", filename, archive_error_string(in));
        goto error;
    }

    if (!(out = archive_write_disk_new())) {
        LOGE("Out of memory");
        goto error;
    }

    archive_write_disk_set_options(out,
                                   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);

    if (!(cwd = getcwd(NULL, 0))) {
        LOGE("Failed to get cwd: %s", strerror(errno));
        goto error;
    }

    if (chdir(target) < 0) {
        LOGE("%s: Failed to change to target directory: %s",
             target, strerror(errno));
        goto error;
    }

    while ((ret = archive_read_next_header(in, &entry)) == ARCHIVE_OK) {
        if ((ret = archive_write_header(out, entry)) != ARCHIVE_OK) {
            LOGE("Failed to write header: %s", archive_error_string(out));
            goto error;
        }

        const void *buff;
        size_t size;
        int64_t offset;
        int ret;

        while ((ret = archive_read_data_block(
                in, &buff, &size, &offset)) == ARCHIVE_OK) {
            if (archive_write_data_block(out, buff, size, offset) != ARCHIVE_OK) {
                LOGE("Failed to write data: %s", archive_error_string(out));
                goto error;
            }
        }

        if (ret != ARCHIVE_EOF) {
            LOGE("Data copy ended without reaching EOF: %s",
                 archive_error_string(in));
            goto error;
        }
    }

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

    chdir(cwd);

    archive_read_free(in);
    archive_write_free(out);

    return true;

error:
    if (cwd) {
        chdir(cwd);
    }

    archive_read_free(in);
    archive_write_free(out);

    return false;
}
Пример #24
0
static Eina_Bool
_etui_epub_file_unzip(Etui_Provider_Data *pd)
{
    struct archive *a;
    struct archive_entry *entry;
    int r;

    if (!eina_file_mkdtemp("etui-epub-tmp-XXXXXX", &pd->doc.path))
        return EINA_FALSE;

    a = archive_read_new();
    if (!a)
        goto free_path;

    if (archive_read_support_filter_all(a) != ARCHIVE_OK)
        goto free_path;

    if (archive_read_support_format_zip(a) != ARCHIVE_OK)
        goto free_path;

    r = archive_read_open_filename(a, pd->doc.filename, 16384);
    if (r != ARCHIVE_OK)
        goto free_path;

    while (archive_read_next_header(a, &entry) == ARCHIVE_OK)
    {
        if (archive_entry_filetype(entry) == AE_IFREG)
        {
            char buf[PATH_MAX];
            const char *name;
            char *dir;
            char *base;
            size_t size;
            void *data;

            name = archive_entry_pathname(entry);
            dir = strdup(name);
            base = strdup(name);
            if (dir && base && (strcmp(dir, ".") != 0))
            {
                snprintf(buf, sizeof(buf), "%s/%s", pd->doc.path, dirname(dir));
                buf[sizeof(buf) - 1] = '\0';
                ecore_file_mkdir(buf);
                printf(" * %s %s %s\n", name, dirname(dir), basename(base));
            }

            if (base)
                free(base);
            if (dir)
                free(dir);

            size = archive_entry_size(entry);
            data = malloc(size);
            if (data)
            {
                size_t res;

                res = archive_read_data(a, data, size);
                if (res > 0)
                {
                    FILE *f;

                    snprintf(buf, sizeof(buf), "%s/%s", pd->doc.path, name);
                    buf[sizeof(buf) - 1] = '\0';
                    printf(" $ %s\n", buf);
                    f = fopen(buf, "wb");
                    if (f)
                    {
                        fwrite(data, 1, size, f);
                        fclose(f);
                    }
                }

                free(data);
            }
        }
        archive_read_data_skip(a);
    }

    archive_read_free(a);

    return EINA_TRUE;

  free_path:
    eina_tmpstr_del(pd->doc.path);

    return EINA_FALSE;
}