Esempio n. 1
0
/*
 * Issue 226: Try to reproduce hang when reading archives where the
 * length-at-end marker ends exactly on a block boundary.
 */
static void
test_compat_zip_7(void)
{
	const char *refname = "test_compat_zip_7.xps";
	struct archive *a;
	struct archive_entry *ae;
	void *p;
	size_t s;
	int i;

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

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

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

		assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
	}
	free(p);
}
Esempio n. 2
0
inline void genSafariExtension(const std::string& path, QueryData& results) {
  Row r;
  r["path"] = path;

  // Loop through (Plist key -> table column name) in kSafariExtensionKeys.
  struct archive* ext = archive_read_new();
  if (ext == nullptr) {
    return;
  }

  // Use open_file, instead of the preferred open_filename for OS X 10.9.
  archive_read_support_format_xar(ext);
  if (archive_read_open_file(ext, path.c_str(), 10240) != ARCHIVE_OK) {
    archive_read_finish(ext);
    return;
  }

  struct archive_entry* entry = nullptr;
  while (archive_read_next_header(ext, &entry) == ARCHIVE_OK) {
    auto item_path = archive_entry_pathname(entry);
    // Documentation for libarchive mentions these APIs may return NULL.
    if (item_path == nullptr) {
      archive_read_data_skip(ext);
      continue;
    }

    // Assume there is no non-root Info.
    if (std::string(item_path).find("Info.plist") == std::string::npos) {
      archive_read_data_skip(ext);
      continue;
    }

    // Read the decompressed Info.plist content.
    auto content = std::string(archive_entry_size(entry), '\0');
    archive_read_data_into_buffer(ext, &content[0], content.size());

    // If the Plist can be parsed, extract important keys into columns.
    pt::ptree tree;
    if (parsePlistContent(content, tree).ok()) {
      for (const auto& it : kSafariExtensionKeys) {
        r[it.second] = tree.get(it.first, "");
      }
    }
    break;
  }

  archive_read_close(ext);
  archive_read_finish(ext);
  results.push_back(std::move(r));
}
Esempio n. 3
0
/*
 * Extract a directory.
 */
static void
extract_dir(struct archive *a, struct archive_entry *e, const char *path)
{
	int mode;

	mode = archive_entry_mode(e) & 0777;
	if (mode == 0)
		mode = 0755;

	/*
	 * Some zipfiles contain directories with weird permissions such
	 * as 0644 or 0444.  This can cause strange issues such as being
	 * unable to extract files into the directory we just created, or
	 * the user being unable to remove the directory later without
	 * first manually changing its permissions.  Therefore, we whack
	 * the permissions into shape, assuming that the user wants full
	 * access and that anyone who gets read access also gets execute
	 * access.
	 */
	mode |= 0700;
	if (mode & 0040)
		mode |= 0010;
	if (mode & 0004)
		mode |= 0001;

	info("d %s\n", path);
	make_dir(path, mode);
	ac(archive_read_data_skip(a));
}
Esempio n. 4
0
static foreign_t
archive_next_header(term_t archive, term_t name)
{ archive_wrapper *ar;
  int rc;

  if ( !get_archive(archive, &ar) )
    return FALSE;
  if ( ar->status == AR_NEW_ENTRY )
    archive_read_data_skip(ar->archive);
  if ( ar->status == AR_OPENED_ENTRY )
    return PL_permission_error("next_header", "archive", archive);

  while ( (rc=archive_read_next_header(ar->archive, &ar->entry)) == ARCHIVE_OK )
  { if ( PL_unify_wchars(name, PL_ATOM, -1,
			 archive_entry_pathname_w(ar->entry)) )
    { ar->status = AR_NEW_ENTRY;
      return TRUE;
    }
    if ( PL_exception(0) )
      return FALSE;
  }

  if ( rc == ARCHIVE_EOF )
    return FALSE;			/* simply at the end */

  return archive_error(ar);
}
Esempio n. 5
0
/*
 * Extract to memory to check CRC
 */
