Пример #1
0
int Tarball::install () {
  archive_entry *entry;
  int r;

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

  archive* ext = archive_write_disk_new();
  const int flags = ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM |
    ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS;
  archive_write_disk_set_options(ext, flags);
  archive_write_disk_set_standard_lookup(ext);

  const std::string subdir = "deps";
  const std::string filename = subdir + "/" + basename(this->location);
  printf("Unpacking archive %s\n", filename.c_str());
  if ((r = archive_read_open_filename(a,filename.c_str(), 10240))) {
    fprintf(stderr, "Error opening archive:\n%s\n", archive_error_string(a));
    return -1;
  }
  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) {
      return -1;
    }
    rewrite_subdir(entry, subdir);
    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) {
        return -1;
      }
    }
    r = archive_write_finish_entry(ext);
    if (r < ARCHIVE_OK) {
      fprintf(stderr, "%s\n", archive_error_string(ext));
    }
    if (r < ARCHIVE_WARN) {
      return -1;
    }
  }
  archive_read_close(a);
  archive_read_free(a);
  archive_write_close(ext);
  archive_write_free(ext);

  return 0;
};
Пример #2
0
static struct extract *
get_extract(struct archive_read *a)
{
	/* If we haven't initialized, do it now. */
	/* This also sets up a lot of global state. */
	if (a->extract == NULL) {
		a->extract = (struct extract *)malloc(sizeof(*a->extract));
		if (a->extract == NULL) {
			archive_set_error(&a->archive, ENOMEM, "Can't extract");
			return (NULL);
		}
		memset(a->extract, 0, sizeof(*a->extract));
		a->extract->ad = archive_write_disk_new();
		if (a->extract->ad == NULL) {
			archive_set_error(&a->archive, ENOMEM, "Can't extract");
			return (NULL);
		}
		if (archive_write_disk_set_standard_lookup(a->extract->ad)) {
			archive_set_error(&a->archive, ENOMEM, "Can't extract");
			return (NULL);
		}
		a->cleanup_archive_extract = archive_read_extract_cleanup;
	}
	return (a->extract);
}
Пример #3
0
/*
 * memory to file
 */
