コード例 #1
0
int extract_file(char* dumpFile, char* file) {
	struct archive_entry *entry;
	int r;

	struct archive *a = archive_read_new();
	archive_read_support_compression_gzip(a);
	archive_read_support_format_cpio(a);
	FILE *dump = fopen(dumpFile, "r");
	r = archive_read_open_FILE(a, dump);
	if (r != ARCHIVE_OK) {
		fprintf(stderr, "Fail to read cpio file");
		fclose(dump);
		return -1;
	}
	fclose(dump);

	FILE *outputFile = fopen(basename(file), "w");
	int notfound = 1;
	while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
		if(strcmp(basename(archive_entry_pathname(entry)), file) == 0) {
			notfound = 0;
			printf("extract %s\n",archive_entry_pathname(entry));
			archive_read_data_into_fd(a, fileno(outputFile));
		}
	}
	fclose(outputFile);
	archive_read_free(a);
	if(notfound) {
		sprintf(stderr, "The crash log %s was not found\n", file);
		return -1;
	}
	return 1;
}
コード例 #2
0
ファイル: nile.c プロジェクト: 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;
}
コード例 #3
0
ファイル: system.c プロジェクト: jlongstreet/dgen-libretro
uint8_t *load(void **context,
	      size_t *file_size, FILE *file, size_t max_size)
{
	size_t pos;
	size_t size = 0;
	struct chunk *chunk;
	struct chunk head = { 0, &head, &head };
	size_t chunk_size = load_size(file);
	int error = 0;
#ifdef WITH_LIBARCHIVE
	struct archive *archive = *context;
	struct archive_entry *archive_entry;

	if (archive != NULL)
		goto init_ok;
	archive = archive_read_new();
	*context = archive;
	if (archive == NULL) {
		error = ENOMEM;
		goto error;
	}
	archive_read_support_compression_all(archive);
	archive_read_support_format_all(archive);
	archive_read_support_format_raw(archive);
	if (archive_read_open_FILE(archive, file) != ARCHIVE_OK) {
		error = EIO;
		goto error;
	}
init_ok:
	switch (archive_read_next_header(archive, &archive_entry)) {
	case ARCHIVE_OK:
		break;
	case ARCHIVE_EOF:
		error = 0;
		goto error;
	default:
		error = EIO;
		goto error;
	}
#else
	*context = (void *)0xffff;
#endif
	if (chunk_size == 0)
		chunk_size = CHUNK_SIZE;
	else if ((max_size != 0) && (chunk_size > max_size))
		chunk_size = max_size;
	while (1) {
		pos = 0;
		chunk = malloc(sizeof(*chunk) + chunk_size);
		if (chunk == NULL) {
			error = errno;
			goto error;
		}
		chunk->size = chunk_size;
		chunk->next = &head;
		chunk->prev = head.prev;
		chunk->prev->next = chunk;
		head.prev = chunk;
		do {
			size_t i;
#ifdef WITH_LIBARCHIVE
			ssize_t j;

			j = archive_read_data(archive, &chunk->data[pos],
					      (chunk->size - pos));
			/*
			  Don't bother with ARCHIVE_WARN and ARCHIVE_RETRY,
			  consider any negative value an error.
			*/
			if (j < 0) {
				error = EIO;
				goto error;
			}
			i = (size_t)j;
#else
			i = fread(&chunk->data[pos], 1, (chunk->size - pos),
				  file);
#endif
			if (i == 0) {
				chunk->size = pos;
#ifndef WITH_LIBARCHIVE
				if (ferror(file)) {
					error = EIO;
					goto error;
				}
				assert(feof(file));
#endif
				goto process;
			}
			pos += i;
			size += i;
			if ((max_size != 0) && (size > max_size)) {
				error = EFBIG;
				goto error;
			}
		}
		while (pos != chunk->size);
		chunk_size = CHUNK_SIZE;
	}
process:
	chunk = realloc(head.next, (sizeof(*chunk) + size));
	if (chunk == NULL) {
		error = errno;
		goto error;
	}
	chunk->next->prev = chunk;
	head.next = chunk;
	pos = chunk->size;
	chunk->size = size;
	chunk = chunk->next;
	while (chunk != &head) {
		struct chunk *next = chunk->next;

		memcpy(&head.next->data[pos], chunk->data, chunk->size);
		pos += chunk->size;
		chunk->next->prev = chunk->prev;
		chunk->prev->next = chunk->next;
		free(chunk);
		chunk = next;
	}
	chunk = head.next;
	chunk->prev = chunk;
	chunk->next = chunk;
	if (file_size != NULL)
		*file_size = chunk->size;
	return chunk->data;
error:
#ifdef WITH_LIBARCHIVE
	load_finish(context);
#endif
	chunk = head.next;
	while (chunk != &head) {
		struct chunk *next = chunk->next;

		free(chunk);
		chunk = next;
	}
	errno = error;
	return NULL;
}
コード例 #4
0
ファイル: utils.cpp プロジェクト: frugalware/pong
bool extractXZ(FILE *sfp, std::string dest)
{
    struct archive *a;
    struct archive *ext;
    struct archive_entry *entry;
    int flags;
    int r;

    /* Select which attributes we want to restore. */
    flags = ARCHIVE_EXTRACT_TIME;
    flags |= ARCHIVE_EXTRACT_PERM;
    flags |= ARCHIVE_EXTRACT_ACL;
    flags |= ARCHIVE_EXTRACT_FFLAGS;

    a = archive_read_new();
    archive_read_support_format_all(a);
    archive_read_support_filter_all(a);
    ext = archive_write_disk_new();
    archive_write_disk_set_options(ext, flags);
    archive_write_disk_set_standard_lookup(ext);
    if ((r = archive_read_open_FILE(a, sfp))) {
      std::cout<<archive_error_string(ext)<<std::endl;
      return false;
    }
    for (;;) {
      r = archive_read_next_header(a, &entry);
      if (r == ARCHIVE_EOF)
        break;
      if (r < ARCHIVE_OK)
        fprintf(stderr, "%s\n", archive_error_string(a));
      if (r < ARCHIVE_WARN) {
          fprintf(stderr, "warn 1\n");
          return false;
      }
      std::string path = archive_entry_pathname(entry);
      //std::cout<<"old path: "<< path<<std::endl;
      archive_entry_set_pathname(entry, (dest + "/" + path).c_str());
      r = archive_write_header(ext, entry);
      if (r < ARCHIVE_OK)
        fprintf(stderr, "%s\n", archive_error_string(ext));
      else if (archive_entry_size(entry) > 0) {
        r = copy_data(a, ext);
        if (r < ARCHIVE_OK)
          fprintf(stderr, "%s\n", archive_error_string(ext));
        if (r < ARCHIVE_WARN) {
            fprintf(stderr, "warn 2\n");
            return false;
        }
      }
      r = archive_write_finish_entry(ext);
      if (r < ARCHIVE_OK)
        fprintf(stderr, "%s\n", archive_error_string(ext));
      if (r < ARCHIVE_WARN) {
          fprintf(stderr, "warn 3\n");
          return false;
      }
    }
    archive_read_close(a);
    archive_read_free(a);
    archive_write_close(ext);
    archive_write_free(ext);
    return true;
}
コード例 #5
0
ファイル: pkg_format.c プロジェクト: vstakhov/pkg
static int
pkg_read_archive_v2(FILE *fs, struct pkg *pkg,
		struct archive **a, struct archive_entry **ae)
{
	struct pkg_section_hdr sec;
	int retcode = EPKG_OK;
	struct pkg_archive_stdio_cookie *cookie;
	FILE *cookied_fs;
	static const int rd_chunk = 8192;