static int
test(struct archive *a, struct archive_entry *e)
{
	ssize_t len;
	int error_count;

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

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

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

	return error_count;
}
static void
test(int skip_explicitely)
{
	struct archive* a = archive_read_new();
	struct archive_entry* e;

	assertEqualInt(ARCHIVE_OK, archive_read_support_format_raw(a));
	assertEqualInt(0, archive_errno(a));
	assertEqualString(NULL, archive_error_string(a));

	assertEqualInt(ARCHIVE_OK, archive_read_open_memory(a, (void*) data,
	    sizeof(data)));
	assertEqualString(NULL, archive_error_string(a));

	assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &e));
	assertEqualInt(0, archive_errno(a));
	assertEqualString(NULL, archive_error_string(a));

	if (skip_explicitely)
		assertEqualInt(ARCHIVE_OK, archive_read_data_skip(a));

	assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &e));
	assertEqualInt(0, archive_errno(a));
	assertEqualString(NULL, archive_error_string(a));

	archive_read_free(a);
}
Esempio n. 7
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);
  }
}
Esempio n. 8
0
/*
 * Print the name of an entry to stdout.
 */
static void
list(struct archive *a, struct archive_entry *e)
{
	char buf[20];
	time_t mtime;

	mtime = archive_entry_mtime(e);
	strftime(buf, sizeof(buf), "%m-%d-%g %R", localtime(&mtime));

	if (!zipinfo_mode) {
		if (v_opt == 1) {
			printf(" %8ju  %s   %s\n",
			    (uintmax_t)archive_entry_size(e),
			    buf, archive_entry_pathname(e));
		} else if (v_opt == 2) {
			printf("%8ju  Stored  %7ju   0%%  %s  %08x  %s\n",
			    (uintmax_t)archive_entry_size(e),
			    (uintmax_t)archive_entry_size(e),
			    buf,
			    0U,
			    archive_entry_pathname(e));
		}
	} else {
		if (Z1_opt)
			printf("%s\n",archive_entry_pathname(e));
	}
	ac(archive_read_data_skip(a));
}
void
verify_read_positions(struct archive *a)
{
	struct archive_entry *ae;
	intmax_t read_position = 0;
	size_t j;

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

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

	assertA(1 == archive_read_next_header(a, &ae));
	assertEqualInt(read_position, (intmax_t)archive_read_header_position(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(read_position, (intmax_t)archive_read_header_position(a));
}
Esempio n. 10
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;
}
Esempio n. 11
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;
}
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;
}
Esempio n. 13
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;
}
Esempio n. 14
0
/*
 * memory to memory
 */
int archive_extract_file4( void *arch_buff, size_t arch_size, const char *src,  void **dest_buff, size_t *dest_len )
{    
    const char              *filename;
    struct archive          *arch_r = NULL;
    struct archive_entry    *entry;

    if( !src )
        return -1;

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

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

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

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

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

    archive_read_finish( arch_r );
    return 0;

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

}
Esempio n. 15
0
 std::string next()
 {
     if (archive_read_next_header(mArchive, &mEntry) == ARCHIVE_OK)
     {
         std::string entryName = archive_entry_pathname(mEntry);
         archive_read_data_skip(mArchive); 
         return entryName;
     }
     return std::string("");
 }