int archive_extract_file3( void *arch_buff, size_t arch_size, const char *src, char *dest )
{
    int                     flags;     
    const char              *filename;
    struct archive          *arch_r = NULL, *arch_w = NULL;
    struct archive_entry    *entry;

    if( !src || !dest )
        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

            flags = ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS;
            arch_w = archive_write_disk_new();
            archive_write_disk_set_options( arch_w, flags );
            archive_write_disk_set_standard_lookup( arch_w );
            archive_entry_set_pathname( entry, dest );

            if( archive_read_extract2( arch_r, entry, arch_w ) != ARCHIVE_OK ) 
                goto errout;

            archive_write_finish( arch_w );
        }
    }

    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 );
    if( arch_w )
        archive_write_finish( arch_w );
    return -1;
}
Пример #4
0
int extract_archive(const char* filename, const char* to_path) {
  struct archive* a;
  struct archive* ext;
  struct archive_entry* entry;
  int r;
  int flags = ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS;

  a = archive_read_new();
  ext = archive_write_disk_new();
  archive_write_disk_set_options(ext, flags);
  archive_write_disk_set_standard_lookup(ext);

  archive_read_support_format_all(a);
  archive_read_support_compression_all(a);

  if(filename != NULL && strcmp(filename, "-") == 0) {
    filename = NULL;
  }
  if((r = archive_read_open_file(a, filename, 10240))) {
    printf("archive_read_open_file(): %s\n", archive_error_string(a));
    return r;
  }
  for(;;) {
    r = archive_read_next_header(a, &entry);
    if(r == ARCHIVE_EOF) {
      break;
    }
    if(r != ARCHIVE_OK) {
      printf("archive_read_next_header(): %s\n", archive_error_string(a));
      return 0;
    }

    // rewrite pathname
    const char* path = archive_entry_pathname(entry);
    char new_path[PATH_MAX + 1];
    sprintf(new_path, "%s/%s", to_path, path + (strncmp(path, "rootfs/", 7) == 0 ? 7 : 0));
    archive_entry_set_pathname(entry, new_path);

    r = archive_write_header(ext, entry);
    if(r != ARCHIVE_OK) {
      printf("archive_write_header(): %s\n", archive_error_string(ext));
    } else {
      copy_data(a, ext);
      if(r != ARCHIVE_OK) {
        printf("archive_write_finish_entry(): %s\n", archive_error_string(ext));
        return 0;
      }

    }
    r = archive_write_finish_entry(ext);

  }
  archive_read_close(a);
  archive_read_finish(a);
  archive_write_close(ext);
  archive_write_finish(ext);
  return 1;
}
Пример #5
0
static void
mode_pass(struct cpio *cpio, const char *destdir)
{
	struct lafe_line_reader *lr;
	const char *p;
	int r;

	/* Ensure target dir has a trailing '/' to simplify path surgery. */
	cpio->destdir = malloc(strlen(destdir) + 8);
	strcpy(cpio->destdir, destdir);
	if (destdir[strlen(destdir) - 1] != '/')
		strcat(cpio->destdir, "/");

	cpio->archive = archive_write_disk_new();
	if (cpio->archive == NULL)
		lafe_errc(1, 0, "Failed to allocate archive object");
	r = archive_write_disk_set_options(cpio->archive, cpio->extract_flags);
	if (r != ARCHIVE_OK)
		lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));
	cpio->linkresolver = archive_entry_linkresolver_new();
	archive_write_disk_set_standard_lookup(cpio->archive);

	cpio->archive_read_disk = archive_read_disk_new();
	if (cpio->archive_read_disk == NULL)
		lafe_errc(1, 0, "Failed to allocate archive object");
	if (cpio->option_follow_links)
		archive_read_disk_set_symlink_logical(cpio->archive_read_disk);
	else
		archive_read_disk_set_symlink_physical(cpio->archive_read_disk);
	archive_read_disk_set_standard_lookup(cpio->archive_read_disk);

	lr = lafe_line_reader("-", cpio->option_null);
	while ((p = lafe_line_reader_next(lr)) != NULL)
		file_to_archive(cpio, p);
	lafe_line_reader_free(lr);

	archive_entry_linkresolver_free(cpio->linkresolver);
	r = archive_write_close(cpio->archive);
	if (cpio->dot)
		fprintf(stderr, "\n");
	if (r != ARCHIVE_OK)
		lafe_errc(1, 0, "%s", archive_error_string(cpio->archive));

	if (!cpio->quiet) {
		int64_t blocks =
			(archive_filter_bytes(cpio->archive, 0) + 511)
			/ 512;
		fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
		    blocks == 1 ? "block" : "blocks");
	}

	archive_write_free(cpio->archive);
}
Пример #6
0
// Based on libarchive's public example code.
// https://github.com/libarchive/libarchive/wiki/Examples#wiki-Constructing_Objects_On_Disk
void GuiZipper::unpackFile(const char *zipFile, const char *outputDir)
    throw (ZipperException*) {
  // TODO: use archive_write_disk_open instead (if/when it exists)
  char cwd[4096];
  getcwd(cwd, 4096);
  char *absZipFile = fileManager_->getAbsFilePath(zipFile);
  platformstl::filesystem_traits<char> traits;
  traits.set_current_directory(outputDir);
  
  struct archive *a;
  struct archive *ext;
  struct archive_entry *entry;
  int flags;
  int r;
  
  flags = ARCHIVE_EXTRACT_TIME;
  flags |= ARCHIVE_EXTRACT_PERM;
  flags |= ARCHIVE_EXTRACT_ACL;
  flags |= ARCHIVE_EXTRACT_FFLAGS;
  
  a = archive_read_new();
  archive_read_support_format_tar(a);
  archive_read_support_filter_gzip(a);
  ext = archive_write_disk_new();
  archive_write_disk_set_options(ext, flags);
  archive_write_disk_set_standard_lookup(ext);
  r = archive_read_open_filename(a, absZipFile, 10240);
  checkForErrors("Error opening archive for reading", a, r);
  for (;;) {
    r = archive_read_next_header(a, &entry);
    if (r == ARCHIVE_EOF) {
      break;
    }
    checkForErrors("Error reading next archive header", a, r);
    r = archive_write_header(ext, entry);
    checkForErrors("Error writing next archive header", a, r);
    copyData(a, ext, outputDir);
    r = archive_write_finish_entry(ext);
    checkForErrors("Error writing archive finish entry", a, r);
  }
  r = archive_read_close(a);
  checkForErrors("Error closing read archive", a, r);
  r = archive_read_free(a);
  checkForErrors("Error freeing read archive", a, r);
  r = archive_write_close(ext);
  checkForErrors("Error closing write archive", a, r);
  r = archive_write_free(ext);
  checkForErrors("Error freeing write archive", a, r);

  traits.set_current_directory(cwd);
  delete absZipFile;
}
Пример #7
0
static void
extract(const char *filename)
{
	struct archive *a;
	struct archive *ext;
	struct archive_entry *entry;
	int flags;
	int r;

	flags = ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM;

	a = archive_read_new();
	archive_read_support_format_all(a);
#if ARCHIVE_VERSION_NUMBER < 3000000
	archive_read_support_compression_all(a);
#else
	archive_read_support_filter_all(a);
#endif
	ext = archive_write_disk_new();
	archive_write_disk_set_options(ext, flags);
	archive_write_disk_set_standard_lookup(ext);
#if ARCHIVE_VERSION_NUMBER < 3000000
	if ((r = archive_read_open_file(a, filename, 10240)))
		die("archive_read_open_file");
#else
	if ((r = archive_read_open_filename(a, filename, 10240)))
		die("archive_read_open_filename");
#endif
	for (;;) {
		r = archive_read_next_header(a, &entry);
		if (r == ARCHIVE_EOF)
			break;
		if (r < ARCHIVE_WARN)
			die(archive_error_string(a));
		r = archive_write_header(ext, entry);
		if (r == ARCHIVE_OK && archive_entry_size(entry) > 0) {
			r = copy_data(a, ext);
			if (r < ARCHIVE_WARN)
				die(archive_error_string(a));
		}
		r = archive_write_finish_entry(ext);
		if (r < ARCHIVE_WARN)
			die(archive_error_string(ext));
	}
	archive_read_close(a);
	archive_read_free(a);
	archive_write_close(ext);
	archive_write_free(ext);
}
Пример #8
0
void
tar_mode_x(struct bsdtar *bsdtar)
{
	struct archive *writer;

	writer = archive_write_disk_new();
	if (writer == NULL)
		lafe_errc(1, ENOMEM, "Cannot allocate disk writer object");
	if (!bsdtar->option_numeric_owner)
		archive_write_disk_set_standard_lookup(writer);
	archive_write_disk_set_options(writer, bsdtar->extract_flags);

	read_archive(bsdtar, 'x', writer);

	if (lafe_unmatched_inclusions_warn(bsdtar->matching, "Not found in archive") != 0)
		bsdtar->return_value = 1;
	archive_write_free(writer);
}
Пример #9
0
static void
mode_pass(struct cpio *cpio, const char *destdir)
{
	unsigned long blocks;
	struct line_reader *lr;
	const char *p;
	int r;

	/* Ensure target dir has a trailing '/' to simplify path surgery. */
	cpio->destdir = malloc(strlen(destdir) + 8);
	strcpy(cpio->destdir, destdir);
	if (destdir[strlen(destdir) - 1] != '/')
		strcat(cpio->destdir, "/");

	cpio->archive = archive_write_disk_new();
	if (cpio->archive == NULL)
		cpio_errc(1, 0, "Failed to allocate archive object");
	r = archive_write_disk_set_options(cpio->archive, cpio->extract_flags);
	if (r != ARCHIVE_OK)
		cpio_errc(1, 0, archive_error_string(cpio->archive));
	cpio->linkresolver = archive_entry_linkresolver_new();
	archive_write_disk_set_standard_lookup(cpio->archive);
	lr = process_lines_init("-", cpio->line_separator);
	while ((p = process_lines_next(lr)) != NULL)
		file_to_archive(cpio, p);
	process_lines_free(lr);

	archive_entry_linkresolver_free(cpio->linkresolver);
	r = archive_write_close(cpio->archive);
	if (r != ARCHIVE_OK)
		cpio_errc(1, 0, archive_error_string(cpio->archive));

	if (!cpio->quiet) {
		blocks = (archive_position_uncompressed(cpio->archive) + 511)
			      / 512;
		fprintf(stderr, "%lu %s\n", blocks,
		    blocks == 1 ? "block" : "blocks");
	}

	archive_write_finish(cpio->archive);
}
Пример #10
0
static struct archive *open_disk(int flags)
{
    struct archive *disk;
    int r;

