Example #1
0
/* Helper function to copy data between archives. */
static int
copy_file_data(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
{
	ssize_t	bytes_read;
	ssize_t	bytes_written;
	off_t	progress = 0;

	bytes_read = archive_read_data(ina, bsdtar->buff, FILEDATABUFLEN);
	while (bytes_read > 0) {
		disk_pause(bsdtar);
		if (network_select(0))
			return (-1);

		siginfo_printinfo(bsdtar, progress);

		bytes_written = archive_write_data(a, bsdtar->buff,
		    bytes_read);
		if (bytes_written < bytes_read) {
			bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a));
			return (-1);
		}

		if (truncate_archive(bsdtar))
			break;
		if (checkpoint_archive(bsdtar, 1))
			return (-1);

		progress += bytes_written;
		bytes_read = archive_read_data(ina, bsdtar->buff,
		    FILEDATABUFLEN);
	}

	return (0);
}
Example #2
0
/* Helper function to copy data between archives. */
static int
copy_file_data(struct bsdtar *bsdtar, struct archive *a,
    struct archive *ina, struct archive_entry *entry)
{
	ssize_t	bytes_read;
	ssize_t	bytes_written;
	int64_t	progress = 0;

	bytes_read = archive_read_data(ina, bsdtar->buff, bsdtar->buff_size);
	while (bytes_read > 0) {
		if (need_report())
			report_write(bsdtar, a, entry, progress);

		bytes_written = archive_write_data(a, bsdtar->buff,
		    bytes_read);
		if (bytes_written < bytes_read) {
			lafe_warnc(0, "%s", archive_error_string(a));
			return (-1);
		}
		progress += bytes_written;
		bytes_read = archive_read_data(ina, bsdtar->buff, bsdtar->buff_size);
	}

	return (0);
}
Example #3
0
static void
test_binary(void)
{
  const char reffile[] = "test_read_format_rar_binary_data.rar";
  char file1_buff[1048576];
  int file1_size = sizeof(file1_buff);
  const char file1_test_txt[] = "\x37\xef\xb2\xbe\x33\xf6\xcc\xcb\xee\x2a\x10"
                                "\x9d\x2e\x01\xe9\xf6\xf9\xe5\xe6\x67\x0c\x2b"
                                "\xd8\x6b\xa0\x26\x9a\xf7\x93\x87\x42\xf1\x08"
                                "\x42\xdc\x9b\x76\x91\x20\xa4\x01\xbe\x67\xbd"
                                "\x08\x74\xde\xec";
  char file2_buff[32618];
  int file2_size = sizeof(file2_buff);
  const char file2_test_txt[] = "\x00\xee\x78\x00\x00\x4d\x45\x54\x41\x2d\x49"
                                "\x4e\x46\x2f\x6d\x61\x6e\x69\x66\x65\x73\x74"
                                "\x2e\x78\x6d\x6c\x50\x4b\x05\x06\x00\x00\x00"
                                "\x00\x12\x00\x12\x00\xaa\x04\x00\x00\xaa\x7a"
                                "\x00\x00\x00\x00";
  struct archive_entry *ae;
  struct archive *a;

  extract_reference_file(reffile);
  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_file(a, reffile, 10240));

  /* First header. */
  assertA(0 == archive_read_next_header(a, &ae));
  assertEqualString("random_data.bin", archive_entry_pathname(ae));
  assertA((int)archive_entry_mtime(ae));
  assertA((int)archive_entry_ctime(ae));
  assertA((int)archive_entry_atime(ae));
  assertEqualInt(file1_size, archive_entry_size(ae));
  assertEqualInt(33188, archive_entry_mode(ae));
  assertA(file1_size == archive_read_data(a, file1_buff, file1_size));
  assertEqualMem(&file1_buff[file1_size - sizeof(file1_test_txt) + 1],
                 file1_test_txt, sizeof(file1_test_txt) - 1);

    /* Second header. */
  assertA(0 == archive_read_next_header(a, &ae));
  assertEqualString("LibarchiveAddingTest.odt", archive_entry_pathname(ae));
  assertA((int)archive_entry_mtime(ae));
  assertA((int)archive_entry_ctime(ae));
  assertA((int)archive_entry_atime(ae));
  assertEqualInt(file2_size, archive_entry_size(ae));
  assertEqualInt(33188, archive_entry_mode(ae));
  assertA(file2_size == archive_read_data(a, file2_buff, file2_size));
  assertEqualMem(&file2_buff[file2_size + 1 - sizeof(file2_test_txt)],
                 file2_test_txt, sizeof(file2_test_txt) - 1);

  /* Test EOF */
  assertA(1 == archive_read_next_header(a, &ae));
  assertEqualInt(2, archive_file_count(a));
  assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
  assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