Esempio n. 16
0
static int
read_file_from_archive(const char *archive_name, struct archive *archive,
                       struct archive_entry **entry,
                       const char *fname, char **content, size_t *len)
{
    int r;

    *content = NULL;
    *len = 0;

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

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

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

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

    return 0;
}
bool LibArchiveInterface::list()
{
    kDebug();

    ArchiveRead arch_reader(archive_read_new());

    if (!(arch_reader.data())) {
        return false;
    }

    if (archive_read_support_compression_all(arch_reader.data()) != ARCHIVE_OK) {
        return false;
    }

    if (archive_read_support_format_all(arch_reader.data()) != ARCHIVE_OK) {
        return false;
    }

    if (archive_read_open_filename(arch_reader.data(), QFile::encodeName(filename()), 10240) != ARCHIVE_OK) {
        emit error(i18nc("@info", "Could not open the archive <filename>%1</filename>, libarchive cannot handle it.",
                   filename()));
        return false;
    }

    m_cachedArchiveEntryCount = 0;
    m_extractedFilesSize = 0;

    struct archive_entry *aentry;
    int result;

    while (!m_abortOperation && (result = archive_read_next_header(arch_reader.data(), &aentry)) == ARCHIVE_OK) {
        if (!m_emitNoEntries) {
            emitEntryFromArchiveEntry(aentry);
        }

        m_extractedFilesSize += (qlonglong)archive_entry_size(aentry);

        m_cachedArchiveEntryCount++;
        archive_read_data_skip(arch_reader.data());
    }
    m_abortOperation = false;

    if (result != ARCHIVE_EOF) {
        emit error(i18nc("@info", "The archive reading failed with the following error: <message>%1</message>",
                   QLatin1String( archive_error_string(arch_reader.data()))));
        return false;
    }

    return archive_read_close(arch_reader.data()) == ARCHIVE_OK;
}
Esempio n. 18
0
bool LibarchivePlugin::list()
{
    qCDebug(ARK) << "Listing archive contents";

    if (!initializeReader()) {
        return false;
    }

    qDebug(ARK) << "Detected compression filter:" << archive_filter_name(m_archiveReader.data(), 0);
    QString compMethod = convertCompressionName(QString::fromUtf8(archive_filter_name(m_archiveReader.data(), 0)));
    if (!compMethod.isEmpty()) {
        emit compressionMethodFound(compMethod);
    }

    m_cachedArchiveEntryCount = 0;
    m_extractedFilesSize = 0;
    m_numberOfEntries = 0;
    auto compressedArchiveSize = QFileInfo(filename()).size();

    struct archive_entry *aentry;
    int result = ARCHIVE_RETRY;

    bool firstEntry = true;
    while (!QThread::currentThread()->isInterruptionRequested() && (result = archive_read_next_header(m_archiveReader.data(), &aentry)) == ARCHIVE_OK) {

        if (firstEntry) {
            qDebug(ARK) << "Detected format for first entry:" << archive_format_name(m_archiveReader.data());
            firstEntry = false;
        }

        if (!m_emitNoEntries) {
            emitEntryFromArchiveEntry(aentry);
        }

        m_extractedFilesSize += (qlonglong)archive_entry_size(aentry);

        emit progress(float(archive_filter_bytes(m_archiveReader.data(), -1))/float(compressedArchiveSize));

        m_cachedArchiveEntryCount++;
        archive_read_data_skip(m_archiveReader.data());
    }

    if (result != ARCHIVE_EOF) {
        qCWarning(ARK) << "Could not read until the end of the archive:" << QLatin1String(archive_error_string(m_archiveReader.data()));
        return false;
    }

    return archive_read_close(m_archiveReader.data()) == ARCHIVE_OK;
}
Esempio n. 19
0
static int
append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
{
	struct archive_entry *in_entry;
	int e;

	while (0 == archive_read_next_header(ina, &in_entry)) {
		if (!new_enough(bsdtar, archive_entry_pathname(in_entry),
			archive_entry_stat(in_entry)))
			continue;
		if (excluded(bsdtar, archive_entry_pathname(in_entry)))
			continue;
		if (bsdtar->option_interactive &&
		    !yes("copy '%s'", archive_entry_pathname(in_entry)))
			continue;
		if (bsdtar->verbose)
			safe_fprintf(stderr, "a %s",
			    archive_entry_pathname(in_entry));
		siginfo_setinfo(bsdtar, "copying",
		    archive_entry_pathname(in_entry),
		    archive_entry_size(in_entry));
		siginfo_printinfo(bsdtar, 0);

		e = archive_write_header(a, in_entry);
		if (e != ARCHIVE_OK) {
			if (!bsdtar->verbose)
				bsdtar_warnc(bsdtar, 0, "%s: %s",
				    archive_entry_pathname(in_entry),
				    archive_error_string(a));
			else
				fprintf(stderr, ": %s", archive_error_string(a));
		}
		if (e == ARCHIVE_FATAL)
			exit(1);

		if (e >= ARCHIVE_WARN) {
			if (archive_entry_size(in_entry) == 0)
				archive_read_data_skip(ina);
			else if (copy_file_data(bsdtar, a, ina))
				exit(1);
		}

		if (bsdtar->verbose)
			fprintf(stderr, "\n");
	}

	/* Note: If we got here, we saw no write errors, so return success. */
	return (0);
}
Esempio n. 20
0
static int archive_seek_subentry( private_sys_t* p_sys, char const* psz_subentry )
{
    libarchive_t* p_arc = p_sys->p_archive;

    struct archive_entry* entry;
    int archive_status;

    while( !( archive_status = archive_read_next_header( p_arc, &entry ) ) )
    {
        char const* entry_path = archive_entry_pathname( entry );

        if( strcmp( entry_path, psz_subentry ) == 0 )
        {
            p_sys->p_entry = archive_entry_clone( entry );

            if( unlikely( !p_sys->p_entry ) )
                return VLC_ENOMEM;

            break;
        }

        archive_read_data_skip( p_arc );
    }

    switch( archive_status )
    {
        case ARCHIVE_WARN:
            msg_Warn( p_sys->p_obj,
              "libarchive: %s", archive_error_string( p_arc ) );
            /* fall through */
        case ARCHIVE_EOF:
        case ARCHIVE_FATAL:
        case ARCHIVE_RETRY:
            archive_set_error( p_arc, ARCHIVE_FATAL,
                "archive does not contain >>> %s <<<", psz_subentry );

            return VLC_EGENERIC;
    }

    /* check if seeking is supported */

    if( p_sys->b_seekable_source )
    {
        if( archive_seek_data( p_sys->p_archive, 0, SEEK_CUR ) >= 0 )
            p_sys->b_seekable_archive = true;
    }

    return VLC_SUCCESS;
}
Esempio n. 21
0
void list_archive_get(const char* const infile, char** filenames, int* nfiles, const int buffsize) {
  //printf("In list_archive_get\n");
  //fflush(stdout);

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

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

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

    archive_read_data_skip(a);

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

  archive_read_close(a);
  err = archive_read_free(a);
  if (err != ARCHIVE_OK){
    fprintf(stderr, "CRITICAL ERROR in list_archive_get(): Error when calling archive_read_free(), '%s', err=%i\n",infile,err);
    fprintf(stderr, "CRITICAL ERROR in list_archive_get(): %s\n",archive_error_string(a));
    exit(EXIT_FAILURE);
  }
}
Esempio n. 22
0
static int
append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
{
    struct archive_entry *in_entry;
    int e;

    while (ARCHIVE_OK == (e = archive_read_next_header(ina, &in_entry))) {
        if (archive_match_excluded(bsdtar->matching, in_entry))
            continue;
        if (bsdtar->option_interactive &&
                !yes("copy '%s'", archive_entry_pathname(in_entry)))
            continue;
        if (bsdtar->verbose > 1) {
            safe_fprintf(stderr, "a ");
            list_item_verbose(bsdtar, stderr, in_entry);
        } else if (bsdtar->verbose > 0)
            safe_fprintf(stderr, "a %s",
                         archive_entry_pathname(in_entry));
        if (need_report())
            report_write(bsdtar, a, in_entry, 0);

        e = archive_write_header(a, in_entry);
        if (e != ARCHIVE_OK) {
            if (!bsdtar->verbose)
                lafe_warnc(0, "%s: %s",
                           archive_entry_pathname(in_entry),
                           archive_error_string(a));
            else
                fprintf(stderr, ": %s", archive_error_string(a));
        }
        if (e == ARCHIVE_FATAL)
            exit(1);

        if (e >= ARCHIVE_WARN) {
            if (archive_entry_size(in_entry) == 0)
                archive_read_data_skip(ina);
            else if (copy_file_data_block(bsdtar, a, ina, in_entry))
                exit(1);
        }

        if (bsdtar->verbose)
            fprintf(stderr, "\n");
    }

    return (e == ARCHIVE_EOF ? ARCHIVE_OK : e);
}
Esempio n. 23
0
size_t LIBARCHIVEgetEntry(char *name, char *contentFile, char **ptr) {
  struct mydata *mydata;
  struct archive *a;
  struct archive_entry *entry;
  char *buf;
  size_t size = 0;

  mydata = (struct mydata*)malloc(sizeof(struct mydata));
  a = archive_read_new();
  mydata->name = name;
  archive_read_support_format_all(a);
  archive_read_support_compression_all(a);
  if (archive_read_open(a, mydata, myopen, myread, myclose) == ARCHIVE_FATAL) {
    fprintf(stderr, "failed to open %s\n", mydata->name);
    free(mydata->name);
    free(mydata);
    return 0;
  }

  while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
    if( 0 == strcmp(archive_entry_pathname(entry), contentFile)) {
      o_log(DEBUGM, "%s", (char *)archive_compression_name(a));
      o_log(DEBUGM, "%s", (char *)archive_format_name(a));
      o_log(DEBUGM, "%s", (char *)archive_entry_pathname(entry));
      size = archive_entry_size(entry);
      if(size <= 0)
        o_log(DEBUGM, "zero size");
      if ((buf = (char *)malloc(size+1)) == NULL)
        o_log(ERROR, "cannot allocate memory");
      if ((size_t)archive_read_data(a, buf, size) != size)
        o_log(DEBUGM, "cannot read data");
      buf[size] = '\0';
      *ptr = buf;
    }
    else
      archive_read_data_skip(a);
  }

  archive_read_close(a);
  archive_read_finish(a);
  free(mydata);
  return size;
}
Esempio n. 24
0
int
pkg_full_signature_check(const char *archive_name, struct archive **archive)
{
	struct archive_entry *entry = NULL;
	char *pkgname;
	int r;

	if (pkg_verify_signature(archive_name, archive, &entry, &pkgname))
		return -1;
	if (pkgname == NULL)
		return 0;

	/* XXX read PLIST and compare pkgname */
	while ((r = archive_read_next_header(*archive, &entry)) == ARCHIVE_OK)
		archive_read_data_skip(*archive);

	free(pkgname);
	return r == ARCHIVE_EOF ? 0 : -1;
}
/* ArchiveReader::skipCurrentEntryData{{{
 * */
