Ejemplo n.º 1
0
Reader *Reader::read_open_filename(const char *filename, const char *cmd, bool raw) 
{
    struct archive *ar = archive_read_new();

    try {
        if(cmd) {
            if(archive_read_support_filter_program(ar, cmd) != ARCHIVE_OK)
                throw 0;
        } else {
            if(archive_read_support_filter_all(ar) != ARCHIVE_OK)
                throw 0;
        }

        if(raw) {
            if(archive_read_support_format_raw(ar) != ARCHIVE_OK)
                throw 0;
        } else {
            if(archive_read_support_format_all(ar) != ARCHIVE_OK)
                throw 0;
        }

        if(archive_read_open_filename(ar, filename, 1024) != ARCHIVE_OK)
            throw 0;

    } catch(...) {
        std::string error_msg = archive_error_string(ar);
        archive_read_free(ar);
        throw Error(error_msg);
    }

    return new Reader(ar);
}
Ejemplo n.º 2
0
static void
pack_extract(const char *pack, const char *dbname, const char *dbpath)
{
	struct archive *a = NULL;
	struct archive_entry *ae = NULL;

	if (access(pack, F_OK) != 0)
		return;

	a = archive_read_new();
	archive_read_support_filter_all(a);
	archive_read_support_format_tar(a);
	if (archive_read_open_filename(a, pack, 4096) != ARCHIVE_OK) {
		/* if we can't unpack it it won't be useful for us */
		unlink(pack);
		archive_read_free(a);
		return;
	}

	while (archive_read_next_header(a, &ae) == ARCHIVE_OK) {
		if (strcmp(archive_entry_pathname(ae), dbname) == 0) {
			archive_entry_set_pathname(ae, dbpath);
			archive_read_extract(a, ae, EXTRACT_ARCHIVE_FLAGS);
			break;
		}
	}

	archive_read_free(a);
}
Ejemplo n.º 3
0
int main(int argc, const char **argv) {
    if (argc > 2) {
        fprintf(stderr, "Usage: %s [file]\n", argv[0]);
        exit(1);
    }

    struct archive *a = archive_read_new();
    archive_read_support_compression_all(a);
    archive_read_support_format_raw(a);

    int err;
    if (argc == 2) err = archive_read_open_filename(a, argv[1], BS);
    else err = archive_read_open_fd(a, 0, BS);
    if (err != ARCHIVE_OK) {
        fprintf(stderr, "Broken archive (1)\n");
        exit(1);
    }

    struct archive_entry *ae;
    err = archive_read_next_header(a, &ae);
    if (err != ARCHIVE_OK) {
        fprintf(stderr, "Broken archive (2)\n");
        exit(1);
    }

    (void) archive_read_data_into_fd(a, 1);

    archive_read_finish(a);
    exit(0);
}
Ejemplo n.º 4
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);
	/*
	 * Note: archive_write_disk_set_standard_lookup() is useful
	 * here, but it requires library routines that can add 500k or
	 * more to a static executable.
	 */
	archive_read_support_format_tar(a);
	/*
	 * On my system, enabling other archive formats adds 20k-30k
	 * each.  Enabling gzip decompression adds about 20k.
	 * Enabling bzip2 is more expensive because the libbz2 library
	 * isn't very well factored.
	 */
	if (filename != NULL && strcmp(filename, "-") == 0)
		filename = NULL;
	if ((r = archive_read_open_filename(a, filename, 10240)))
		fail("archive_read_open_filename()",
		    archive_error_string(a), r);
	for (;;) {
		r = archive_read_next_header(a, &entry);
		if (r == ARCHIVE_EOF)
			break;
		if (r != ARCHIVE_OK)
			fail("archive_read_next_header()",
			    archive_error_string(a), 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)
				warn("archive_write_header()",
				    archive_error_string(ext));
			else {
				copy_data(a, ext);
				r = archive_write_finish_entry(ext);
				if (r != ARCHIVE_OK)
					fail("archive_write_finish_entry()",
					    archive_error_string(ext), 1);
			}

		}
		if (verbose || !do_extract)
			msg("\n");
	}
	archive_read_close(a);
	archive_read_free(a);
	exit(0);
}
Ejemplo n.º 5
0
/*
 * An archive file has one empty file. It means there is no content
 * in the archive file except for a header.
 */