    disk = archive_write_disk_new();
    if (!disk) {
        opkg_msg(ERROR, "Failed to create disk archive object.\n");
        return NULL;
    }

    r = archive_write_disk_set_options(disk, flags);
    if (r == ARCHIVE_WARN)
        opkg_msg(NOTICE, "Warning when setting disk options: %s\n",
                 archive_error_string(disk));
    else if (r != ARCHIVE_OK) {
        opkg_msg(ERROR, "Failed to set disk options: %s\n",
                 archive_error_string(disk));
        goto err_cleanup;
    }

    r = archive_write_disk_set_standard_lookup(disk);
    if (r == ARCHIVE_WARN)
        opkg_msg(NOTICE,
                 "Warning when setting user/group lookup functions: %s\n",
                 archive_error_string(disk));
    else if (r != ARCHIVE_OK) {
        opkg_msg(ERROR, "Failed to set user/group lookup functions: %s\n",
                 archive_error_string(disk));
        goto err_cleanup;
    }

    return disk;

 err_cleanup:
    archive_write_free(disk);
    return NULL;
}
Пример #11
0
	RESULTCODE ArchiveProcessorImpl::Decompress()
	{
		const char* tpath = GetArchivePath();
		if(tpath==NULL)
		{
			return AG_FAILURE;
		}
		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_compression_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_filename(a, tpath, 10240)))
		{
			return AG_FAILURE;
		}

		while(true)
		{
			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)
			{
				break;
			}

			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)
			{
				break;
			}

			r = archive_write_finish_entry(ext);
			if (r < ARCHIVE_OK)
			{
				fprintf(stderr, "%s\n", archive_error_string(ext));
			}
			if(r < ARCHIVE_WARN)
			{
				break;
			}
		}	

		archive_read_close(a);
		archive_read_free(a);	

		archive_write_close(ext);
		archive_write_free(ext);


		//return r==ARCHIVE_OK ? AG_SUCCESS : AG_FAILURE;
		return AG_SUCCESS;
	}