ZEND_METHOD(ArchiveReader, skipCurrentEntryData){
	zval *this = getThis();
	archive_file_t *arch;
	zend_error_handling error_handling;
	int r;
	
	zend_replace_error_handling(EH_THROW, ce_ArchiveException, &error_handling TSRMLS_CC);

	if (!_archive_get_fd(this, &arch TSRMLS_CC)) {
		zend_restore_error_handling(&error_handling TSRMLS_CC);
		return;
	}
	r = archive_read_data_skip(arch->arch);
	if(r != ARCHIVE_OK){
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Skip archive entry failed");
		zend_restore_error_handling(&error_handling TSRMLS_CC);
		return;
	}
	return;
}/*}}}*/
int main() {
    struct archive *a = archive_read_new();
    archive_read_support_filter_all(a);
    archive_read_support_format_all(a);
    int r = archive_read_open_filename(a, "test.tar", 10240);
    if (r != ARCHIVE_OK)
        return 1;

    struct archive_entry *entry;
    while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
        printf("%s\\n",archive_entry_pathname(entry));
        int64_t offset = archive_read_current_position(a);
        archive_read_data_skip(a);
    }

    r = archive_read_free(a);
    if (r != ARCHIVE_OK)
        return 1;

    return 0;
}
Esempio n. 27
0
static int ReadDir( stream_directory_t* p_directory, input_item_node_t* p_node )
{
    private_sys_t* p_sys = p_directory->p_sys;
    libarchive_t* p_arc = p_sys->p_archive;

    struct vlc_readdir_helper rdh;
    vlc_readdir_helper_init( &rdh, p_directory, p_node);
    struct archive_entry* entry;
    int archive_status;

    while( !( archive_status = archive_read_next_header( p_arc, &entry ) ) )
    {
        if( archive_entry_filetype( entry ) == AE_IFDIR )
            continue;

        char const* path = archive_entry_pathname( entry );

        if( unlikely( !path ) )
            break;

        char*       mrl  = vlc_stream_extractor_CreateMRL( p_directory, path );

        if( unlikely( !mrl ) )
            break;

        if( vlc_readdir_helper_additem( &rdh, mrl, path, NULL, ITEM_TYPE_FILE,
                                        ITEM_LOCAL ) )
        {
            free( mrl );
            break;
        }
        free( mrl );

        if( archive_read_data_skip( p_arc ) )
            break;
    }

    vlc_readdir_helper_finish( &rdh, archive_status == ARCHIVE_EOF );
    return archive_status == ARCHIVE_EOF ? VLC_SUCCESS : VLC_EGENERIC;
}
Esempio n. 28
0
static int extract_db_file(alpm_handle_t *handle, struct archive *archive,
		struct archive_entry *entry, alpm_pkg_t *newpkg, const char *entryname)
{
	char filename[PATH_MAX]; /* the actual file we're extracting */
	const char *dbfile = NULL;
	if(strcmp(entryname, ".INSTALL") == 0) {
		dbfile = "install";
	} else if(strcmp(entryname, ".CHANGELOG") == 0) {
		dbfile = "changelog";
	} else if(strcmp(entryname, ".MTREE") == 0) {
		dbfile = "mtree";
	} else if(*entryname == '.') {
		/* reserve all files starting with '.' for future possibilities */
		_alpm_log(handle, ALPM_LOG_DEBUG, "skipping extraction of '%s'\n", entryname);
		archive_read_data_skip(archive);
		return 0;
	}
	archive_entry_set_perm(entry, 0644);
	snprintf(filename, PATH_MAX, "%s%s-%s/%s",
			_alpm_db_path(handle->db_local), newpkg->name, newpkg->version, dbfile);
	return perform_extraction(handle, archive, entry, filename);
}
Esempio n. 29
0
bool OdinPatcher::Impl::processContents()
{
    archive_entry *entry;
    int laRet;
    int mzRet;

    zipFile zf = MinizipUtils::ctxGetZipFile(zOutput);

    while ((laRet = archive_read_next_header(aInput, &entry)) == ARCHIVE_OK) {
        if (cancelled) return false;

        const char *name = archive_entry_pathname(entry);
        if (!name) {
            continue;
        }

        updateDetails(name);

        if (strcmp(name, "boot.img") == 0) {
            LOGD("Handling boot.img");

            // Boot images should never be over about 30 MiB. This check is here
            // so the patcher won't try to read a multi-gigabyte system image
            // into RAM
            la_int64_t size = archive_entry_size(entry);
            if (size > 30 * 1024 * 1024) {
                LOGE("Boot image exceeds 30 MiB: %" PRId64, size);
                error = ErrorCode::BootImageTooLargeError;
                return false;
            }

            std::vector<unsigned char> data;
            if (size > 0) {
                data.reserve(size);
            }
            char buf[10240];
            la_ssize_t n;
            while ((n = archive_read_data(aInput, buf, sizeof(buf))) > 0) {
                data.insert(data.end(), buf, buf + n);
            }
            if (n != 0) {
                LOGE("libarchive: Failed to read data: %s",
                     archive_error_string(aInput));
                error = ErrorCode::ArchiveReadDataError;
                return false;
            }

            if (!MultiBootPatcher::patchBootImage(pc, info, &data, &error)) {
                return false;
            }

            auto errorRet = MinizipUtils::addFile(zf, name, data);
            if (errorRet != ErrorCode::NoError) {
                error = errorRet;
                return false;
            }

            continue;
        } else if (!StringUtils::starts_with(name, "cache.img")
                && !StringUtils::starts_with(name, "system.img")) {
            LOGD("Skipping %s", name);
            if (archive_read_data_skip(aInput) != ARCHIVE_OK) {
                LOGE("libarchive: Failed to skip data: %s",
                     archive_error_string(aInput));
                error = ErrorCode::ArchiveReadDataError;
                return false;
            }
            continue;
        }

        LOGD("Handling %s", name);

        std::string zipName(name);
        if (StringUtils::ends_with(name, ".ext4")) {
            zipName.erase(zipName.size() - 5);
        }
        zipName += ".sparse";

        // Ha! I'll be impressed if a Samsung firmware image does NOT need zip64
        int zip64 = archive_entry_size(entry) > ((1ll << 32) - 1);

        zip_fileinfo zi;
        memset(&zi, 0, sizeof(zi));

        // Open file in output zip
        mzRet = zipOpenNewFileInZip2_64(
            zf,                    // file
            zipName.c_str(),       // filename
            &zi,                   // zip_fileinfo
            nullptr,               // extrafield_local
            0,                     // size_extrafield_local
            nullptr,               // extrafield_global
            0,                     // size_extrafield_global
            nullptr,               // comment
            Z_DEFLATED,            // method
            Z_DEFAULT_COMPRESSION, // level
            0,                     // raw
            zip64                  // zip64
        );
        if (mzRet != ZIP_OK) {
            LOGE("minizip: Failed to open new file in output zip: %s",
                 MinizipUtils::zipErrorString(mzRet).c_str());
            error = ErrorCode::ArchiveWriteHeaderError;
            return false;
        }

        la_ssize_t nRead;
        char buf[10240];
        while ((nRead = archive_read_data(aInput, buf, sizeof(buf))) > 0) {
            if (cancelled) return false;

            mzRet = zipWriteInFileInZip(zf, buf, nRead);
            if (mzRet != ZIP_OK) {
                LOGE("minizip: Failed to write %s in output zip: %s",
                     zipName.c_str(),
                     MinizipUtils::zipErrorString(mzRet).c_str());
                error = ErrorCode::ArchiveWriteDataError;
                zipCloseFileInZip(zf);
                return false;
            }
        }
        if (nRead != 0) {
            LOGE("libarchive: Failed to read %s: %s",
                 name, archive_error_string(aInput));
            error = ErrorCode::ArchiveReadDataError;
            zipCloseFileInZip(zf);
            return false;
        }

        // Close file in output zip
        mzRet = zipCloseFileInZip(zf);
        if (mzRet != ZIP_OK) {
            LOGE("minizip: Failed to close file in output zip: %s",
                 MinizipUtils::zipErrorString(mzRet).c_str());
            error = ErrorCode::ArchiveWriteDataError;
            return false;
        }
    }

    if (laRet != ARCHIVE_EOF) {
        LOGE("libarchive: Failed to read header: %s",
             archive_error_string(aInput));
        error = ErrorCode::ArchiveReadHeaderError;
        return false;
    }

    if (cancelled) return false;

    return true;
}
Esempio n. 30
0
/*
 * Handle read modes: 'x', 't' and 'p'.
 */