static void
test_empty_file()
{
	const char *refname = "test_read_format_7zip_empty_file.7z";
	struct archive_entry *ae;
	struct archive *a;

	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 empty. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
	assertEqualString("empty", archive_entry_pathname(ae));
	assertEqualInt(86401, archive_entry_mtime(ae));
	assertEqualInt(0, archive_entry_size(ae));

	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_COMPRESSION_NONE, archive_compression(a));
	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));
}
Ejemplo n.º 6
0
/*
 * Copy from specified archive to current archive.  Returns non-zero
 * for write errors (which force us to terminate the entire archiving
 * operation).  If there are errors reading the input archive, we set
 * bsdtar->return_value but return zero, so the overall archiving
 * operation will complete and return non-zero.
 */
static int
append_archive_filename(struct bsdtar *bsdtar, struct archive *a,
    const char *raw_filename)
{
	struct archive *ina;
	const char *filename = raw_filename;
	int rc;

	if (strcmp(filename, "-") == 0)
		filename = NULL; /* Library uses NULL for stdio. */

	ina = archive_read_new();
	archive_read_support_format_all(ina);
	archive_read_support_filter_all(ina);
	set_reader_options(bsdtar, a);
	if (archive_read_open_filename(ina, filename,
					bsdtar->bytes_per_block)) {
		lafe_warnc(0, "%s", archive_error_string(ina));
		bsdtar->return_value = 1;
		return (0);
	}

	rc = append_archive(bsdtar, a, ina);

	if (rc != ARCHIVE_OK) {
		lafe_warnc(0, "Error reading archive %s: %s",
		    raw_filename, archive_error_string(ina));
		bsdtar->return_value = 1;
	}
	archive_read_free(ina);

	return (rc);
}
Ejemplo n.º 7
0
/* Open an outer archive with the given filename. */
static struct archive *open_outer(const char *filename)
{
    struct archive *outer;
    int r;

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

    /* Outer package is in 'ar' format, uncompressed. */
    r = archive_read_support_format_ar(outer);
    if (r != ARCHIVE_OK) {
        opkg_msg(ERROR, "Ar format not supported: %s\n",
                 archive_error_string(outer));
        goto err_cleanup;
    }

    r = archive_read_open_filename(outer, filename, EXTRACT_BUFFER_LEN);
    if (r != ARCHIVE_OK) {
        opkg_msg(ERROR, "Failed to open package '%s': %s\n", filename,
                 archive_error_string(outer));
        goto err_cleanup;
    }

    return outer;

 err_cleanup:
    archive_read_free(outer);
    return NULL;
}
Ejemplo n.º 8
0
//********************************************************************************************************
void list_archive(const char* const infile) {
  // Adapted from:
  // https://github.com/libarchive/libarchive/wiki/Examples#List_contents_of_Archive_stored_in_File
  // Note - this function will always be "chatty"; make sure to flush the stdout before using it...
  // TODO: Write a function which *returns* the list of files
  //       (by writing it into a char** supplied by the caller)

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

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

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

  archive_read_close(a);
  err = archive_read_free(a);
  if (err != ARCHIVE_OK){
    fprintf(stderr, "CRITICAL ERROR in list_archive(): Error when calling archive_read_free(), '%s', err=%i\n",infile,err);
    fprintf(stderr, "CRITICAL ERROR in list_archive(): %s\n",archive_error_string(a));
    exit(EXIT_FAILURE);
  }
}
Ejemplo n.º 9
0
/*
 * Extract an archive (optionally compressed).
 * Args:
 *     filename      Full path to archive to unpack.
 *     dest          Directory to unpack in, or NULL for current dir.
 * Returns ARCHIVE_OK on success, or appropriate ARCHIVE_* value
 * on failure (see /usr/include/archive.h).
 */