	if (pkg_skip_to_section(fs, PKG_FORMAT_SECTION_PAYLOAD, &sec) != EPKG_OK) {
		return (EPKG_END);
	}

	*a = archive_read_new();
	/* We don't support anything but (zstd) + tar here */
	archive_read_support_filter_none(*a);
	archive_read_support_format_tar(*a);
	cookie = xmalloc(sizeof(*cookie));
	cookie->fs = fs;
	cookie->remain = sec.size;

	if (sec.flags & PKG_FORMAT_FLAGS_ZSTD) {
		cookie->zstream =  ZSTD_createDStream();
		cookie->rdbuf = xmalloc(rd_chunk);
		cookie->rd_len = rd_chunk;
		cookie->rd_offset = 0;
	}
	else {
		cookie->zstream = NULL;
	}

	cookied_fs = funopen(cookie, pkg_archive_cookie_read, NULL, NULL,
			pkg_archive_cookie_close);

	if (archive_read_open_FILE(*a, cookied_fs) != ARCHIVE_OK) {
		pkg_emit_error("archive_read_open_fd: %s",
				archive_error_string(*a));
		retcode = EPKG_FATAL;

		goto cleanup;
	}

	if (archive_read_next_header(*a, ae) != ARCHIVE_OK) {
		pkg_emit_error("archive_read_next_header: %s",
				archive_error_string(*a));
		retcode = EPKG_FATAL;

		goto cleanup;
	}

cleanup:

	if (retcode != EPKG_OK) {
		if (*a != NULL) {
			archive_read_close(*a);
			archive_read_free(*a);
		}
	}

	return (retcode);
}