static void
read_archive(struct bsdar *bsdar, char mode)
{
	struct archive		 *a;
	struct archive_entry	 *entry;
	struct stat		  sb;
	struct tm		 *tp;
	const char		 *bname;
	const char		 *name;
	mode_t			  md;
	size_t			  size;
	time_t			  mtime;
	uid_t			  uid;
	gid_t			  gid;
	char			**av;
	char			  buf[25];
	char			  find;
	int			  flags, r, i;

	if ((a = archive_read_new()) == NULL)
		bsdar_errc(bsdar, EX_SOFTWARE, 0, "archive_read_new failed");
	archive_read_support_format_ar(a);
	AC(archive_read_open_filename(a, bsdar->filename, DEF_BLKSZ));

	for (;;) {
		r = archive_read_next_header(a, &entry);
		if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY ||
		    r == ARCHIVE_FATAL)
			bsdar_warnc(bsdar, archive_errno(a), "%s",
			    archive_error_string(a));
		if (r == ARCHIVE_EOF || r == ARCHIVE_FATAL)
			break;
		if (r == ARCHIVE_RETRY) {
			bsdar_warnc(bsdar, 0, "Retrying...");
			continue;
		}

		if ((name = archive_entry_pathname(entry)) == NULL)
			break;

		/* Skip pseudo members. */
		if (strcmp(name, "/") == 0 || strcmp(name, "//") == 0 ||
		    strcmp(name, "/SYM64/") == 0)
			continue;

		if (bsdar->argc > 0) {
			find = 0;
			for(i = 0; i < bsdar->argc; i++) {
				av = &bsdar->argv[i];
				if (*av == NULL)
					continue;
				if ((bname = basename(*av)) == NULL)
					bsdar_errc(bsdar, EX_SOFTWARE, errno,
					    "basename failed");
				if (strcmp(bname, name) != 0)
					continue;

				*av = NULL;
				find = 1;
				break;
			}
			if (!find)
				continue;
		}

		if (mode == 't') {
			if (bsdar->options & AR_V) {
				md = archive_entry_mode(entry);
				uid = archive_entry_uid(entry);
				gid = archive_entry_gid(entry);
				size = archive_entry_size(entry);
				mtime = archive_entry_mtime(entry);
				(void)strmode(md, buf);
				(void)fprintf(stdout, "%s %6d/%-6d %8ju ",
				    buf + 1, uid, gid, (uintmax_t)size);
				tp = localtime(&mtime);
				(void)strftime(buf, sizeof(buf),
				    "%b %e %H:%M %Y", tp);
				(void)fprintf(stdout, "%s %s", buf, name);
			} else
				(void)fprintf(stdout, "%s", name);
			r = archive_read_data_skip(a);
			if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY ||
			    r == ARCHIVE_FATAL) {
				(void)fprintf(stdout, "\n");
				bsdar_warnc(bsdar, archive_errno(a), "%s",
				    archive_error_string(a));
			}

			if (r == ARCHIVE_FATAL)
				break;

			(void)fprintf(stdout, "\n");
		} else {
			/* mode == 'x' || mode = 'p' */
			if (mode == 'p') {
				if (bsdar->options & AR_V) {
					(void)fprintf(stdout, "\n<%s>\n\n",
					    name);
					fflush(stdout);
				}
				r = archive_read_data_into_fd(a, 1);
			} else {
				/* mode == 'x' */
				if (stat(name, &sb) != 0) {
					if (errno != ENOENT) {
						bsdar_warnc(bsdar, 0,
						    "stat %s failed",
						    bsdar->filename);
						continue;
					}
				} else {
					/* stat success, file exist */
					if (bsdar->options & AR_CC)
						continue;
					if (bsdar->options & AR_U &&
					    archive_entry_mtime(entry) <=
					    sb.st_mtime)
						continue;
				}

				if (bsdar->options & AR_V)
					(void)fprintf(stdout, "x - %s\n", name);
				/* Disallow absolute paths. */
				if (name[0] == '/') {
					bsdar_warnc(bsdar, 0,
					    "Absolute path '%s'", name);
					continue;
				}
				/* Basic path security flags. */
				flags = ARCHIVE_EXTRACT_SECURE_SYMLINKS |
				    ARCHIVE_EXTRACT_SECURE_NODOTDOT;
				if (bsdar->options & AR_O)
					flags |= ARCHIVE_EXTRACT_TIME;

				r = archive_read_extract(a, entry, flags);
			}

			if (r)
				bsdar_warnc(bsdar, archive_errno(a), "%s",
				    archive_error_string(a));
		}
	}
	AC(archive_read_close(a));
	AC(archive_read_free(a));
}