int unpack_archive_file(char *filename, char *dest) {
    int rc = 0;
    struct archive *a = NULL;

    if (filename == NULL || access(filename, R_OK) == -1) {
        logMessage(ERROR, "unable to read %s (%s:%d): %m",
                   filename, __func__, __LINE__);
        return ARCHIVE_FATAL;
    }

    if ((rc = unpack_init(&a)) != ARCHIVE_OK) {
        logMessage(ERROR, "unable to initialize libarchive");
        return rc;
    }

    rc = archive_read_open_filename(a, filename,
                                    ARCHIVE_DEFAULT_BYTES_PER_BLOCK);
    if (rc != ARCHIVE_OK) {
        logMessage(ERROR, "error opening %s (%s:%d): %s",
                   filename, __func__, __LINE__,
                   archive_error_string(a));
        return rc;
    }

    return unpack_members_and_finish(a, dest, NULL, NULL);
}
Ejemplo n.º 10
0
static void
test_extract_length_at_end(void)
{
	const char *refname = "test_read_format_zip_length_at_end.zip";
	char *p;
	size_t s;
	struct archive *a;

	extract_reference_file(refname);

	/* Verify extraction with seeking reader. */
	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_extract_length_at_end(a, 1);

	/* Verify extraction with streaming reader. */
	p = slurpfile(&s, 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, read_open_memory(a, p, s, 108));
	verify_extract_length_at_end(a, 0);
	free(p);
}
Ejemplo n.º 11
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;
};
Ejemplo n.º 12
0
int main(int argc, char* argv[]) {

  // setup the archive object
  struct archive* a = archive_read_new();
  archive_read_support_filter_all(a);
  archive_read_support_format_all(a);

  // actually open the archive file
  int r = archive_read_open_filename(a, argv[1], 10240); // Note 1
  if (r != ARCHIVE_OK)
    return 1;

  // read through the entries
  struct archive_entry *entry;
  while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {

    // output the path to the archived file
    puts(archive_entry_pathname(entry));

    // move over the data part of the archive entry
    archive_read_data_skip(a);
  }

  // close it up
  r = archive_read_close(a); 
  if (r != ARCHIVE_OK)
    return 1;

  return 0;
}
Ejemplo n.º 13
0
/*
 * For each entry in the archive, it checks "entry + len" pointer against searched string.
 * Len is always the offset of the current dir inside archive, eg: foo.tgz/bar/x,
 * while checking x, len will be strlen("bar/")
 */
static int search_inside_archive(const char *path) {
    char *ptr;
    int len = 0, ret = FTW_CONTINUE, r = 0, string_length;
    struct archive_entry *entry;
    struct archive *a = archive_read_new();

    archive_read_support_filter_all(a);
    archive_read_support_format_all(a);
    string_length = strlen(sv.searched_string);
    if ((a) && (archive_read_open_filename(a, path, BUFF_SIZE) == ARCHIVE_OK)) {
        while ((!quit) && (ret == FTW_CONTINUE) && (archive_read_next_header(a, &entry) == ARCHIVE_OK)) {
            if (!sv.search_lazy) {
                r = !strncmp(archive_entry_pathname(entry) + len, sv.searched_string, string_length);
            } else if (strcasestr(archive_entry_pathname(entry) + len, sv.searched_string)) {
                r = 1;
            }
            if (r) {
                snprintf(sv.found_searched[sv.found_cont], PATH_MAX, "%s/%s", path, archive_entry_pathname(entry));
                sv.found_cont++;
                if (sv.found_cont == MAX_NUMBER_OF_FOUND) {
                    ret = FTW_STOP;
                }
            }
            ptr = strrchr(archive_entry_pathname(entry), '/');
            if ((ptr) && (strlen(ptr) == 1)) {
                len = strlen(archive_entry_pathname(entry));
            }
        }
    }
    archive_read_free(a);
    return quit ? FTW_STOP : ret;
}
Ejemplo n.º 14
0
/*
 * Verify that we skip junk between entries.  The compat_zip_2.zip file
 * has several bytes of junk between 'file1' and 'file2'.  Such
 * junk is routinely introduced by some Zip writers when they manipulate
 * existing zip archives.
 */
static void
test_compat_zip_2(void)
{
	char name[] = "test_compat_zip_2.zip";
	struct archive_entry *ae;
	struct archive *a;

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

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

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

	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
Ejemplo n.º 15
0
/*
 * An archive file has no entry.
 */
static void
test_empty_archive()
{
	const char *refname = "test_read_format_7zip_empty_archive.7z";
	struct archive_entry *ae;
	struct archive *a;

	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));

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

	assertEqualInt(0, archive_file_count(a));

	/* 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));
}
Ejemplo n.º 16
0
/*
 * file to file
 */