Пример #12
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;
}
Пример #13
0
bool libarchive_tar_extract(const std::string &filename,
                            const std::string &target,
                            const std::vector<std::string> &patterns)
{
    if (target.empty()) {
        LOGE("%s: Invalid target path for extraction", target.c_str());
        return false;
    }

    autoclose::archive matcher(archive_match_new(), archive_match_free);
    if (!matcher) {
        LOGE("%s: Out of memory when creating matcher", __FUNCTION__);
        return false;
    }
    autoclose::archive in(archive_read_new(), archive_read_free);
    if (!in) {
        LOGE("%s: Out of memory when creating archive reader", __FUNCTION__);
        return false;
    }
    autoclose::archive out(archive_write_disk_new(), archive_write_free);
    if (!out) {
        LOGE("%s: Out of memory when creating disk writer", __FUNCTION__);
        return false;
    }

    // Set up matcher parameters
    for (const std::string &pattern : patterns) {
        if (archive_match_include_pattern(
                matcher.get(), pattern.c_str()) != ARCHIVE_OK) {
            LOGE("Invalid pattern: %s", pattern.c_str());
            return false;
        }
    }

    // Set up archive reader parameters
    //archive_read_support_format_gnutar(in.get());
    archive_read_support_format_tar(in.get());
    //archive_read_support_filter_bzip2(in.get());
    //archive_read_support_filter_gzip(in.get());
    //archive_read_support_filter_xz(in.get());

    // Set up disk writer parameters
    archive_write_disk_set_standard_lookup(out.get());
    archive_write_disk_set_options(out.get(), LIBARCHIVE_DISK_WRITER_FLAGS);

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

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

    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", filename.c_str());
            continue;
        } else if (ret != ARCHIVE_OK) {
            LOGE("%s: Failed to read header: %s",
                 filename.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", filename.c_str());
            return false;
        }

        LOGV("%s", path);

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

        archive_entry_set_pathname(entry, target_path.c_str());

        // Check pattern matches
        if (archive_match_excluded(matcher.get(), entry)) {
            continue;
        }

        // 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: %s", filename.c_str(), archive_error_string(in.get()));
        return false;
    }

    // Check that all patterns were matched
    const char *pattern;
    while ((ret = archive_match_path_unmatched_inclusions_next(
            matcher.get(), &pattern)) == ARCHIVE_OK) {
        LOGE("%s: Pattern not matched: %s", filename.c_str(), pattern);
    }
    if (ret != ARCHIVE_EOF) {
        LOGE("%s: %s", filename.c_str(), archive_error_string(matcher.get()));
        return false;
    }

    return archive_match_path_unmatched_inclusions(matcher.get()) == 0;
}
Пример #14
0
void Package::readPackageFile(const std::string &package_path)
{
    if (!package_path.empty())
        mPackagePath = package_path;

    boost::filesystem::path unpacked_dir = mWorkDir;
    unpacked_dir /= mPackagePath.stem();
    mUnpackedDir = unpacked_dir;

    const void *buf;

    int r;

    struct archive *a = archive_read_new();
    struct archive_entry *entry;

    archive_read_support_compression_bzip2(a);
    archive_read_support_format_tar(a);


    struct archive *ext = archive_write_disk_new();
    int flags = ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS;
    archive_write_disk_set_options(ext, flags);
    archive_write_disk_set_standard_lookup(ext);

    r = archive_read_open_filename(a, package_path.c_str(), 16384);
    if (r != ARCHIVE_OK) {
        archive_read_free(a);
        archive_write_free(ext);
        throw Exception(std::string("archive_read_open_filename() failed for file: ") + package_path);
    }

    while (true) {

        r = archive_read_next_header(a, &entry);
        if (r == ARCHIVE_EOF) {
            break;
        }
        if (r < ARCHIVE_OK) {
            std::cerr << archive_error_string(ext) << std::endl;
        }
        if (r < ARCHIVE_WARN) {
            archive_read_free(a);
            archive_write_free(ext);
            throw Exception(std::string("archive_read_next_header() failed:") + archive_error_string(a));
        }

        std::cout << std::string("extract: ") << archive_entry_pathname(entry) << std::endl;
        archive_entry_set_pathname(entry, (mUnpackedDir.string() + std::string("/") + archive_entry_pathname(entry)).c_str());

        r = archive_write_header(ext, entry);
        if (r < ARCHIVE_OK) {
            archive_read_free(a);
            archive_write_free(ext);
            throw Exception(std::string("archive_write_header() failed:") + archive_error_string(ext));
        } else if (archive_entry_size(entry) > 0) {

            size_t size;
            int64_t offset;
            while (true) {
                r = archive_read_data_block(a, &buf, &size, &offset);
                if (r == ARCHIVE_EOF)
                    break;
                if (r < ARCHIVE_WARN) {
                    archive_read_free(a);
                    archive_write_free(ext);
                    throw Exception(std::string(archive_error_string(ext)));
                }
                if (r < ARCHIVE_OK) {
                    std::cerr << archive_error_string(ext) << std::endl;
                    break;
                }

                r = archive_write_data_block(ext, buf, size, offset);
                if (r < ARCHIVE_WARN) {
                    archive_read_free(a);
                    archive_write_free(ext);
                    throw Exception(std::string(archive_error_string(ext)));
                }
                if (r < ARCHIVE_OK) {
                    std::cerr << archive_error_string(ext) << std::endl;
                    break;
                }
            }


            r = archive_write_finish_entry(ext);
            if (r < ARCHIVE_OK)
                std::cerr << archive_error_string(ext) << std::endl;
            if (r < ARCHIVE_WARN) {
                archive_read_free(a);
                archive_write_free(ext);
                throw Exception(std::string(archive_error_string(ext)));
            }
        }
    }
    archive_read_close(a);
    archive_read_free(a);
    archive_write_close(ext);
    archive_write_free(ext);
}
Пример #15
0
void mfu_flist_archive_extract(const char* filename, bool verbose, int flags)
{
    int r;

    /* TODO: this needs to be parallelized */

    /* initiate archive object for reading */
    struct archive* a = archive_read_new();

    /* initiate archive object for writing */
    struct archive* ext = archive_write_disk_new();
    archive_write_disk_set_options(ext, flags);

    /* we want all the format supports */
    archive_read_support_filter_bzip2(a);
    archive_read_support_filter_gzip(a);
    archive_read_support_filter_compress(a);
    archive_read_support_format_tar(a);

    archive_write_disk_set_standard_lookup(ext);

    if (filename != NULL && strcmp(filename, "-") == 0) {
        filename = NULL;
    }

    /* blocksize set to 1024K */
    if ((r = archive_read_open_filename(a, filename, 10240))) {
        errmsg(archive_error_string(a));
        exit(r);
    }

    struct archive_entry* entry;
    for (;;) {
        r = archive_read_next_header(a, &entry);
        if (r == ARCHIVE_EOF) {
            break;
        }
        if (r != ARCHIVE_OK) {
            errmsg(archive_error_string(a));
            exit(r);
        }

        if (verbose) {
            msg("x ");
        }

        if (verbose) {
            msg(archive_entry_pathname(entry));
        }

        r = archive_write_header(ext, entry);
        if (r != ARCHIVE_OK) {
            errmsg(archive_error_string(a));
        } else {
            copy_data(a, ext);
        }

        if (verbose) {
            msg("\n");
        }
    }

    archive_read_close(a);
    archive_read_free(a);
}
Пример #16
0
static void extract_archive(const char *filename, const char *output)
{
    struct archive *a;
    struct archive *ext;
    struct archive_entry *entry;
    int flags;
    int r;

    flags = ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_SECURE_NODOTDOT;

    a = archive_read_new();
#if ARCHIVE_VERSION_NUMBER < 4000000
    archive_read_support_compression_bzip2(a);
#else
    archive_read_support_filter_bzip2(a);
#endif
    archive_read_support_format_tar(a);

    ext = archive_write_disk_new();
    archive_write_disk_set_options(ext, flags);
    archive_write_disk_set_standard_lookup(ext);

    r = archive_read_open_file(a, filename, 10240);

    if (r) {
        std::string msg = extract_archive_error(filename, output, a);

	archive_read_close(a);
#if ARCHIVE_VERSION_NUMBER < 4000000
        archive_read_finish(a);
#else
	archive_read_free(a);
#endif

        throw utils::InternalError(msg);
    }

    for (;;) {
        r = archive_read_next_header(a, &entry);
        if (r == ARCHIVE_EOF) {
            break;
        }

        if (r != ARCHIVE_OK) {
            std::string msg = extract_archive_error(filename, output, a);

            archive_read_close(a);
#if ARCHIVE_VERSION_NUMBER < 4000000
            archive_read_finish(a);
#else
            archive_read_free(a);
#endif

            archive_write_close(ext);
#if ARCHIVE_VERSION_NUMBER < 4000000
            archive_write_finish(ext);
#else
            archive_write_free(ext);
#endif

            throw utils::InternalError(msg);
        }

        if (r < ARCHIVE_WARN) {
            break;
        }

        r = archive_write_header(ext, entry);

        if (r != ARCHIVE_OK) {
            std::string msg = extract_archive_error(filename, output, a);

            archive_read_close(a);
#if ARCHIVE_VERSION_NUMBER < 4000000
            archive_read_finish(a);
#else
            archive_read_free(a);
#endif
            archive_write_close(ext);
#if ARCHIVE_VERSION_NUMBER < 4000000
            archive_write_finish(ext);
#else
            archive_write_free(ext);
#endif

            throw utils::InternalError(msg);
        } else {
            r = copy_data(a, ext);

            if (r != ARCHIVE_OK) {
                std::string msg = extract_archive_error(filename, output, a);

                archive_read_close(a);
#if ARCHIVE_VERSION_NUMBER < 4000000
                archive_read_finish(a);
#else
                archive_read_free(a);
#endif
                archive_write_close(ext);
#if ARCHIVE_VERSION_NUMBER < 4000000
                archive_write_finish(ext);
#else
                archive_write_free(ext);
#endif


                throw utils::InternalError(msg);
            }
        }
    }

    archive_read_close(a);
#if ARCHIVE_VERSION_NUMBER < 4000000
    archive_read_finish(a);
#else
    archive_read_free(a);
#endif
    archive_write_close(ext);
#if ARCHIVE_VERSION_NUMBER < 4000000
    archive_write_finish(ext);
#else
    archive_write_free(ext);
#endif

}
Пример #17
0
bool vesKiwiArchiveUtils::extractArchive(const std::string& filename, const std::string& destDir)
{
  this->mEntries.clear();


  struct archive *a;
  struct archive *ext;
  struct archive_entry *entry;
  int flags;
  int r;

  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_compression_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, filename.c_str(), 10240))) {
    this->setError("Error Opening File", "Failed to open file: " + filename);
    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) {
      this->setError("Error Reading Archive", archive_error_string(a));
      return false;
    }

    std::string destPath = archive_entry_pathname(entry);

    //printf("entry: %s\n", destPath.c_str());

    if (destDir.size()) {
      destPath = destDir + "/" + destPath;
    }

    archive_entry_set_pathname(entry, destPath.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) {
      copy_data(a, ext);
      if (r != ARCHIVE_OK)
        fprintf(stderr, "%s\n", archive_error_string(ext));
      if (r < ARCHIVE_WARN) {
        this->setError("Error Reading Archive", archive_error_string(ext));
        return false;
      }

    }
    r = archive_write_finish_entry(ext);
    if (r != ARCHIVE_OK)
      fprintf(stderr, "%s\n", archive_error_string(ext));
    if (r < ARCHIVE_WARN) {
      this->setError("Error Reading Archive", archive_error_string(ext));
      return false;
    }

    this->mEntries.push_back(destPath);
  }

  archive_read_close(a);
  archive_read_free(a);
  archive_write_close(ext);
  archive_write_free(ext);
  return true;

}
Пример #18
0
bool ExtractArchive(const char *zip_file, const char *out_dir)
{
   struct archive *input = archive_read_new();
   archive_read_support_format_all(input);
   archive_read_support_compression_all(input);
   struct archive *output = archive_write_disk_new();
   archive_write_disk_set_options(output, ARCHIVE_EXTRACT_TIME);
   archive_write_disk_set_standard_lookup(output);
   const int BLOCK_SIZE = 65536;
   int r = archive_read_open_filename(input, zip_file, BLOCK_SIZE);

   if (r != ARCHIVE_OK)
   {
      debug(("Error opening archive %s: %s\n", zip_file, archive_error_string(input)));
      extraction_error = IDS_BADARCHIVE;
      return false;
   }

   // libarchive can only extract into the current directory, so we
   // need to set it and restore it.
   char original_dir[MAX_PATH];
   getcwd(original_dir, sizeof(original_dir));
   chdir(out_dir);
   
   bool retval = true;
   while (true)
   {
      struct archive_entry *entry;
      r = archive_read_next_header(input, &entry);
      if (r == ARCHIVE_EOF)
         break;
      
      if (r != ARCHIVE_OK)
      {
         debug(("Error reading archive header: %s\n", archive_error_string(input)));
         extraction_error = IDS_BADARCHIVE;
         retval = false;
         break;
      }
      r = archive_write_header(output, entry);
      if (r != ARCHIVE_OK)
      {
         debug(("Error writing archive header: %s\n", archive_error_string(input)));
         extraction_error = IDS_UNKNOWNERROR;
         retval = false;
         break;
      }

      if (archive_entry_size(entry) > 0)
      {
         r = CopyArchiveData(input, output);
         if (r != ARCHIVE_OK)
         {
            debug(("CopyArchiveData error: %s\n", archive_error_string(input)));
            extraction_error = IDS_UNKNOWNERROR;
            retval = false;
            break;
         }
      }
      r = archive_write_finish_entry(output);
      if (r != ARCHIVE_OK)
      {
         debug(("write_finish_entry error: %s\n", archive_error_string(input)));
         extraction_error = IDS_UNKNOWNERROR;
         retval = false;
         break;
      }

      debug(("Archive file %s extracted\n", archive_entry_pathname(entry)));
      
      // Extraction went OK; process Windows messages
      ClearMessageQueue();  // Check for user hitting abort button

      // Check for user abort
      if (abort_download)
      {
         retval = false;
         break;
      }
   }
   archive_read_close(input);
   archive_read_free(input);
   archive_write_close(output);
   archive_write_free(output);

   // Go back to original working directory
   chdir(original_dir);

   return retval;
}
Пример #19
0
int archive_extract_all( char *arch_file, char *dest_dir, char *suffix )
{
    int                     ret, flags;     
    char                    *pwd = NULL, *filename = NULL, *filename_new = NULL, *hardlink = NULL;
    struct archive          *arch_r = NULL, *arch_w = NULL;
    struct archive_entry    *entry = NULL;


    if( !arch_file )
        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_filename( arch_r, arch_file, 10240 ) != ARCHIVE_OK )
        goto errout;

    if( dest_dir )
    {
        if( util_mkdir( dest_dir ) == -1 )
        {
            if( errno == EEXIST )
            {
                if( access( dest_dir, R_OK | W_OK | X_OK ) == -1 )
                {
                    goto errout;
                }

            }
            else
            {
                goto errout;
            }
        }
        pwd = getcwd( NULL, 0 );
        chdir( dest_dir );
    }

    flags = ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_OWNER;
    arch_w = archive_write_disk_new();
    archive_write_disk_set_options( arch_w, flags );
    archive_write_disk_set_standard_lookup( arch_w );

    while( archive_read_next_header( arch_r, &entry ) == ARCHIVE_OK ) 
    {
        if( suffix )
            filename = (char *)archive_entry_pathname( entry );
        
#ifdef DEBUG
        if( !filename )
            filename = (char *)archive_entry_pathname( entry );

        printf("extract:%s\n", filename );
#endif

        if( suffix && archive_entry_filetype( entry ) != AE_IFDIR  )
        {
            filename_new = util_strcat( filename, suffix, NULL );
            archive_entry_set_pathname( entry, filename_new );
            free( filename_new );

            if( archive_entry_nlink( entry ) > 0 )
            {
                hardlink = (char *)archive_entry_hardlink( entry );
                if( hardlink )
                {
                    filename_new = util_strcat( hardlink, suffix, NULL );
                    archive_entry_set_hardlink( entry, filename_new );
                    free( filename_new );
                }
            }

        }

        ret = archive_read_extract2( arch_r, entry, arch_w );
        if( ret != ARCHIVE_OK && ret != ARCHIVE_WARN ) 
        {
            goto errout;
        }


#ifdef DEBUG
        if( ret != ARCHIVE_OK)
        {
            printf("ret:%d, file:%s, link:%d, size:%d, read_err:%s, write_err:%s\n", ret, filename, archive_entry_nlink(entry), archive_entry_size(entry), archive_error_string(arch_r), archive_error_string(arch_w));
        }
#endif
    }


    archive_read_finish( arch_r );
    archive_write_finish( arch_w );
    if( pwd )
    {
        chdir( pwd );
        free( pwd );
    }
    return 0;