/*
 * Extract a file compressed with PPMd.
 */
static void
test_ppmd()
{
	const char *refname = "test_read_format_7zip_ppmd.7z";
	struct archive_entry *ae;
	struct archive *a;
	size_t remaining;
	ssize_t bytes;
	char buff[1024];

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

	/* Verify regular file1. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
	assertEqualString("ppmd_test.txt", archive_entry_pathname(ae));
	assertEqualInt(1322464589, archive_entry_mtime(ae));
	assertEqualInt(102400, archive_entry_size(ae));
	assertEqualInt(archive_entry_is_encrypted(ae), 0);
	assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
	remaining = (size_t)archive_entry_size(ae);
	while (remaining) {
		if (remaining < sizeof(buff))
			assertEqualInt(remaining,
			    bytes = archive_read_data(a, buff, sizeof(buff)));
		else
			assertEqualInt(sizeof(buff),
			    bytes = archive_read_data(a, buff, sizeof(buff)));
		if (bytes > 0)
			remaining -= bytes;
		else
			break;
	}
	assertEqualInt(0, remaining);

	assertEqualInt(1, archive_file_count(a));

	/* End of archive. */
	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));

	/* Verify archive format. */
	assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0));
	assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));

	/* Close the archive. */
	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
/*
 * Extract a file compressed with BCJ + LZMA2.
 */
static void
test_bcj(const char *refname)
{
	struct archive_entry *ae;
	struct archive *a;
	size_t remaining;
	ssize_t bytes;
	char buff[1024];

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

	/* Verify regular x86exe. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualInt((AE_IFREG | 0444), archive_entry_mode(ae) & ~0111);
	assertEqualString("x86exe", archive_entry_pathname(ae));
	assertEqualInt(172802, archive_entry_mtime(ae));
	assertEqualInt(27328, archive_entry_size(ae));
	remaining = (size_t)archive_entry_size(ae);
	while (remaining) {
		if (remaining < sizeof(buff))
			assertEqualInt(remaining,
			    bytes = archive_read_data(a, buff, sizeof(buff)));
		else
			assertEqualInt(sizeof(buff),
			    bytes = archive_read_data(a, buff, sizeof(buff)));
		if (bytes > 0)
			remaining -= bytes;
		else
			break;
	}
	assertEqualInt(0, remaining);

	assertEqualInt(1, archive_file_count(a));

	/* End of archive. */
	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));

	/* Verify archive format. */
	assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0));
	assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));

	/* Close the archive. */
	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
Example #6
0
static DEB_RESULT
parse_control_file(struct archive *controlarchive, struct archive_entry *entry, DEB_FILE *file)
{
    DEB_RESULT result = DEB_RESULT_OK;

    int64_t size = archive_entry_size(entry);
	char *buf = DEB_ALLOC(char *, size + 1); /* +1 for null terminator */

    if(archive_read_data(controlarchive, buf, (size_t) size) != size) {
		result = DEB_RESULT_CONTROL_FILE_READ_FAIL;
		goto cleanup;
	}

    buf[size] = '\0';

    DEB_PROPERTIES *properties = deb_properties_parse(buf);
    if(!properties) {
        result = DEB_RESULT_CONTROL_FILE_PARSE_FAIL;
        goto cleanup;
    }

    file->properties = properties;

cleanup:
    if(buf) {
        free(buf);
    }

    return result;
}
void
verify_read_positions(struct archive *a)
{
	struct archive_entry *ae;
	intmax_t read_position = 0;
	size_t j;

	/* Initial header position is zero. */
	assert(read_position == (intmax_t)archive_read_header_position(a));
	for (j = 0; j < sizeof(data_sizes)/sizeof(data_sizes[0]); ++j) {
		assertA(0 == archive_read_next_header(a, &ae));
		assertEqualInt(read_position,
		    (intmax_t)archive_read_header_position(a));
		/* Every other entry: read, then skip */
		if (j & 1)
			assertEqualInt(1,
			    archive_read_data(a, tmp, 1));
		assertA(0 == archive_read_data_skip(a));
		/* read_data_skip() doesn't change header_position */
		assertEqualInt(read_position,
		    (intmax_t)archive_read_header_position(a));

		read_position += 512; /* Size of header. */
		read_position += (data_sizes[j] + 511) & ~511;
	}

	assertA(1 == archive_read_next_header(a, &ae));
	assertEqualInt(read_position, (intmax_t)archive_read_header_position(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(read_position, (intmax_t)archive_read_header_position(a));
}
Example #8
0
static void
verify_file0_stream(struct archive *a, int size_known)
{
	struct archive_entry *ae;

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("-", archive_entry_pathname(ae));
	assertEqualInt(AE_IFREG | 0664, archive_entry_mode(ae));
	if (size_known) {
		// zip64b has the uncompressed size at the beginning,
		// plus CRC and compressed size using length-at-end.
		assert(archive_entry_size_is_set(ae));
		assertEqualInt(6, archive_entry_size(ae));
	} else {
		// zip64a does not have a size at the beginning at all.
		assert(!archive_entry_size_is_set(ae));
	}
#ifdef HAVE_ZLIB_H
	{
		char data[16];
		assertEqualIntA(a, 6, archive_read_data(a, data, 16));
		assertEqualMem(data, "file0\x0a", 6);
	}
#endif
	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));
}
Example #9
0
/*
 * Obsolete function provided for compatibility only.  Note that the API
 * of this function doesn't allow the caller to detect if the remaining
 * data from the archive entry is shorter than the buffer provided, or
 * even if an error occurred while reading data.
 */