int archive_extract_file( char *arch_file, const char *src, char *dest )
{
    int                     flags;     
    const char              *filename;
    struct archive          *arch_r = NULL, *arch_w = NULL;
    struct archive_entry    *entry;

    if( !arch_file || !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_filename( arch_r, arch_file, 10240 ) != 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;
}
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;
}
Ejemplo n.º 18
0
struct archive *uniso_open(uniso_status_t *s, const char *src) {
    struct archive *iso = archive_read_new();
    archive_read_support_format_iso9660(iso);
    if(archive_read_open_filename(iso, src, 10240) != ARCHIVE_OK) {
        s->error = strdup2("Could not open ISO file.");
        return NULL;
    }
    return iso;
}
Ejemplo n.º 19
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);
  }
}
Ejemplo n.º 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;
}
Ejemplo n.º 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;
}
Ejemplo n.º 22
0
Archivo: elf.c Proyecto: srfrog/epic5
/*
 * this one takes a filename and an extension we expect is an archive,
 * and attempts to open it up. it returns -1 on error, 0 if it's not
 * an archive, or 1 if the archive was successfully loaded
 */
static int	archive_fopen(struct epic_loadfile *elf, char *filename, const char *ext, int do_error)
{
    int    ret;

    int    pos;
    char * fname;
    char * extra;
    char * safet;

    fname = LOCAL_COPY(filename);
    safet = LOCAL_COPY(filename);

    extra = fname;

    if ((pos=stristr(fname, ext))!=-1) {

        /*
         * Here we make fname actually point to a real
         * file, instead of virtual files/directories
         * inside the archive.. and check if we're
         * supposed to load a file by default..
         */
        extra+=pos;
        while (*extra!='/') {
            if (*extra==0)
                break;
            extra++;
            pos++;
        }
        safet+=pos;
        *extra++ = 0;

        elf->a = archive_read_new();
        if (!archive_read_support_format_all(elf->a)) {

            if ( !(ret = archive_read_open_filename(elf->a, fname, 10240)) ) {
                if ( (strstr(safet, "/"))!=NULL ) { /* specific file provided */
                    if (!find_in_archive(elf->a, &elf->entry, extra, do_error))
                        return 0;
                } else {
                    if (!find_in_archive(elf->a, &elf->entry, ".ircrc", do_error)) { /* bootstrap */
                        if (do_error)
                            yell("No .ircrc in the zip file specified");
                        return -1;
                    }
                }
                /*
                 * Our archive should now be open and pointing to the
                 * beginning of the specified file
                 */
                return 1;
            } /* <-- we can fall off the end */
        }
    }
    return 0;
}
static void
test_compat_tar_hardlink_1(void)
{
	char name[] = "test_compat_tar_hardlink_1.tar";
	struct archive_entry *ae;
	struct archive *a;

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

	/* Read first entry, which is a regular file. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("xmcd-3.3.2/docs_d/READMf",
		archive_entry_pathname(ae));
	assertEqualString(NULL, archive_entry_hardlink(ae));
	assertEqualInt(321, archive_entry_size(ae));
	assertEqualInt(1082575645, archive_entry_mtime(ae));
	assertEqualInt(1851, archive_entry_uid(ae));
	assertEqualInt(3, archive_entry_gid(ae));
	assertEqualInt(0100444, archive_entry_mode(ae));

	/* Read second entry, which is a hard link at the end of archive. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("xmcd-3.3.2/README",
		archive_entry_pathname(ae));
	assertEqualString(
		"xmcd-3.3.2/docs_d/READMf",
		archive_entry_hardlink(ae));
	assertEqualInt(0, archive_entry_size(ae));
	assertEqualInt(1082575645, archive_entry_mtime(ae));
	assertEqualInt(1851, archive_entry_uid(ae));
	assertEqualInt(3, archive_entry_gid(ae));
	assertEqualInt(0100444, archive_entry_mode(ae));

	/* Verify the end-of-archive. */
	/*
	 * This failed in libarchive 2.4.12 because the tar reader
	 * tried to obey the size field for the hard link and ended
	 * up running past the end of the file.
	 */
	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));

	/* Verify that the format detection worked. */
	assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_NONE);
	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR);

	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
#if ARCHIVE_VERSION_NUMBER < 2000000
	archive_read_finish(a);
#else
	assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
#endif
}
Ejemplo n.º 24
0
/*
 * test_compat_cpio_1.cpio checks heuristics for avoiding false
 * hardlinks.  foo1 and foo2 are files that have nlinks=1 and so
 * should not be marked as hardlinks even though they have identical
 * ino values.  bar1 and bar2 have nlinks=2 so should be marked
 * as hardlinks.
 */