errout:

    if( arch_r )
        archive_read_finish( arch_r );

    if( arch_w )
        archive_write_finish( arch_w );

    if( pwd )
    {
        chdir( pwd );
        free( pwd );
    }
    return -1;
}
Пример #20
0
emb_ruby_error_t emb_ruby_uncompress(){

  struct archive *input_archive;
  struct archive *output_archive;
  struct archive_entry* entry;

  int result;
  int output_flags;

  unsigned char buff[2048];
  int buffsize = 2048;
  int size;

  output_flags = ARCHIVE_EXTRACT_TIME;
  output_flags |= ARCHIVE_EXTRACT_PERM;
  output_flags |= ARCHIVE_EXTRACT_ACL;
  output_flags |= ARCHIVE_EXTRACT_FFLAGS;

  input_archive = archive_read_new();
  output_archive = archive_write_disk_new();

  archive_read_support_filter_gzip(input_archive);
  archive_read_support_format_tar(input_archive);
  //archive_read_support_format_raw(a);

  archive_write_disk_set_options(output_archive, output_flags);
  archive_write_disk_set_standard_lookup(output_archive);

  result = archive_read_open_memory(input_archive, (void*)binary_data, binary_size);

  if (result != ARCHIVE_OK) {
    fprintf(stderr, "%s\n", archive_error_string(input_archive));
    return E_UNCOMPRESS_ERROR;
  }


  for (;;) {

    /**
     * Read new header from memory
     */
    result = archive_read_next_header(input_archive, &entry);
    // EOF
    if (result == ARCHIVE_EOF) {
      break;
    }
    // error handling
    if (result != ARCHIVE_OK) {
      fprintf(stderr, "%s\n", archive_error_string(input_archive));
      emd_ruby_uncompress_cleanup(input_archive, output_archive);
      return E_UNCOMPRESS_ERROR;
    }

    /**
     * Write new header into disk
     */
    result = archive_write_header(output_archive, entry);
    // error handling
    if (result != ARCHIVE_OK) {
      fprintf(stderr, "%s\n", archive_error_string(output_archive));
      emd_ruby_uncompress_cleanup(input_archive, output_archive);
      return E_UNCOMPRESS_ERROR;
    }

    /**
     * copy the data
     */
     result = emb_ruby_uncompress_copy_data(input_archive, output_archive);
     if (result != ARCHIVE_OK) {
          fprintf(stderr, "%s\n", archive_error_string(output_archive));
          emd_ruby_uncompress_cleanup(input_archive, output_archive);
          return E_UNCOMPRESS_ERROR;
      }

      /**
       * Write the trailing
       */
       result = archive_write_finish_entry(output_archive);
       if (result != ARCHIVE_OK) {
            fprintf(stderr, "%s\n", archive_error_string(output_archive));
            emd_ruby_uncompress_cleanup(input_archive, output_archive);
            return E_UNCOMPRESS_ERROR;
        }

  }

  emd_ruby_uncompress_cleanup(input_archive, output_archive);

  return E_SUCCESS;

}
Пример #21
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);
  }
}
Пример #22
0
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;
}
Пример #23
0
int main(int argc, char* argv[]){
	struct archive* ar;
	struct archive_entry* aren;
	int arnum;

	if(argc < 3){
		fprintf(stderr, "Usage: %s infile outfile\n", argv[0]);
		return 255;
	}

#ifdef ENABLE_STAGE_1
	puts("==> Stage 1: Listing");

	ar = archive_read_new();
	archive_read_support_filter_all(ar);
	archive_read_support_format_all(ar);

	arnum = archive_read_open_filename(ar, argv[1], 16384);
	if(arnum != ARCHIVE_OK){
		fprintf(stderr, "%s: %s: %s\n", 
			argv[0], argv[1], archive_error_string(ar));
		return 1;
	}

	while(archive_read_next_header(ar, &aren) == ARCHIVE_OK){
		const char *hardlink, *symlink;
		printf("%s format: %s, pathname: %s, size: %"PRId64", links: %d,"
			   "username: %s, uid: %d", 
			argv[1], archive_format_name(ar), archive_entry_pathname(aren),
			archive_entry_size(aren), archive_entry_nlink(aren),
			archive_entry_uname(aren), archive_entry_uid(aren));
		hardlink = archive_entry_hardlink(aren);
		symlink = archive_entry_symlink(aren);
		if(hardlink != NULL){
			printf(", hardlink: %s", hardlink);
		}
		if(symlink != NULL){
			printf(", symlink: %s", symlink);
		}
		putchar('\n');
	}
	
	archive_read_close(ar);
	archive_read_free(ar);
#endif

#ifdef ENABLE_STAGE_2
	puts("==> Stage 2: Displaying");

	ar = archive_read_new();
	archive_read_support_filter_all(ar);
	archive_read_support_format_all(ar);

	arnum = archive_read_open_filename(ar, argv[1], 16384);
	if(arnum != ARCHIVE_OK){
		fprintf(stderr, "%s: %s: %s\n",
			argv[0], argv[1], archive_error_string(ar));
		return 2;
	}

	while(archive_read_next_header(ar, &aren) == ARCHIVE_OK){
		printf("<<< %s >>>\n", archive_entry_pathname(aren));
		for(;;){
			size_t size;
			off_t  offset;
			const void* buffer;
			switch(archive_read_data_block(ar, &buffer, &size, &offset)){
				case ARCHIVE_OK:
					puts(":: Block reading succeeded");
					fwrite(buffer, size, 1, stdout);
					break;
				case ARCHIVE_WARN:
					puts(":: Block reading succeeded, warning exists");
					fwrite(buffer, size, 1, stdout);
					break;
				case ARCHIVE_EOF:
					goto loop_outside;
				case ARCHIVE_RETRY:
					puts(":: Block reading failed, retrying");
					break;
				case ARCHIVE_FATAL:
					puts(":: Fatal error! STOP!");
					return 2;
			}
		}
loop_outside:
		puts("@@ Extract OK @@");
	}

	archive_read_close(ar);
	archive_read_free(ar);
#endif

#ifdef ENABLE_STAGE_3
	puts("==> Stage 3: Extracting");

	struct archive* arext;

	ar = archive_read_new();
	archive_read_support_format_all(ar);
	archive_read_support_filter_all(ar);

	arext = archive_write_disk_new();
	archive_write_disk_set_options(arext,
		ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_ACL | 
		ARCHIVE_EXTRACT_FFLAGS | ARCHIVE_EXTRACT_XATTR );
	archive_write_disk_set_standard_lookup(arext);

	if(archive_read_open_filename(ar, argv[1], 16384)){
		fprintf(stderr, "%s: %s: %s\n",
			argv[0], argv[1], archive_error_string(ar));
		return 3;
	}

	while((arnum = archive_read_next_header(ar, &aren)) == ARCHIVE_OK){
		int filesize, accsize;
		printf("<<< %s >>>\n", archive_entry_pathname(aren));
		if(archive_write_header(arext, aren) != ARCHIVE_OK){
			puts(":: Write header not OK ...");
		}else if((filesize = archive_entry_size(aren)) > 0){
			accsize = 0;
			for(;;){
				size_t size;
				off_t  offset;
				const void* buffer;
				arnum = archive_read_data_block(ar, &buffer, &size, &offset);
				if(arnum != ARCHIVE_OK){
					break;
				}
				arnum = archive_write_data(arext, buffer, size);
				if(arnum >= 0){
					accsize += arnum;
					printf(":: %d of %d bytes written\n", accsize, filesize);
				}
			}
		}
		
		if(archive_write_finish_entry(arext) != ARCHIVE_OK){
			return 3;
		}
	}

	archive_read_close(ar);
	archive_read_free(ar);
	archive_write_close(arext);
	archive_write_free(arext);
#endif


	return 0;
}
Пример #24
0
static void
extract(const char *filename, int do_extract, int flags)
{
	struct archive *a;
	struct archive *ext;
	struct archive_entry *entry;
	int r;

	a = archive_read_new();
	ext = archive_write_disk_new();
	archive_write_disk_set_options(ext, flags);
#ifndef NO_BZIP2_EXTRACT
	archive_read_support_filter_bzip2(a);
#endif
#ifndef NO_GZIP_EXTRACT
	archive_read_support_filter_gzip(a);
#endif
#ifndef NO_COMPRESS_EXTRACT
	archive_read_support_filter_compress(a);
#endif
#ifndef NO_TAR_EXTRACT
	archive_read_support_format_tar(a);
#endif
#ifndef NO_CPIO_EXTRACT
	archive_read_support_format_cpio(a);
#endif
#ifndef NO_LOOKUP
	archive_write_disk_set_standard_lookup(ext);
#endif
	if (filename != NULL && strcmp(filename, "-") == 0)
		filename = NULL;
	if ((r = archive_read_open_filename(a, filename, 10240))) {
		errmsg(archive_error_string(a));
		errmsg("\n");
		exit(r);
	}
	for (;;) {
		r = archive_read_next_header(a, &entry);
		if (r == ARCHIVE_EOF)
			break;
		if (r != ARCHIVE_OK) {
			errmsg(archive_error_string(a));
			errmsg("\n");
			exit(1);
		}
		if (verbose && do_extract)
			msg("x ");
		if (verbose || !do_extract)
			msg(archive_entry_pathname(entry));
		if (do_extract) {
			r = archive_write_header(ext, entry);
			if (r != ARCHIVE_OK)
				errmsg(archive_error_string(a));
			else
				copy_data(a, ext);
		}
		if (verbose || !do_extract)
			msg("\n");
	}
	archive_read_close(a);
	archive_read_free(a);
	exit(0);
}
Пример #25
0
static bool ExtractArchive(const char *zip_file, const char *out_dir)
{
   struct archive *input = archive_read_new();
   archive_read_support_format_all(input);
   archive_read_support_compression_all(input);
   struct archive *output = archive_write_disk_new();
   archive_write_disk_set_options(output, ARCHIVE_EXTRACT_TIME);
   archive_write_disk_set_standard_lookup(output);
   int hRes;
   const int BLOCK_SIZE = 65536;
   int r = archive_read_open_filename(input, zip_file, BLOCK_SIZE);

   if (r != ARCHIVE_OK)
   {
      extraction_error = IDS_BADARCHIVE;
      return false;
   }

   // libarchive can only extract into the current directory, so we
   // need to set it and restore it.
   char original_dir[MAX_PATH];
   char *cRet = getcwd(original_dir, sizeof(original_dir));
   hRes = chdir(out_dir);
   
   bool retval = true;
   while (true)
   {
      struct archive_entry *entry;
      r = archive_read_next_header(input, &entry);
      if (r == ARCHIVE_EOF)
         break;
      
      if (r != ARCHIVE_OK)
      {
         extraction_error = IDS_BADARCHIVE;
         retval = false;
         break;
      }
      r = archive_write_header(output, entry);
      if (r != ARCHIVE_OK)
      {
		 const char *msg = archive_error_string(output);
         extraction_error = IDS_UNKNOWNERROR;
         retval = false;
         break;
      }

      if (archive_entry_size(entry) > 0)
      {
         r = CopyArchiveData(input, output);
         if (r != ARCHIVE_OK)
         {
            const char *msg = archive_error_string(output);
            extraction_error = IDS_UNKNOWNERROR;
            retval = false;
            break;
         }
      }
      r = archive_write_finish_entry(output);
      if (r != ARCHIVE_OK)
      {
         extraction_error = IDS_UNKNOWNERROR;
         retval = false;
         break;
      }

      // Extraction went OK; process Windows messages
      ClearMessageQueue();
   }
   archive_read_close(input);
   archive_read_free(input);
   archive_write_close(output);
   archive_write_free(output);

   // Go back to original working directory
   hRes = chdir(original_dir);

   return retval;
}