int
archive_read_data_into_buffer(struct archive *a, void *d, ssize_t len)
{

	archive_read_data(a, d, len);
	return (ARCHIVE_OK);
}
Example #10
0
/*
 * Extract to memory to check CRC
 */
static int
test(struct archive *a, struct archive_entry *e)
{
	ssize_t len;
	int error_count;

	error_count = 0;
	if (S_ISDIR(archive_entry_filetype(e)))
		return 0;

	info("    testing: %s\t", archive_entry_pathname(e));
	while ((len = archive_read_data(a, buffer, sizeof buffer)) > 0)
		/* nothing */;
	if (len < 0) {
		info(" %s\n", archive_error_string(a));
		++error_count;
	} else {
		info(" OK\n");
	}

	/* shouldn't be necessary, but it doesn't hurt */
	ac(archive_read_data_skip(a));

	return error_count;
}
Example #11
0
static int archive_entry_seek(stream_t *s, int64_t newpos)
{
    struct priv *p = s->priv;
    if (!p->mpa)
        return -1;
    if (archive_seek_data(p->mpa->arch, newpos, SEEK_SET) >= 0)
        return 1;
    // libarchive can't seek in most formats.
    if (newpos < s->pos) {
        // Hack seeking backwards into working by reopening the archive and
        // starting over.
        MP_VERBOSE(s, "trying to reopen archive for performing seek\n");
        if (reopen_archive(s) < STREAM_OK)
            return -1;
        s->pos = 0;
    }
    if (newpos > s->pos) {
        // For seeking forwards, just keep reading data (there's no libarchive
        // skip function either).
        char buffer[4096];
        while (newpos > s->pos) {
            if (mp_cancel_test(s->cancel))
                return -1;

            int size = MPMIN(newpos - s->pos, sizeof(buffer));
            int r = archive_read_data(p->mpa->arch, buffer, size);
            if (r < 0) {
                MP_ERR(s, "%s\n", archive_error_string(p->mpa->arch));
                return -1;
            }
            s->pos += r;
        }
    }
    return 1;
}
Example #12
0
static void
test_noeof(void)
{
  char buff[64];
  const char reffile[] = "test_read_format_rar_noeof.rar";
  const char test_txt[] = "test text document\r\n";
  int size = sizeof(test_txt)-1;
  struct archive_entry *ae;
  struct archive *a;

  extract_reference_file(reffile);
  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_file(a, reffile, 10240));

  /* First header. */
  assertA(0 == archive_read_next_header(a, &ae));
  assertEqualString("test.txt", archive_entry_pathname(ae));
  assertA((int)archive_entry_mtime(ae));
  assertA((int)archive_entry_ctime(ae));
  assertA((int)archive_entry_atime(ae));
  assertEqualInt(20, archive_entry_size(ae));
  assertEqualInt(33188, archive_entry_mode(ae));
  assertA(size == archive_read_data(a, buff, size));
  assertEqualMem(buff, test_txt, size);

  /* Test EOF */
  assertA(1 == archive_read_next_header(a, &ae));
  assertEqualInt(1, archive_file_count(a));
  assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
  assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