static void
test_compat_cpio_1(void)
{
	char name[] = "test_compat_cpio_1.cpio";
	struct archive_entry *ae;
	struct archive *a;

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

	/* Read first entry. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("foo1", archive_entry_pathname(ae));
	assertEqualString(NULL, archive_entry_hardlink(ae));
	assertEqualInt(1260250228, archive_entry_mtime(ae));
	assertEqualInt(1000, archive_entry_uid(ae));
	assertEqualInt(1000, archive_entry_gid(ae));
	assertEqualInt(0100644, archive_entry_mode(ae));

	/* Read second entry. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("foo2", archive_entry_pathname(ae));
	assertEqualString(NULL, archive_entry_hardlink(ae));
	assertEqualInt(1260250228, archive_entry_mtime(ae));
	assertEqualInt(1000, archive_entry_uid(ae));
	assertEqualInt(1000, archive_entry_gid(ae));
	assertEqualInt(0100644, archive_entry_mode(ae));

	/* Read third entry. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("bar1", archive_entry_pathname(ae));
	assertEqualString(NULL, archive_entry_hardlink(ae));
	assertEqualInt(1260250228, archive_entry_mtime(ae));
	assertEqualInt(1000, archive_entry_uid(ae));
	assertEqualInt(1000, archive_entry_gid(ae));
	assertEqualInt(0100644, archive_entry_mode(ae));

	/* Read fourth entry. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("bar2", archive_entry_pathname(ae));
	assertEqualString("bar1", archive_entry_hardlink(ae));
	assertEqualInt(1260250228, archive_entry_mtime(ae));
	assertEqualInt(1000, archive_entry_uid(ae));
	assertEqualInt(1000, archive_entry_gid(ae));
	assertEqualInt(0100644, archive_entry_mode(ae));

	/* Verify that the format detection worked. */
	assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_NONE);
	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_SVR4_NOCRC);

	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
Ejemplo n.º 25
0
static void extract_recovery(char *ramdisk_path)
{
    // Delete everything in the current root
    DIR *root = opendir("/");
    struct dirent *dp;
    while ((dp = readdir(root)) != NULL)
    {
        unlink(dp->d_name);
    }
    closedir(root);

    // Open the ramdisk
    struct archive *a = archive_read_new();
    archive_read_support_filter_lzma(a);
    archive_read_support_format_cpio(a);
    if (archive_read_open_filename(a, ramdisk_path, 4096) == ARCHIVE_OK)
    {
        // Set up the writer
        struct archive *ext = archive_write_disk_new();
        archive_write_disk_set_options(ext, ARCHIVE_EXTRACT_UNLINK | ARCHIVE_EXTRACT_PERM);
        chdir("/");

        while (1)
        {
            struct archive_entry *entry;

            // Read the next file
            if (archive_read_next_header(a, &entry) == ARCHIVE_EOF)
                break;

            // Create the file
            archive_write_header(ext, entry);

            // If the file has data to write...
            if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) > 0)
            {
                const void *block;
                size_t size;
                int64_t offset;

                // Write the blocks until EOF
                while (1)
                {
                    if (archive_read_data_block(a, &block, &size, &offset) == ARCHIVE_EOF)
                        break;
                    archive_write_data_block(ext, block, size, offset);
                }
            }
        }

        archive_write_free(ext);
    }

    archive_read_free(a);
}
Ejemplo n.º 26
0
/*
 * file to memory
 */
int archive_extract_file2( char *arch_file, const char *src, void **dest_buff, size_t *dest_len )
{
    const char              *filename;
    struct archive          *arch_r = NULL;
    struct archive_entry    *entry;

    if( !arch_file || !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_filename( arch_r, arch_file, 10240 ) != 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 + 10 );
                memset( *dest_buff, 0, *dest_len + 10 );
            }

            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, "errno:%d, error:%s\n", archive_errno( arch_r ), archive_error_string( arch_r ) );