Example #13
0
File: files.c Project: srfrog/epic5
char *	file_readb (int fd, int numb)
{
	File *ptr = lookup_file(fd);
	if (!ptr)
		return malloc_strdup(empty_string);
	else
	{
                char *	ret;
		char *	blah;

		blah = (char *)new_malloc(numb+1);
                if (ptr->elf->fp) {
                    clearerr(ptr->elf->fp);
                    numb = fread(blah, 1, numb, ptr->elf->fp);
#ifdef HAVE_LIBARCHIVE
                } else if (ptr->elf->a) {
                    numb = archive_read_data(ptr->elf->a, blah, numb);
#endif
                } else {
                    /* others */
                }

		if ((ret = transform_string_dyn("+CTCP", blah, numb, NULL)))
			new_free(&blah);
		else
			ret = blah;
		return ret;
	}
}
Example #14
0
xbps_dictionary_t HIDDEN
xbps_archive_get_dictionary(struct archive *ar, struct archive_entry *entry)
{
	xbps_dictionary_t d = NULL;
	size_t buflen;
	ssize_t nbytes = -1;
	char *buf;

	assert(ar != NULL);
	assert(entry != NULL);

	buflen = (size_t)archive_entry_size(entry);
	buf = malloc(buflen);
	if (buf == NULL)
		return NULL;

	nbytes = archive_read_data(ar, buf, buflen);
	if ((size_t)nbytes != buflen) {
		free(buf);
		return NULL;
	}

	/* If blob is already a dictionary we are done */
	d = xbps_dictionary_internalize(buf);
	if (xbps_object_type(d) == XBPS_TYPE_DICTIONARY) {
		free(buf);
		return d;
	}
	return NULL;
}
bool la_copy_data_to_fd(archive *a, int fd)
{
    char buf[BUF_SIZE];
    la_ssize_t n_read;
    ssize_t n_written;
    la_ssize_t remain;

    while ((n_read = archive_read_data(a, buf, sizeof(buf))) > 0) {
        remain = n_read;

        while (remain > 0) {
            n_written = write(fd, buf + (n_read - remain),
                              static_cast<size_t>(remain));
            if (n_written <= 0) {
                LOGE("Failed to write data: %s", strerror(errno));
                return false;
            }

            remain -= n_written;
        }
    }

    if (n_read < 0) {
        LOGE("Failed to read archive entry data: %s",
             archive_error_string(a));
        return false;
    }

    return true;
}
Example #16
0
static ssize_t
verify_signature_read_cb(struct archive *archive, void *cookie, const void **buf)
{
	struct signature_archive *state = cookie;
	char hash[SHA512_DIGEST_STRING_LENGTH];
	ssize_t len, expected;

	if (state->sign_cur_block >= state->sign_block_number)
		return 0;

	/* The following works for sign_block_len > 1 */
	if (state->sign_cur_block + 1 == state->sign_block_number)
		expected = state->pkg_size % state->sign_block_len;
	else
		expected = state->sign_block_len;

	len = archive_read_data(state->archive, state->sign_buf, expected);
	if (len != expected) {
		warnx("Short read from package");
		return -1;
	}

	hash_block(state->sign_buf, len, hash);

	if (strcmp(hash, state->sign_blocks[state->sign_cur_block]) != 0) {
		warnx("Invalid signature of block %llu",
		    (unsigned long long)state->sign_cur_block);
		return -1;
	}
	++state->sign_cur_block;
	*buf = state->sign_buf;
	return len;
}
Example #17
0
static
int extract_one(struct archive* a, struct archive_entry* ae, uint32_t crc) {
    la_ssize_t fsize, bytes_read;
    uint8_t* buf;
    int ret = 1;
    uint32_t computed_crc;

    fsize = archive_entry_size(ae);
    buf = malloc(fsize);
    if(buf == NULL)
        return 1;

    bytes_read = archive_read_data(a, buf, fsize);
    if(bytes_read != fsize) {
        assertEqualInt(bytes_read, fsize);
        goto fn_exit;
    }

    computed_crc = crc32(0, buf, fsize);
    assertEqualInt(computed_crc, crc);
    ret = 0;
    
fn_exit:
    free(buf);
    return ret;
}
static void
test_large_splitted_file(void)
{
  static const char *reffiles[] =
  {
    "test_read_large_splitted_rar_aa",
    "test_read_large_splitted_rar_ab",
    "test_read_large_splitted_rar_ac",
    "test_read_large_splitted_rar_ad",
    "test_read_large_splitted_rar_ae",
    NULL
  };
  const char test_txt[] = "gin-bottom: 0in\"><BR>\n</P>\n</BODY>\n</HTML>";
  int size = 241647978, offset = 0;
  char buff[64];
  struct archive_entry *ae;
  struct archive *a;

  extract_reference_files(reffiles);
  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_filenames(a, reffiles, 10240));

  /* First header. */
  assertA(0 == archive_read_next_header(a, &ae));
  assertEqualString("ppmd_lzss_conversion_test.txt",
                    archive_entry_pathname(ae));
  assertA((int)archive_entry_mtime(ae));
  assertA((int)archive_entry_ctime(ae));
  assertA((int)archive_entry_atime(ae));
  assertEqualInt(size, archive_entry_size(ae));
  assertEqualInt(33188, archive_entry_mode(ae));
  while (offset + (int)sizeof(buff) < size)
  {
    assertA(sizeof(buff) == archive_read_data(a, buff, sizeof(buff)));
    offset += sizeof(buff);
  }
  assertA(size - offset == archive_read_data(a, buff, size - offset));
  assertEqualMem(buff, test_txt, size - offset);

  /* Test EOF */
  assertA(1 == archive_read_next_header(a, &ae));
  assertEqualInt(1, archive_file_count(a));
  assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
  assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
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;
}
Example #20
0
bool Decompress(const std::string & file, const std::string & output_path, std::ostream & info_output, std::ostream & error_output)
{
	// Ensure the output path exists.
	PathManager::MakeDir(output_path);

	struct archive * a = archive_read_new();
	archive_read_support_filter_all(a);
	archive_read_support_format_all(a);
	if (archive_read_open_filename(a, file.c_str(), BUFFSIZE) != ARCHIVE_OK)
	{
		error_output << "Unable to open " << file << std::endl;
		return false;
	}

	char buff[BUFFSIZE];
	struct archive_entry *entry;
	while (archive_read_next_header(a, &entry) == ARCHIVE_OK)
	{
		std::string filename = archive_entry_pathname(entry);
		std::string fullpath = output_path + "/" + filename;

		if (archive_entry_filetype(entry) == AE_IFDIR)
			PathManager::MakeDir(fullpath);
		else
		{
			std::fstream f(fullpath.c_str(), std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
			if (!f)
			{
				error_output << "Unable to open file for write (permissions issue?): " << fullpath << std::endl;
				return false;
			}

			int size = -1;
			while (size != 0)
			{
				size = archive_read_data(a, buff, BUFFSIZE);
				if (size < 0)
				{
					error_output << "Encountered corrupt file: " << filename << std::endl;
					return false;
				}
				else if (size != 0)
					f.write(buff, size);
			}
		}

		archive_read_data_skip(a);
	}
	if (archive_read_free(a) != ARCHIVE_OK)
	{
		error_output << "Unable to finish read of " << file << std::endl;
		return false;
	}

	info_output << "Successfully decompressed " << file << std::endl;
	return true;
}
Example #21
0
int extract_archive(char *filename)
{
    struct archive *a;
    struct archive_entry *entry;
    int r;
    size_t size;
    char buff[BUFFER_SIZE];
    FILE *fd;

    a = archive_read_new();
    archive_read_support_compression_gzip(a);
    archive_read_support_format_tar(a);

    r = archive_read_open_filename(a, filename, 10240);

    if (r != ARCHIVE_OK) {
        return 1;
    }

    for (;;) {
        if ((r = archive_read_next_header(a, &entry))) {
            if (r != ARCHIVE_OK) {
                if (r == ARCHIVE_EOF) {
                    return 0;
                }else{
                    return 1;
                }
            }
        }

        fd = fopen(archive_entry_pathname(entry),"wb");
        if (fd == NULL) {
            fprintf(stderr, "problem extracting archive: %s: %s\n", filename,
                    strerror(errno));
            return 1;
        }
        for (;;) {
            size = archive_read_data(a, buff, BUFFER_SIZE);
            if (size < 0) {
                return 1;
            }

            if (size == 0) {
                break;
            }

            fwrite(buff, 1, size, fd);
        }
        fclose(fd);
    }

    r = archive_read_finish(a);
    if (r != ARCHIVE_OK) {
        return 4;
    }
    return 0;
}
Example #22
0
File: nile.c Project: Gottox/nile
FILE *
uncompress(FILE *f, FILE* out, enum Options options) {
	int fdtmp = -1, i, size;
	struct archive *a = NULL;
	struct archive_entry *entry;
	FILE *rv = f, *ftmp;
	char buf[BUFSIZ], tmpfile[] = "/tmp/nile.XXXXXX", nfilter = 0;

	if(!(options & NILE_DECOMPRESS))
		goto uncompress_cleanup;

	a = archive_read_new();
	archive_read_support_filter_all(a);
	archive_read_support_format_raw(a);
	if(archive_read_open_FILE(a, f) != ARCHIVE_OK ||
	   archive_read_next_header(a, &entry) != ARCHIVE_OK) {
		fprintf(stderr, "Warning: decompression failed while open\n");
		goto uncompress_cleanup;
	}
	if((nfilter = archive_filter_count(a)) == 0) {
		goto uncompress_cleanup;
	}
	if((fdtmp = mkstemp(tmpfile)) == -1) {
		perror("mkstemp");
		goto uncompress_cleanup;
	}

	while((size = archive_read_data(a, buf, sizeof(buf))) > 0) {
		write(fdtmp, buf, size);
	}
	if (size < 0) {
		fprintf(stderr, "Warning: decompression failed read\n");
		goto uncompress_cleanup;
	}
	if((ftmp = fdopen(fdtmp, "r")) == NULL) {
		perror("fdopen");
		goto uncompress_cleanup;
	}
	rv = ftmp;

uncompress_cleanup:
	rewind(f);
	if(out != NULL) {
		for(i = 0; i < nfilter; i++) {
			fputc(archive_filter_code(a, i), out);
		}
		for(i = i % HEADER_PADDING; i < HEADER_PADDING; i++) {
			fputc(0, out);
		}
	}
	if(fdtmp > 0)
		close(fdtmp);
	if(a != NULL) {
		archive_read_free(a);
	}
	return rv;
}
Example #23
0
void PictureBank::loadArchive(const std::string &filename)
{
  std::cout << "reading image archive: " << filename << std::endl;
  struct archive *a;
  struct archive_entry *entry;
  int rc;

  a = archive_read_new();
  archive_read_support_compression_all(a);
  archive_read_support_format_all(a);
  rc = archive_read_open_filename(a, filename.c_str(), 16384); // block size
  
  if (rc != ARCHIVE_OK) 
  {
    THROW("Cannot open archive " << filename);
  }

  SDL_Surface *surface;
  SDL_RWops *rw;

  const Uint32 bufferSize = 10000000;  // allocated buffer
  std::auto_ptr< Uint8 > buffer( new Uint8[ bufferSize ] );
   
  if( buffer.get() == 0 ) 
    THROW("Memory error, cannot allocate buffer size " << bufferSize);

  std::string entryname;
  while( archive_read_next_header(a, &entry) == ARCHIVE_OK )
  {
    // for all entries in archive
    entryname = archive_entry_pathname(entry);
    if ((archive_entry_stat(entry)->st_mode & S_IFREG) == 0)
    {
      // not a regular file (maybe a directory). skip it.
      continue;
    }

    if (archive_entry_stat(entry)->st_size >= bufferSize) 
    {
      THROW("Cannot load archive: file is too big " << entryname << " in archive " << filename);
    }
      
    int size = archive_read_data(a, buffer.get(), bufferSize);  // read data into buffer
    rw = SDL_RWFromMem(buffer.get(), size);
    surface = IMG_Load_RW(rw, 0);
    SDL_SetAlpha( surface, 0, 0 );

    setPicture(entryname, *surface);
    SDL_FreeRW(rw);
  }

  rc = archive_read_finish(a);
  if (rc != ARCHIVE_OK)
  {
    THROW("Error while reading archive " << filename);
  }
}
Example #24
0
/*
 * memory to memory
 */
int archive_extract_file4( void *arch_buff, size_t arch_size, const char *src,  void **dest_buff, size_t *dest_len )
{    
    const char              *filename;
    struct archive          *arch_r = NULL;
    struct archive_entry    *entry;

    if( !src )
        return -1;

    arch_r = archive_read_new();
    archive_read_support_format_all( arch_r );
    archive_read_support_compression_all( arch_r );

    if( archive_read_open_memory( arch_r, arch_buff, arch_size ) != ARCHIVE_OK )
        goto errout;

    while( archive_read_next_header( arch_r, &entry ) == ARCHIVE_OK ) 
    {
        filename = archive_entry_pathname( entry );
		if( fnmatch( src, filename, FNM_PATHNAME | FNM_PERIOD ) )
		{
			if( archive_read_data_skip( arch_r ) != ARCHIVE_OK )
            {
                goto errout;
            }
		}
        else
        {
#ifdef DEBUG
            printf("extract:%s\n", filename );
#endif

            *dest_len = archive_entry_size( entry ); 
            if( *dest_len > 0 )
            {
                *dest_buff = malloc( *dest_len + 1 );
                memset( *dest_buff, 0, *dest_len + 1 );
            }

            if( archive_read_data( arch_r, *dest_buff, *dest_len) < 0 ) 
                goto errout;
        }
    }

    archive_read_finish( arch_r );
    return 0;

errout:
#ifdef DEBUG
    fprintf( stderr, "%s\n", archive_error_string( arch_r ) );
#endif
    if( arch_r )
        archive_read_finish( arch_r );
    return -1;

}
Example #25
0
static int archive_entry_seek(stream_t *s, int64_t newpos)
{
    struct priv *p = s->priv;
    if (p->mpa && !p->broken_seek) {
        locale_t oldlocale = uselocale(p->mpa->locale);
        int r = archive_seek_data(p->mpa->arch, newpos, SEEK_SET);
        uselocale(oldlocale);
        if (r >= 0)
            return 1;
        MP_WARN(s, "possibly unsupported seeking - switching to reopening\n");
        p->broken_seek = true;
        if (reopen_archive(s) < STREAM_OK)
            return -1;
    }
    // libarchive can't seek in most formats.
    if (newpos < s->pos) {
        // Hack seeking backwards into working by reopening the archive and
        // starting over.
        MP_VERBOSE(s, "trying to reopen archive for performing seek\n");
        if (reopen_archive(s) < STREAM_OK)
            return -1;
        s->pos = 0;
    }
    if (newpos > s->pos) {
        // For seeking forwards, just keep reading data (there's no libarchive
        // skip function either).
        char buffer[4096];
        while (newpos > s->pos) {
            if (mp_cancel_test(s->cancel))
                return -1;

            int size = MPMIN(newpos - s->pos, sizeof(buffer));
            locale_t oldlocale = uselocale(p->mpa->locale);
            int r = archive_read_data(p->mpa->arch, buffer, size);
            if (r <= 0) {
                if (r == 0 && newpos > p->entry_size) {
                    MP_ERR(s, "demuxer trying to seek beyond end of archive "
                           "entry\n");
                } else if (r == 0) {
                    MP_ERR(s, "end of archive entry reached while seeking\n");
                } else {
                    MP_ERR(s, "%s\n", archive_error_string(p->mpa->arch));
                }
                uselocale(oldlocale);
                if (mp_archive_check_fatal(p->mpa, r)) {
                    mp_archive_free(p->mpa);
                    p->mpa = NULL;
                }
                return -1;
            }
            uselocale(oldlocale);
            s->pos += r;
        }
    }
    return 1;
}
Example #26
0
static ssize_t inner_read(struct archive *a, void *client_data,
                          const void **buff)
{
    (void)a;

    struct inner_data *data = (struct inner_data *)client_data;

    *buff = data->buffer;
    return archive_read_data(data->outer, data->buffer, EXTRACT_BUFFER_LEN);
}
Example #27
0
static int archive_entry_fill_buffer(stream_t *s, char *buffer, int max_len)
{
    struct priv *p = s->priv;
    if (!p->mpa)
        return 0;
    int r = archive_read_data(p->mpa->arch, buffer, max_len);
    if (r < 0)
        MP_ERR(s, "%s\n", archive_error_string(p->mpa->arch));
    return r;
}
Example #28
0
static int
read_file_from_archive(const char *archive_name, struct archive *archive,
                       struct archive_entry **entry,
                       const char *fname, char **content, size_t *len)
{
    int r;

    *content = NULL;
    *len = 0;

retry:
    if (*entry == NULL &&
            (r = archive_read_next_header(archive, entry)) != ARCHIVE_OK) {
        if (r == ARCHIVE_FATAL) {
            warnx("Cannot read from archive `%s': %s",
                  archive_name, archive_error_string(archive));
        } else {
            warnx("Premature end of archive `%s'", archive_name);
        }
        *entry = NULL;
        return -1;
    }
    if (strcmp(archive_entry_pathname(*entry), "//") == 0) {
        archive_read_data_skip(archive);
        *entry = NULL;
        goto retry;
    }

    if (strcmp(fname, archive_entry_pathname(*entry)) != 0)
        return 1;

    /*
    	if (archive_entry_size(*entry) > SSIZE_MAX - 1) {
    		warnx("Signature of archive `%s' too large to process",
    		    archive_name);
    		return 1;
    	}
    */
    *len = archive_entry_size(*entry);
    *content = xmalloc(*len + 1);

    if (archive_read_data(archive, *content, *len) != (ssize_t)*len) {
        warnx("Cannot read complete %s from archive `%s'", fname,
              archive_name);
        free(*content);
        *len = 0;
        *content = NULL;
        return 1;
    }
    (*content)[*len] = '\0';
    *entry = NULL;

    return 0;
}
Example #29
0
static int check_resource(struct resource_list *list, const char *file_resource_name, struct archive *a, struct archive_entry *ae)
{
    struct resource_list *item = rlist_find_by_name(list, file_resource_name);
    if (!item)
        ERR_RETURN("Can't find file-resource for %s", file_resource_name);

    if (item->processed)
        ERR_RETURN("Processing %s twice. Archive is corrupt.", file_resource_name);
    item->processed = true;

    struct sparse_file_map sfm;
    sparse_file_init(&sfm);
    OK_OR_RETURN(sparse_file_get_map_from_resource(item->resource, &sfm));

    size_t expected_length = sparse_file_data_size(&sfm);
    ssize_t archive_length = archive_entry_size(ae);
    if (archive_length < 0)
        ERR_RETURN("Missing file length in archive for %s", file_resource_name);
    if ((size_t) archive_length != expected_length)
        ERR_RETURN("Length mismatch for %s", file_resource_name);

    char *expected_hash = cfg_getstr(item->resource, "blake2b-256");
    if (!expected_hash || strlen(expected_hash) != crypto_generichash_BYTES * 2)
        ERR_RETURN("invalid blake2b-256 hash for '%s'", file_resource_name);

    crypto_generichash_state hash_state;
    crypto_generichash_init(&hash_state, NULL, 0, crypto_generichash_BYTES);
    size_t length_left = expected_length;
    while (length_left != 0) {
        char buffer[4096];

        size_t to_read = sizeof(buffer);
        if (to_read > length_left)
            to_read = length_left;

        ssize_t len = archive_read_data(a, buffer, to_read);
        if (len <= 0)
            ERR_RETURN("Error reading '%s' in archive", archive_entry_pathname(ae));

        crypto_generichash_update(&hash_state, (const unsigned char*) buffer, len);
        length_left -= len;
    }

    unsigned char hash[crypto_generichash_BYTES];
    crypto_generichash_final(&hash_state, hash, sizeof(hash));
    char hash_str[sizeof(hash) * 2 + 1];
    bytes_to_hex(hash, hash_str, sizeof(hash));
    if (memcmp(hash_str, expected_hash, sizeof(hash_str)) != 0)
        ERR_RETURN("Detected blake2b digest mismatch for %s", file_resource_name);

    return 0;
}
Example #30
0
pu_mtree_reader_t *pu_mtree_reader_open_package( alpm_handle_t *h, alpm_pkg_t *p) {
  pu_mtree_reader_t *reader;
  struct archive *mtree;
  char path[PATH_MAX];
  struct archive_entry *entry = NULL;
  char *buf, rbuf[256];
  size_t len;
  FILE *fbuf;
  const char *dbpath = alpm_option_get_dbpath(h);
  const char *pkgname = alpm_pkg_get_name(p);
  const char *pkgver = alpm_pkg_get_version(p);

  if((fbuf = open_memstream(&buf, &len)) == NULL) { return NULL; }

  sprintf(path, "%slocal/%s-%s/mtree", dbpath, pkgname, pkgver);

  if((mtree = archive_read_new()) == NULL) { return NULL; }
  archive_read_support_filter_all(mtree);
  archive_read_support_format_raw(mtree);
  if(archive_read_open_filename(mtree, path, 64) != ARCHIVE_OK) {
    archive_read_free(mtree);
    return NULL;
  }

  if(archive_read_next_header(mtree, &entry) != ARCHIVE_OK) {
    archive_read_free(mtree);
    return NULL;
  }

  while(1) {
      ssize_t size;
      while((size = archive_read_data(mtree, rbuf, 256)) == ARCHIVE_RETRY);
      if(size < 0) { fclose(fbuf); free(buf); return NULL; }
      if(size == 0) { break; }
      fwrite(rbuf, size, 1, fbuf);
  }
  archive_read_free(mtree);
  fclose(fbuf);

  if((fbuf = fmemopen(buf, len, "r")) == NULL) {
    free(buf);
    return NULL;
  } else if((reader = pu_mtree_reader_open_stream(fbuf)) == NULL) {
    free(buf);
    fclose(fbuf);
    return NULL;
  } else {
    reader->_stream_buf = buf;
    reader->_close_stream = 1;
    return reader;
  }
}