#endif
    if( arch_r )
        archive_read_finish( arch_r );
    return -1;
}
Ejemplo n.º 27
0
static void
test_read_format_ustar_filename_KOI8R_CP1251(const char *refname)
{
	struct archive *a;
	struct archive_entry *ae;

	/*
	 * Read KOI8-R filename in CP1251 with "hdrcharset=KOI8-R" option.
	 */
	if (NULL == setlocale(LC_ALL, "Russian_Russia") &&
	    NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
		skipping("CP1251 locale not available on this system.");
		return;
	}

	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));
	if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=KOI8-R")) {
		skipping("This system cannot convert character-set"
		    " from KOI8-R to CP1251.");
		goto cleanup;
	}
	assertEqualIntA(a, ARCHIVE_OK,
	    archive_read_open_filename(a, refname, 10240));

	/* Verify regular file. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("\xef\xf0\xe8\xe2\xe5\xf2",
	    archive_entry_pathname(ae));
	assertEqualInt(6, archive_entry_size(ae));
	assertEqualInt(archive_entry_is_encrypted(ae), 0);
	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);

	/* Verify regular file. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("\xcf\xd0\xc8\xc2\xc5\xd2",
	    archive_entry_pathname(ae));
	assertEqualInt(6, archive_entry_size(ae));
	assertEqualInt(archive_entry_is_encrypted(ae), 0);
	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);


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

	/* Verify archive format. */
	assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
	assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));

	/* Close the archive. */
	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
cleanup:
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
Ejemplo n.º 28
0
	bool open()
	{
		/* Open the animation file. */
		this->archive = archive_read_new();
		archive_read_support_format_all(this->archive);
		if (archive_read_open_filename(this->archive, this->path, 10240) != ARCHIVE_OK) {
			fprintf(stderr, "Failed to open animation archive.\n");
			return false;
		}
		return true;
	}
Ejemplo n.º 29
0
static void
test_read_format_ustar_filename_CP866_UTF8(const char *refname)
{
	struct archive *a;
	struct archive_entry *ae;

	/*
	 * Read CP866 filename in en_US.UTF-8 with "hdrcharset=CP866" option.
	 */
	if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
		skipping("en_US.UTF-8 locale not available on this system.");
		return;
	}

	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));
	if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=CP866")) {
		skipping("This system cannot convert character-set"
		    " from CP866 to UTF-8.");
		goto cleanup;
	}
	assertEqualIntA(a, ARCHIVE_OK,
	    archive_read_open_filename(a, refname, 10240));

	/* Verify regular file. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("\xd0\x9f\xd0\xa0\xd0\x98\xd0\x92\xd0\x95\xd0\xa2",
	    archive_entry_pathname(ae));
	assertEqualInt(6, archive_entry_size(ae));
	assertEqualInt(archive_entry_is_encrypted(ae), 0);
	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);

	/* Verify regular file. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",
	    archive_entry_pathname(ae));
	assertEqualInt(6, archive_entry_size(ae));
	assertEqualInt(archive_entry_is_encrypted(ae), 0);
	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);


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

	/* Verify archive format. */
	assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
	assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));

	/* Close the archive. */
	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
cleanup:
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
Ejemplo n.º 30
0
static void
test_read_format_ustar_filename_eucJP_CP932(const char *refname)
{
	struct archive *a;
	struct archive_entry *ae;

	/*
	 * Read eucJP filename in CP932/SJIS with "hdrcharset=eucJP" option.
	 */
	if (NULL == setlocale(LC_ALL, "Japanese_Japan") &&
	    NULL == setlocale(LC_ALL, "ja_JP.SJIS")) {
		skipping("CP932 locale not available on this system.");
		return;
	}

	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));
	if (ARCHIVE_OK != archive_read_set_options(a, "hdrcharset=eucJP")) {
		skipping("This system cannot convert character-set"
		    " from eucJP.");
		goto cleanup;
	}
	assertEqualIntA(a, ARCHIVE_OK,
	    archive_read_open_filename(a, refname, 10240));

	/* Verify regular file. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("\x8a\xbf\x8e\x9a.txt", archive_entry_pathname(ae));
	assertEqualInt(8, archive_entry_size(ae));
	assertEqualInt(archive_entry_is_encrypted(ae), 0);
	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);

	/* Verify regular file. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("\x95\x5c.txt", archive_entry_pathname(ae));
	assertEqualInt(4, archive_entry_size(ae));
	assertEqualInt(archive_entry_is_encrypted(ae), 0);
	assertEqualIntA(a, archive_read_has_encrypted_entries(a), ARCHIVE_READ_FORMAT_ENCRYPTION_UNSUPPORTED);


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

	/* Verify archive format. */
	assertEqualIntA(a, ARCHIVE_FILTER_COMPRESS, archive_filter_code(a, 0));
	assertEqualIntA(a, ARCHIVE_FORMAT_TAR_USTAR, archive_format(a));

	/* Close the archive. */
	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
cleanup:
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}