コード例 #1
0
inline void genSafariExtension(const std::string& uid,
                               const std::string& path,
                               QueryData& results) {
  Row r;
  r["uid"] = uid;
  r["path"] = path;

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

  // Perform a dry run of the file read.
  if (!readFile(path).ok()) {
    return;
  }

  // Finally drop privileges to the user controlling the extension.
  auto dropper = DropPrivileges::get();
  if (!dropper->dropToParent(path)) {
    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_filename(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));
}
コード例 #2
0
ファイル: archiving.c プロジェクト: alist/Greenwich
int archive_extract_tar_bzip2(void) {
	struct archive *a;
	struct archive *ext;
	int r = 0;
	int flags = 0;
	int error = 0;
	
	a = archive_read_new();
	archive_read_support_format_tar(a);
	archive_read_support_compression_bzip2(a);
	
	ext = archive_write_disk_new();
	archive_write_disk_set_options(ext, flags);

	if ((r = archive_read_open_file(a, NULL, 10240))) {
		fprintf(stderr, "archiving: %s", archive_error_string(a));
		error = r;
	}
	else {
		for (;;) {
			struct archive_entry *entry;
			r = archive_read_next_header(a, &entry);
			if (r == ARCHIVE_EOF) { break; }
			if (r != ARCHIVE_OK) {
				fprintf(stderr, "archiving: %s", archive_error_string(a));
				error = 1;
				break;
			}
			if (archive_write_header(ext, entry) != ARCHIVE_OK) {
				fprintf(stderr, "archiving: %s", archive_error_string(ext));
			}
			else {
				const void *buff;
				size_t size;
				off_t offset;
				
				for (;;) {
					r = archive_read_data_block(a, &buff, &size, &offset);
					if (r == ARCHIVE_EOF) { r = ARCHIVE_OK; break; }
					if (r != ARCHIVE_OK) {
						fprintf(stderr, "archiving: %s", archive_error_string(ext));
						break;
					}
					r = archive_write_data_block(ext, buff, size, offset);
					if (r != ARCHIVE_OK) {
						fprintf(stderr, "archiving: %s", archive_error_string(ext));
						break;
					}
				}
				if (r != ARCHIVE_OK) {
					error = 1;
					break;
				}
				
				r = archive_write_finish_entry(ext);
				if (r != ARCHIVE_OK) {
					fprintf(stderr, "archiving: %s", archive_error_string(ext));
					error = 1;
					break;
				}
			}
		}
	}
	archive_read_close(a);
	archive_read_finish(a);
	
	return error;
}
コード例 #3
0
/*
 * Apple shipped an extended version of GNU tar with Mac OS X 10.5
 * and earlier.
 */
static void
test_compat_mac_1(void)
{
	char name[] = "test_compat_mac-1.tar.Z";
	struct archive_entry *ae;
	struct archive *a;
	const void *attr;
	size_t attrSize;

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

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString(TESTPATH, archive_entry_pathname(ae));
	assertEqualInt(1275688109, archive_entry_mtime(ae));
	assertEqualInt(95594, archive_entry_uid(ae));
	assertEqualString("kientzle", archive_entry_uname(ae));
	assertEqualInt(5000, archive_entry_gid(ae));
	assertEqualString("", archive_entry_gname(ae));
	assertEqualInt(040755, archive_entry_mode(ae));

	attr = archive_entry_mac_metadata(ae, &attrSize);
	assert(attr == NULL);
	assertEqualInt(0, attrSize);

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString(TESTPATH "dir/", archive_entry_pathname(ae));
	assertEqualInt(1275687611, archive_entry_mtime(ae));
	assertEqualInt(95594, archive_entry_uid(ae));
	assertEqualString("kientzle", archive_entry_uname(ae));
	assertEqualInt(5000, archive_entry_gid(ae));
	assertEqualString("", archive_entry_gname(ae));
	assertEqualInt(040755, archive_entry_mode(ae));

	attr = archive_entry_mac_metadata(ae, &attrSize);
	assert(attr != NULL);
	assertEqualInt(225, attrSize);

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString(TESTPATH "file", archive_entry_pathname(ae));
	assertEqualInt(1275687588, archive_entry_mtime(ae));
	assertEqualInt(95594, archive_entry_uid(ae));
	assertEqualString("kientzle", archive_entry_uname(ae));
	assertEqualInt(5000, archive_entry_gid(ae));
	assertEqualString("", archive_entry_gname(ae));
	assertEqualInt(0100644, archive_entry_mode(ae));

	attr = archive_entry_mac_metadata(ae, &attrSize);
	assert(attr != NULL);
	assertEqualInt(225, attrSize);

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("dir/", archive_entry_pathname(ae));
	assertEqualInt(1275688064, archive_entry_mtime(ae));
	assertEqualInt(95594, archive_entry_uid(ae));
	assertEqualString("kientzle", archive_entry_uname(ae));
	assertEqualInt(5000, archive_entry_gid(ae));
	assertEqualString("", archive_entry_gname(ae));
	assertEqualInt(040755, archive_entry_mode(ae));

	attr = archive_entry_mac_metadata(ae, &attrSize);
	assert(attr != NULL);
	assertEqualInt(225, attrSize);
	assertEqualMem("\x00\x05\x16\x07\x00\x02\x00\x00Mac OS X", attr, 16);

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("file", archive_entry_pathname(ae));
	assertEqualInt(1275625860, archive_entry_mtime(ae));
	assertEqualInt(95594, archive_entry_uid(ae));
	assertEqualString("kientzle", archive_entry_uname(ae));
	assertEqualInt(5000, archive_entry_gid(ae));
	assertEqualString("", archive_entry_gname(ae));
	assertEqualInt(0100644, archive_entry_mode(ae));

	attr = archive_entry_mac_metadata(ae, &attrSize);
	assert(attr != NULL);
	assertEqualInt(225, attrSize);
	assertEqualMem("\x00\x05\x16\x07\x00\x02\x00\x00Mac OS X", attr, 16);

	/* Verify the end-of-archive. */
	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));

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

	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
コード例 #4
0
ファイル: pkg_archive.c プロジェクト: ownsherass/bxpkg
void pkg_archive_close(struct archive *a){
	archive_read_close(a);
	archive_read_finish(a);
}
コード例 #5
0
ファイル: elf.c プロジェクト: srfrog/epic5
off_t	epic_stat(const char *filename, struct stat *buf)
{
#ifdef HAVE_LIBARCHIVE
    struct  archive *a;
    struct  archive_entry *entry = NULL;
#endif
    int     ret;

    char *  zip;
    char *  zipstr;
    char *  sl;
    int     ziploc;
    int     scan = 0;

#ifdef HAVE_LIBARCHIVE
    /*
     * should probably fill the stat structure with
     * as much as possible.. i don't know what might
     * rely on this information..
     */

    zipstr = LOCAL_COPY(filename);
    sl = LOCAL_COPY(filename);
    zip = zipstr;

    if (((ziploc=stristr(zipstr, ".zip"))!=-1) || ((ziploc=stristr(zipstr, ".tar"))!=-1)) {
        zip+=ziploc;
        while (*zip!='/') {
            if (*zip==0)
                break;
            zip++;
            ziploc++;
        }
        sl+=ziploc;
        *zip++ = 0;

        if ( strstr(sl, "/")!=NULL ) scan=1;

        a = archive_read_new();
        archive_read_support_format_all(a);

        if ( !(ret=archive_read_open_filename(a, zipstr, 10240)) ) {
            if (scan) {
                if (!(find_in_archive(a, &entry, zip, 0)) ) {
                    return -1;
                } else {
                    /* this is such a hack, but libarchive consistantly */
                    /* crashes on me when i use it's stat routines */
                    buf->st_size=1;
                    buf->st_mode=33188;

                    archive_read_close(a);
                    archive_read_free(a);
                    return 0;
                }
            }
        }
    }
#endif

    if (!stat(filename, buf)) {
        return 0;
    } else {
        return -1;
    }
}
コード例 #6
0
ファイル: testarchive.c プロジェクト: nkfly/govern-hadoop
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;
}
コード例 #7
0
static void
test_format(int	(*set_format)(struct archive *))
{
    char filedata[64];
    struct archive_entry *ae;
    struct archive *a;
    char *p;
    size_t used;
    size_t buffsize = 1000000;
    char *buff;
    int damaged = 0;

    buff = malloc(buffsize);

    /* Create a new archive in memory. */
    assert((a = archive_write_new()) != NULL);
    assertA(0 == (*set_format)(a));
    assertA(0 == archive_write_add_filter_none(a));
    assertA(0 == archive_write_open_memory(a, buff, buffsize, &used));

    /*
     * Write a file to it.
     */
    assert((ae = archive_entry_new()) != NULL);
    archive_entry_set_mtime(ae, 1, 10);
    assert(1 == archive_entry_mtime(ae));
    assert(10 == archive_entry_mtime_nsec(ae));
    p = strdup("file");
    archive_entry_copy_pathname(ae, p);
    strcpy(p, "XXXX");
    free(p);
    assertEqualString("file", archive_entry_pathname(ae));
    archive_entry_set_mode(ae, S_IFREG | 0755);
    assert((S_IFREG | 0755) == archive_entry_mode(ae));
    archive_entry_set_size(ae, 8);

    assertA(0 == archive_write_header(a, ae));
    archive_entry_free(ae);
    assertA(8 == archive_write_data(a, "12345678", 9));

    /*
     * Write another file to it.
     */
    assert((ae = archive_entry_new()) != NULL);
    archive_entry_set_mtime(ae, 1, 10);
    assert(1 == archive_entry_mtime(ae));
    assert(10 == archive_entry_mtime_nsec(ae));
    p = strdup("file2");
    archive_entry_copy_pathname(ae, p);
    strcpy(p, "XXXX");
    free(p);
    assertEqualString("file2", archive_entry_pathname(ae));
    archive_entry_set_mode(ae, S_IFREG | 0755);
    assert((S_IFREG | 0755) == archive_entry_mode(ae));
    archive_entry_set_size(ae, 4);

    assertA(0 == archive_write_header(a, ae));
    archive_entry_free(ae);
    assertA(4 == archive_write_data(a, "1234", 5));

    /*
     * Write a file with a name, filetype, and size.
     */
    assert((ae = archive_entry_new()) != NULL);
    archive_entry_copy_pathname(ae, "name");
    archive_entry_set_size(ae, 0);
    archive_entry_set_filetype(ae, AE_IFREG);
    assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae));
    assert(archive_error_string(a) == NULL);
    archive_entry_free(ae);

    /*
     * Write a file with a name and filetype but no size.
     */
    assert((ae = archive_entry_new()) != NULL);
    archive_entry_copy_pathname(ae, "name");
    archive_entry_unset_size(ae);
    archive_entry_set_filetype(ae, AE_IFREG);
    assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae));
    assert(archive_error_string(a) != NULL);
    archive_entry_free(ae);

    /*
     * Write a file with a name and size but no filetype.
     */
    assert((ae = archive_entry_new()) != NULL);
    archive_entry_copy_pathname(ae, "name");
    archive_entry_set_size(ae, 0);
    assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae));
    assert(archive_error_string(a) != NULL);
    archive_entry_free(ae);

    /*
     * Write a file with a size and filetype but no name.
     */
    assert((ae = archive_entry_new()) != NULL);
    archive_entry_set_size(ae, 0);
    archive_entry_set_filetype(ae, AE_IFREG);
    assertEqualInt(ARCHIVE_FAILED, archive_write_header(a, ae));
    assert(archive_error_string(a) != NULL);
    archive_entry_free(ae);

    /*
     * Write a directory to it.
     */
    assert((ae = archive_entry_new()) != NULL);
    archive_entry_set_mtime(ae, 11, 110);
    archive_entry_copy_pathname(ae, "dir");
    archive_entry_set_mode(ae, S_IFDIR | 0755);
    archive_entry_set_size(ae, 512);

    assertA(0 == archive_write_header(a, ae));
    assertEqualInt(0, archive_entry_size(ae));
    archive_entry_free(ae);
    assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9));


    /* Close out the archive. */
    assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
    assertEqualInt(ARCHIVE_OK, archive_write_free(a));

    /*
     * Damage the second entry to test the search-ahead recovery.
     * TODO: Move the damage-recovery checking to a separate test;
     * it doesn't really belong in this write test.
     */
    {
        int i;
        for (i = 80; i < 150; i++) {
            if (memcmp(buff + i, "07070", 5) == 0) {
                damaged = 1;
                buff[i] = 'X';
                break;
            }
        }
    }
    failure("Unable to locate the second header for damage-recovery test.");
    assert(damaged == 1);

    /*
     * Now, read the data back.
     */
    assert((a = archive_read_new()) != NULL);
    assertA(0 == archive_read_support_format_all(a));
    assertA(0 == archive_read_support_filter_all(a));
    assertA(0 == archive_read_open_memory(a, buff, used));

    if (!assertEqualIntA(a, 0, archive_read_next_header(a, &ae))) {
        archive_read_free(a);
        return;
    }

    assertEqualInt(1, archive_entry_mtime(ae));
    /* Not the same as above: cpio doesn't store hi-res times. */
    assert(0 == archive_entry_mtime_nsec(ae));
    assert(0 == archive_entry_atime(ae));
    assert(0 == archive_entry_ctime(ae));
    assertEqualString("file", archive_entry_pathname(ae));
    assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
    assertEqualInt(8, archive_entry_size(ae));
    assertA(8 == archive_read_data(a, filedata, 10));
    assertEqualMem(filedata, "12345678", 8);

    /*
     * The second file can't be read because we damaged its header.
     */

    /*
     * Read the third file back.
     * ARCHIVE_WARN here because the damaged entry was skipped.
     */
    assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
    assertEqualString("name", archive_entry_pathname(ae));

    /*
     * Read the dir entry back.
     */
    assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
    assertEqualInt(11, archive_entry_mtime(ae));
    assert(0 == archive_entry_mtime_nsec(ae));
    assert(0 == archive_entry_atime(ae));
    assert(0 == archive_entry_ctime(ae));
    assertEqualString("dir", archive_entry_pathname(ae));
    assertEqualInt((S_IFDIR | 0755), archive_entry_mode(ae));
    assertEqualInt(0, archive_entry_size(ae));
    assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));

    /* Verify the end of the archive. */
    assertEqualIntA(a, 1, archive_read_next_header(a, &ae));
    assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
    assertEqualInt(ARCHIVE_OK, archive_read_free(a));

    free(buff);
}
コード例 #8
0
ファイル: pkg_add.c プロジェクト: juliandunn/pkg
int
pkg_add(struct pkgdb *db, const char *path, unsigned flags, struct pkg_manifest_key *keys)
{
	const char	*arch;
	const char	*origin;
	const char	*name;
	struct archive	*a;
	struct archive_entry *ae;
	struct pkg	*pkg = NULL;
	struct pkg_dep	*dep = NULL;
	struct pkg      *pkg_inst = NULL;
	bool		 extract = true;
	bool		 handle_rc = false;
	bool		 disable_mtree;
	char		 dpath[MAXPATHLEN];
	const char	*basedir;
	const char	*ext;
	char		*mtree;
	char		*prefix;
	int		 retcode = EPKG_OK;
	int		 ret;

	assert(path != NULL);

	/*
	 * Open the package archive file, read all the meta files and set the
	 * current archive_entry to the first non-meta file.
	 * If there is no non-meta files, EPKG_END is returned.
	 */
	ret = pkg_open2(&pkg, &a, &ae, path, keys, 0);
	if (ret == EPKG_END)
		extract = false;
	else if (ret != EPKG_OK) {
		retcode = ret;
		goto cleanup;
	}
	if ((flags & PKG_ADD_UPGRADE) == 0)
		pkg_emit_install_begin(pkg);

	if (pkg_is_valid(pkg) != EPKG_OK) {
		pkg_emit_error("the package is not valid");
		return (EPKG_FATAL);
	}

	if (flags & PKG_ADD_AUTOMATIC)
		pkg_set(pkg, PKG_AUTOMATIC, (int64_t)true);

	/*
	 * Check the architecture
	 */

	pkg_get(pkg, PKG_ARCH, &arch, PKG_ORIGIN, &origin, PKG_NAME, &name);

	if (!is_valid_abi(arch, true)) {
		if ((flags & PKG_ADD_FORCE) == 0) {
			retcode = EPKG_FATAL;
			goto cleanup;
		}
	}

	/*
	 * Check if the package is already installed
	 */

	ret = pkg_try_installed(db, origin, &pkg_inst, PKG_LOAD_BASIC);
	if (ret == EPKG_OK) {
		if ((flags & PKG_FLAG_FORCE) == 0) {
			pkg_emit_already_installed(pkg_inst);
			retcode = EPKG_INSTALLED;
			pkg_free(pkg_inst);
			pkg_inst = NULL;
			goto cleanup;
		}
		else {
			pkg_emit_notice("package %s is already installed, forced install", name);
			pkg_free(pkg_inst);
			pkg_inst = NULL;
		}
	} else if (ret != EPKG_END) {
		retcode = ret;
		goto cleanup;
	}

	/*
	 * Check for dependencies by searching the same directory as
	 * the package archive we're reading.  Of course, if we're
	 * reading from a file descriptor or a unix domain socket or
	 * somesuch, there's no valid directory to search.
	 */

	if (pkg_type(pkg) == PKG_FILE) {
		basedir = dirname(path);
		if ((ext = strrchr(path, '.')) == NULL) {
			pkg_emit_error("%s has no extension", path);
			retcode = EPKG_FATAL;
			goto cleanup;
		}
	} else {
		basedir = NULL;
		ext = NULL;
	}

	while (pkg_deps(pkg, &dep) == EPKG_OK) {
		if (pkg_is_installed(db, pkg_dep_origin(dep)) == EPKG_OK)
			continue;

		if (basedir != NULL) {
			const char *dep_name = pkg_dep_name(dep);
			const char *dep_ver = pkg_dep_version(dep);

			snprintf(dpath, sizeof(dpath), "%s/%s-%s%s", basedir,
			    dep_name, dep_ver, ext);

			if ((flags & PKG_ADD_UPGRADE) == 0 &&
			    access(dpath, F_OK) == 0) {
				ret = pkg_add(db, dpath, PKG_ADD_AUTOMATIC, keys);
				if (ret != EPKG_OK) {
					retcode = EPKG_FATAL;
					goto cleanup;
				}
			} else {
				pkg_emit_error("Missing dependency matching '%s'",
				    pkg_dep_get(dep, PKG_DEP_ORIGIN));
				retcode = EPKG_FATAL;
				goto cleanup;
			}
		} else {
			retcode = EPKG_FATAL;
			pkg_emit_missing_dep(pkg, dep);
			goto cleanup;
		}
	}

	/* register the package before installing it in case there are
	 * problems that could be caught here. */
	retcode = pkgdb_register_pkg(db, pkg, flags & PKG_ADD_UPGRADE, flags & PKG_FLAG_FORCE);

	if (retcode != EPKG_OK)
		goto cleanup;

	/* MTREE replicates much of the standard functionality
	 * inplicit in the way pkg works.  It has to remain available
	 * in the ports for compatibility with the old pkg_tools, but
	 * ultimately, MTREE should be made redundant.  Use this for
	 * experimantal purposes and to develop MTREE-free versions of
	 * packages. */

	pkg_config_bool(PKG_CONFIG_DISABLE_MTREE, &disable_mtree);
	if (!disable_mtree) {
		pkg_get(pkg, PKG_PREFIX, &prefix, PKG_MTREE, &mtree);
		if ((retcode = do_extract_mtree(mtree, prefix)) != EPKG_OK)
			goto cleanup_reg;
	}

	/*
	 * Execute pre-install scripts
	 */
	if ((flags & (PKG_ADD_NOSCRIPT | PKG_ADD_USE_UPGRADE_SCRIPTS)) == 0)
		pkg_script_run(pkg, PKG_SCRIPT_PRE_INSTALL);

	/* add the user and group if necessary */
	/* pkg_add_user_group(pkg); */

	/*
	 * Extract the files on disk.
	 */
	if (extract && (retcode = do_extract(a, ae)) != EPKG_OK) {
		/* If the add failed, clean up (silently) */
		pkg_delete_files(pkg, 2);
		pkg_delete_dirs(db, pkg, 1);
		goto cleanup_reg;
	}

	/*
	 * Execute post install scripts
	 */
	if ((flags & PKG_ADD_NOSCRIPT) == 0) {
		if ((flags & PKG_ADD_USE_UPGRADE_SCRIPTS) == PKG_ADD_USE_UPGRADE_SCRIPTS)
			pkg_script_run(pkg, PKG_SCRIPT_POST_UPGRADE);
		else
			pkg_script_run(pkg, PKG_SCRIPT_POST_INSTALL);
	}

	/*
	 * start the different related services if the users do want that
	 * and that the service is running
	 */

	pkg_config_bool(PKG_CONFIG_HANDLE_RC_SCRIPTS, &handle_rc);
	if (handle_rc)
		pkg_start_stop_rc_scripts(pkg, PKG_RC_START);

	cleanup_reg:
	if ((flags & PKG_ADD_UPGRADE) == 0)
		pkgdb_register_finale(db, retcode);

	if (retcode == EPKG_OK && (flags & PKG_ADD_UPGRADE) == 0)
		pkg_emit_install_finished(pkg);

	cleanup:
	if (a != NULL) {
		archive_read_close(a);
		archive_read_free(a);
	}

	pkg_free(pkg);

	if (pkg_inst != NULL)
		pkg_free(pkg_inst);

	return (retcode);
}
コード例 #9
0
/*
 * Verify our ability to read sample files created by Solaris pax for
 * a sparse file.
 */
static void
test_compat_solaris_pax_sparse_1(void)
{
	char name[] = "test_compat_solaris_pax_sparse_1.pax.Z";
	struct archive_entry *ae;
	struct archive *a;
	int64_t offset, length;
	const void *buff;
	size_t bytes_read;
	char data[1024*8];
	int r;

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

	/* Read first entry. */
	assertEqualIntA(a, ARCHIVE_OK, r = archive_read_next_header(a, &ae));
	if (r != ARCHIVE_OK) {
		archive_read_free(a);
		return;
	}
	assertEqualString("hole", archive_entry_pathname(ae));
	assertEqualInt(1310411683, archive_entry_mtime(ae));
	assertEqualInt(101, archive_entry_uid(ae));
	assertEqualString("cue", archive_entry_uname(ae));
	assertEqualInt(10, archive_entry_gid(ae));
	assertEqualString("staff", archive_entry_gname(ae));
	assertEqualInt(0100644, archive_entry_mode(ae));

	/* Verify the sparse information. */
	failure("This sparse file should have tree data blocks");
	assertEqualInt(3, archive_entry_sparse_reset(ae));
	assertEqualInt(ARCHIVE_OK,
	    archive_entry_sparse_next(ae, &offset, &length));
	assertEqualInt(0, offset);
	assertEqualInt(131072, length);
	assertEqualInt(ARCHIVE_OK,
	    archive_entry_sparse_next(ae, &offset, &length));
	assertEqualInt(393216, offset);
	assertEqualInt(131072, length);
	assertEqualInt(ARCHIVE_OK,
	    archive_entry_sparse_next(ae, &offset, &length));
	assertEqualInt(786432, offset);
	assertEqualInt(32775, length);
	while (ARCHIVE_OK ==
	    archive_read_data_block(a, &buff, &bytes_read, &offset)) {
		failure("The data blocks should not include the hole");
		assert((offset >= 0 && offset + bytes_read <= 131072) ||
		       (offset >= 393216 && offset + bytes_read <= 393216+131072) ||
		       (offset >= 786432 && offset + bytes_read <= 786432+32775));
		if (offset == 0 && bytes_read >= 1024*8) {
			memset(data, 'a', sizeof(data));
			failure("First data block should be 8K bytes of 'a'");
			assertEqualMem(buff, data, sizeof(data));
		} else if (offset + bytes_read == 819207 && bytes_read >= 7) {
			const char *last = buff;
			last += bytes_read - 7;
			memset(data, 'c', 7);
			failure("Last seven bytes should be all 'c'");
			assertEqualMem(last, data, 7);
		}
	}

	/* Verify the end-of-archive. */
	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));

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

	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
コード例 #10
0
ファイル: archive_read.c プロジェクト: bashow0316/freebsd
/*
 * Release memory and other resources.
 */
static int
_archive_read_free(struct archive *_a)
{
	struct archive_read *a = (struct archive_read *)_a;
	struct archive_read_passphrase *p;
	int i, n;
	int slots;
	int r = ARCHIVE_OK;

	if (_a == NULL)
		return (ARCHIVE_OK);
	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
	    ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_read_free");
	if (a->archive.state != ARCHIVE_STATE_CLOSED
	    && a->archive.state != ARCHIVE_STATE_FATAL)
		r = archive_read_close(&a->archive);

	/* Call cleanup functions registered by optional components. */
	if (a->cleanup_archive_extract != NULL)
		r = (a->cleanup_archive_extract)(a);

	/* Cleanup format-specific data. */
	slots = sizeof(a->formats) / sizeof(a->formats[0]);
	for (i = 0; i < slots; i++) {
		a->format = &(a->formats[i]);
		if (a->formats[i].cleanup)
			(a->formats[i].cleanup)(a);
	}

	/* Free the filters */
	__archive_read_free_filters(a);

	/* Release the bidder objects. */
	n = sizeof(a->bidders)/sizeof(a->bidders[0]);
	for (i = 0; i < n; i++) {
		if (a->bidders[i].free != NULL) {
			int r1 = (a->bidders[i].free)(&a->bidders[i]);
			if (r1 < r)
				r = r1;
		}
	}

	/* Release passphrase list. */
	p = a->passphrases.first;
	while (p != NULL) {
		struct archive_read_passphrase *np = p->next;

		/* A passphrase should be cleaned. */
		memset(p->passphrase, 0, strlen(p->passphrase));
		free(p->passphrase);
		free(p);
		p = np;
	}

	archive_string_free(&a->archive.error_string);
	archive_entry_free(a->entry);
	a->archive.magic = 0;
	__archive_clean(&a->archive);
	free(a->client.dataset);
	free(a);
	return (r);
}
コード例 #11
0
static void
test_filename(const char *prefix, int dlen, int flen)
{
	char buff[8192];
	char filename[400];
	char dirname[400];
	struct archive_entry *ae;
	struct archive *a;
	size_t used;
	int separator = 0;
	int i = 0;

	if (prefix != NULL) {
		strcpy(filename, prefix);
		i = (int)strlen(prefix);
	}
	if (dlen > 0) {
		for (; i < dlen; i++)
			filename[i] = 'a';
		filename[i++] = '/';
		separator = 1;
	}
	for (; i < dlen + flen + separator; i++)
		filename[i] = 'b';
	filename[i] = '\0';

	strcpy(dirname, filename);

	/* Create a new archive in memory. */
	assert((a = archive_write_new()) != NULL);
	assertA(0 == archive_write_set_format_ustar(a));
	assertA(0 == archive_write_set_compression_none(a));
	assertA(0 == archive_write_set_bytes_per_block(a,0));
	assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));

	/*
	 * Write a file to it.
	 */
	assert((ae = archive_entry_new()) != NULL);
	archive_entry_copy_pathname(ae, filename);
	archive_entry_set_mode(ae, S_IFREG | 0755);
	failure("dlen=%d, flen=%d", dlen, flen);
	if (flen > 100) {
		assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae));
	} else {
		assertEqualIntA(a, 0, archive_write_header(a, ae));
	}
	archive_entry_free(ae);

	/*
	 * Write a dir to it (without trailing '/').
	 */
	assert((ae = archive_entry_new()) != NULL);
	archive_entry_copy_pathname(ae, dirname);
	archive_entry_set_mode(ae, S_IFDIR | 0755);
	failure("dlen=%d, flen=%d", dlen, flen);
	if (flen >= 100) {
		assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae));
	} else {
		assertEqualIntA(a, 0, archive_write_header(a, ae));
	}
	archive_entry_free(ae);

	/* Tar adds a '/' to directory names. */
	strcat(dirname, "/");

	/*
	 * Write a dir to it (with trailing '/').
	 */
	assert((ae = archive_entry_new()) != NULL);
	archive_entry_copy_pathname(ae, dirname);
	archive_entry_set_mode(ae, S_IFDIR | 0755);
	failure("dlen=%d, flen=%d", dlen, flen);
	if (flen >= 100) {
		assertEqualIntA(a, ARCHIVE_FAILED, archive_write_header(a, ae));
	} else {
		assertEqualIntA(a, 0, archive_write_header(a, ae));
	}
	archive_entry_free(ae);

	/* Close out the archive. */
	assertA(0 == archive_write_close(a));
#if ARCHIVE_VERSION_NUMBER < 2000000
	archive_write_finish(a);
#else
	assertEqualInt(0, archive_write_finish(a));
#endif

	/*
	 * Now, read the data back.
	 */
	assert((a = archive_read_new()) != NULL);
	assertA(0 == archive_read_support_format_all(a));
	assertA(0 == archive_read_support_compression_all(a));
	assertA(0 == archive_read_open_memory(a, buff, used));

	if (flen <= 100) {
		/* Read the file and check the filename. */
		assertA(0 == archive_read_next_header(a, &ae));
		failure("dlen=%d, flen=%d", dlen, flen);
		assertEqualString(filename, archive_entry_pathname(ae));
		assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));
	}

	/*
	 * Read the two dirs and check the names.
	 *
	 * Both dirs should read back with the same name, since
	 * tar should add a trailing '/' to any dir that doesn't
	 * already have one.
	 */
	if (flen <= 99) {
		assertA(0 == archive_read_next_header(a, &ae));
		assert((S_IFDIR | 0755) == archive_entry_mode(ae));
		failure("dlen=%d, flen=%d", dlen, flen);
		assertEqualString(dirname, archive_entry_pathname(ae));
	}

	if (flen <= 99) {
		assertA(0 == archive_read_next_header(a, &ae));
		assert((S_IFDIR | 0755) == archive_entry_mode(ae));
		assertEqualString(dirname, archive_entry_pathname(ae));
	}

	/* Verify the end of the archive. */
	failure("This fails if entries were written that should not have been written.  dlen=%d, flen=%d", dlen, flen);
	assertEqualInt(1, archive_read_next_header(a, &ae));
	assert(0 == archive_read_close(a));
#if ARCHIVE_VERSION_NUMBER < 2000000
	archive_read_finish(a);
#else
	assertEqualInt(0, archive_read_finish(a));
#endif
}
コード例 #12
0
ファイル: update.c プロジェクト: CIAvash/pkgfile
static void archive_conv_close(struct archive_conv *conv) {
  archive_write_close(conv->out);
  archive_write_free(conv->out);
  archive_read_close(conv->in);
  archive_read_free(conv->in);
}
コード例 #13
0
ファイル: extract.c プロジェクト: liloman/PRoot
/**
 * Extract the archive stored at the given @path.  This function
 * returns -1 if an error occurred, otherwise 0.
 */
int extract_archive_from_file(const char *path)
{
    struct archive *archive = NULL;
    CallbackData *data = NULL;
    int status2;
    int status;

    archive = archive_read_new();
    if (archive == NULL) {
        note(NULL, ERROR, INTERNAL, "can't initialize archive structure");
        status = -1;
        goto end;
    }

    status = archive_read_support_format_cpio(archive);
    if (status != ARCHIVE_OK) {
        note(NULL, ERROR, INTERNAL, "can't set archive format: %s",
             archive_error_string(archive));
        status = -1;
        goto end;
    }

    status = archive_read_support_format_gnutar(archive);
    if (status != ARCHIVE_OK) {
        note(NULL, ERROR, INTERNAL, "can't set archive format: %s",
             archive_error_string(archive));
        status = -1;
        goto end;
    }

    status = archive_read_support_filter_gzip(archive);
    if (status != ARCHIVE_OK) {
        note(NULL, ERROR, INTERNAL, "can't add archive filter: %s",
             archive_error_string(archive));
        status = -1;
        goto end;
    }

    status = archive_read_support_filter_lzop(archive);
    if (status != ARCHIVE_OK) {
        note(NULL, ERROR, INTERNAL, "can't add archive filter: %s",
             archive_error_string(archive));
        status = -1;
        goto end;
    }

    data = talloc_zero(NULL, CallbackData);
    if (data == NULL) {
        note(NULL, ERROR, INTERNAL, "can't allocate callback data");
        status = -1;
        goto end;

    }

    data->path = talloc_strdup(data, path);
    if (data->path == NULL) {
        note(NULL, ERROR, INTERNAL, "can't allocate callback data path");
        status = -1;
        goto end;

    }

    status = archive_read_open(archive, data, open_callback, read_callback, close_callback);
    if (status != ARCHIVE_OK) {
        /* Don't complain if no error message were registered,
         * ie. when testing for a self-extracting archive.  */
        if (archive_error_string(archive) != NULL)
            note(NULL, ERROR, INTERNAL, "can't read archive: %s",
                 archive_error_string(archive));
        status = -1;
        goto end;
    }

    status = extract_archive(archive);
end:
    if (archive != NULL) {
        status2 = archive_read_close(archive);
        if (status2 != ARCHIVE_OK) {
            note(NULL, WARNING, INTERNAL, "can't close archive: %s",
                 archive_error_string(archive));
        }

        status2 = archive_read_free(archive);
        if (status2 != ARCHIVE_OK) {
            note(NULL, WARNING, INTERNAL, "can't free archive: %s",
                 archive_error_string(archive));
        }
    }

    TALLOC_FREE(data);

    return status;
}
コード例 #14
0
ファイル: untar.c プロジェクト: sajjadG/cpp-code-snippets
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);
	archive_read_support_format_all(a);
  	archive_read_support_compression_all(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_file(a, filename, 10240)))
		fail("archive_read_open_file()",
		    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);
}
コード例 #15
0
/*
 * test_compat_gtar_1.tgz exercises reading long filenames and
 * symlink targets stored in the GNU tar format.
 */
static void
test_compat_gtar_1(void)
{
    char name[] = "test_compat_gtar_1.tar";
    struct archive_entry *ae;
    struct archive *a;
    int r;

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

    /* Read first entry. */
    assertEqualIntA(a, ARCHIVE_OK, r = archive_read_next_header(a, &ae));
    if (r != ARCHIVE_OK) {
        archive_read_free(a);
        return;
    }
    assertEqualString(
        "12345678901234567890123456789012345678901234567890"
        "12345678901234567890123456789012345678901234567890"
        "12345678901234567890123456789012345678901234567890"
        "12345678901234567890123456789012345678901234567890",
        archive_entry_pathname(ae));
    assertEqualInt(1197179003, archive_entry_mtime(ae));
    assertEqualInt(1000, archive_entry_uid(ae));
    assertEqualString("tim", archive_entry_uname(ae));
    assertEqualInt(1000, archive_entry_gid(ae));
    assertEqualString("tim", archive_entry_gname(ae));
    assertEqualInt(0100644, archive_entry_mode(ae));

    /* Read second entry. */
    assertEqualIntA(a, ARCHIVE_OK, r = archive_read_next_header(a, &ae));
    if (r != ARCHIVE_OK) {
        archive_read_free(a);
        return;
    }
    assertEqualString(
        "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij"
        "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij"
        "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij"
        "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghij",
        archive_entry_pathname(ae));
    assertEqualString(
        "12345678901234567890123456789012345678901234567890"
        "12345678901234567890123456789012345678901234567890"
        "12345678901234567890123456789012345678901234567890"
        "12345678901234567890123456789012345678901234567890",
        archive_entry_symlink(ae));
    assertEqualInt(1197179043, archive_entry_mtime(ae));
    assertEqualInt(1000, archive_entry_uid(ae));
    assertEqualString("tim", archive_entry_uname(ae));
    assertEqualInt(1000, archive_entry_gid(ae));
    assertEqualString("tim", archive_entry_gname(ae));
    assertEqualInt(0120755, archive_entry_mode(ae));

    /* Verify the end-of-archive. */
    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_GNUTAR);

    assertEqualInt(ARCHIVE_OK, archive_read_close(a));
    assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
コード例 #16
0
/**
 * Issue 152: A file generated by a tool that doesn't really
 * believe in populating local file headers at all.  This
 * is only readable with the seeking reader.
 */
static void
test_compat_zip_5(void)
{
	const char *refname = "test_compat_zip_5.zip";
	struct archive_entry *ae;
	struct archive *a;
	void *p;
	size_t s;

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

	/* Verify with seek support.
	 * Everything works correctly here. */
	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_seek(a, p, s, 18));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("Metadata/Job_PT.xml", archive_entry_pathname(ae));
	assertEqualInt(3559, archive_entry_size(ae));
	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
	assertEqualInt(0666, archive_entry_perm(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("Metadata/MXDC_Empty_PT.xml", archive_entry_pathname(ae));
	assertEqualInt(456, archive_entry_size(ae));
	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
	assertEqualInt(0666, archive_entry_perm(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("Documents/1/Metadata/Page1_Thumbnail.JPG", archive_entry_pathname(ae));
	assertEqualInt(1495, archive_entry_size(ae));
	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
	assertEqualInt(0666, archive_entry_perm(ae));
	/* TODO: Read some of the file data and verify it.
	   The code to read uncompressed Zip entries with "file at end" semantics
	   is tricky and should be verified more carefully. */

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("Documents/1/Pages/_rels/1.fpage.rels", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("Documents/1/Pages/1.fpage", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("Documents/1/Resources/Fonts/3DFDBC8B-4514-41F1-A808-DEA1C79BAC2B.odttf", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("Documents/1/_rels/FixedDocument.fdoc.rels", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("Documents/1/FixedDocument.fdoc", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("_rels/FixedDocumentSequence.fdseq.rels", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("FixedDocumentSequence.fdseq", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("_rels/.rels", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("[Content_Types].xml", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));

	/* Try reading without seek support. */
	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, 3));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("Metadata/Job_PT.xml", archive_entry_pathname(ae));
	assertEqualInt(0, archive_entry_size(ae));
	assert(!archive_entry_size_is_set(ae));
	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
	assertEqualInt(0666, archive_entry_perm(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("Metadata/MXDC_Empty_PT.xml", archive_entry_pathname(ae));
	assertEqualInt(0, archive_entry_size(ae));
	assert(!archive_entry_size_is_set(ae));
	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
	assertEqualInt(0666, archive_entry_perm(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("Documents/1/Metadata/Page1_Thumbnail.JPG", archive_entry_pathname(ae));
	assertEqualInt(0, archive_entry_size(ae));
	assert(!archive_entry_size_is_set(ae));
	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
	assertEqualInt(0666, archive_entry_perm(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("Documents/1/Pages/_rels/1.fpage.rels", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("Documents/1/Pages/1.fpage", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("Documents/1/Resources/Fonts/3DFDBC8B-4514-41F1-A808-DEA1C79BAC2B.odttf", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("Documents/1/_rels/FixedDocument.fdoc.rels", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("Documents/1/FixedDocument.fdoc", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("_rels/FixedDocumentSequence.fdseq.rels", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("FixedDocumentSequence.fdseq", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("_rels/.rels", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("[Content_Types].xml", archive_entry_pathname(ae));

	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
	free(p);
}
コード例 #17
0
ファイル: archive_handler.c プロジェクト: sbabic/swupdate
static void *
extract(void *p)
{
	locale_t archive_locale;
	locale_t old_locale;
	struct archive *a;
	struct archive *ext = NULL;
	struct archive_entry *entry = NULL;
	int r;
	int flags;
	struct extract_data *data = (struct extract_data *)p;
	flags = data->flags;
	int exitval = -EFAULT;

	/*
	 * Enable system locale - change from the standard (C) to system locale.
	 * This allows libarchive (in case it is activated) to handle filenames.
	 * We only change LC_CTYPE since libarchive only needs the charset set.
	 * We don't use LC_ALL because it causes problems on some systems.
	 * We restore the original LC_CTYPE after extraction to avoid side effects.
	 * We use uselocale instead of setlocale to avoid setting LC_CTYPE globally.
	 * See on libarchive Website for a more complete description of the issue:
	 *  https://github.com/libarchive/libarchive/issues/587
	 *  https://github.com/libarchive/libarchive/wiki/Filenames
	 */
	archive_locale = newlocale(LC_CTYPE_MASK, "", (locale_t)0);
	old_locale = uselocale(archive_locale);

	a = archive_read_new();
	if (!a) {
		goto out;
	}

	ext = archive_write_disk_new();
	if (!ext) {
		goto out;
	}

	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_all(a);
	archive_read_support_filter_all(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.
	 */
	char* FIFO = alloca(strlen(get_tmpdir())+strlen(FIFO_FILE_NAME)+1);
	sprintf(FIFO, "%s%s", get_tmpdir(), FIFO_FILE_NAME);
	if ((r = archive_read_open_filename(a, FIFO, 4096))) {
		ERROR("archive_read_open_filename(): %s %d",
		    archive_error_string(a), r);
		goto out;
	}
	for (;;) {
		r = archive_read_next_header(a, &entry);
		if (r == ARCHIVE_EOF)
			break;
		if (r != ARCHIVE_OK) {
			ERROR("archive_read_next_header(): %s %d",
			    archive_error_string(a), 1);
			goto out;
		}

		if (debug)
			TRACE("Extracting %s", archive_entry_pathname(entry));

		r = archive_write_header(ext, entry);
		if (r != ARCHIVE_OK)
			TRACE("archive_write_header(): %s",
			    archive_error_string(ext));
		else {
			copy_data(a, ext);
			r = archive_write_finish_entry(ext);
			if (r != ARCHIVE_OK)  {
				ERROR("archive_write_finish_entry(): %s",
				    archive_error_string(ext));
				goto out;
			}
		}

	}

	exitval = 0;

out:
	if (ext) {
		r = archive_write_free(ext);
		if (r) {
			ERROR("archive_write_free(): %s %d",
					archive_error_string(a), r);
			exitval = -EFAULT;
		}
	}

	if (a) {
		archive_read_close(a);
		archive_read_free(a);
	}

	uselocale(old_locale);
	data->exitval = exitval;
	pthread_exit(NULL);
}
コード例 #18
0
ファイル: vesKiwiArchiveUtils.cpp プロジェクト: 151706061/ves
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;

}
コード例 #19
0
ファイル: test_fuzz.c プロジェクト: 0xffffffRabbit/NextBSD-1
static void
test_fuzz(const struct files *filesets)
{
	const void *blk;
	size_t blk_size;
	int64_t blk_offset;
	int n;

	for (n = 0; filesets[n].names != NULL; ++n) {
		const size_t buffsize = 30000000;
		struct archive_entry *ae;
		struct archive *a;
		char *rawimage = NULL, *image = NULL, *tmp = NULL;
		size_t size = 0, oldsize = 0;
		int i, q;

		extract_reference_files(filesets[n].names);
		if (filesets[n].uncompress) {
			int r;
			/* Use format_raw to decompress the data. */
			assert((a = archive_read_new()) != NULL);
			assertEqualIntA(a, ARCHIVE_OK,
			    archive_read_support_filter_all(a));
			assertEqualIntA(a, ARCHIVE_OK,
			    archive_read_support_format_raw(a));
			r = archive_read_open_filenames(a, filesets[n].names, 16384);
			if (r != ARCHIVE_OK) {
				archive_read_free(a);
				if (filesets[n].names[0] == NULL || filesets[n].names[1] == NULL) {
					skipping("Cannot uncompress fileset");
				} else {
					skipping("Cannot uncompress %s", filesets[n].names[0]);
				}
				continue;
			}
			assertEqualIntA(a, ARCHIVE_OK,
			    archive_read_next_header(a, &ae));
			rawimage = malloc(buffsize);
			size = archive_read_data(a, rawimage, buffsize);
			assertEqualIntA(a, ARCHIVE_EOF,
			    archive_read_next_header(a, &ae));
			assertEqualInt(ARCHIVE_OK,
			    archive_read_free(a));
			assert(size > 0);
			if (filesets[n].names[0] == NULL || filesets[n].names[1] == NULL) {
				failure("Internal buffer is not big enough for "
					"uncompressed test files");
			} else {
				failure("Internal buffer is not big enough for "
					"uncompressed test file: %s", filesets[n].names[0]);
			}
			if (!assert(size < buffsize)) {
				free(rawimage);
				continue;
			}
		} else {
			for (i = 0; filesets[n].names[i] != NULL; ++i)
			{
				tmp = slurpfile(&size, filesets[n].names[i]);
				rawimage = (char *)realloc(rawimage, oldsize + size);
				memcpy(rawimage + oldsize, tmp, size);
				oldsize += size;
				size = oldsize;
				free(tmp);
				if (!assert(rawimage != NULL))
					continue;
			}
		}
		if (size == 0)
			continue;
		image = malloc(size);
		assert(image != NULL);
		if (image == NULL) {
			free(rawimage);
			return;
		}
		srand((unsigned)time(NULL));

		for (i = 0; i < 1000; ++i) {
			FILE *f;
			int j, numbytes, trycnt;

			/* Fuzz < 1% of the bytes in the archive. */
			memcpy(image, rawimage, size);
			q = (int)size / 100;
			if (q < 4)
				q = 4;
			numbytes = (int)(rand() % q);
			for (j = 0; j < numbytes; ++j)
				image[rand() % size] = (char)rand();

			/* Save the messed-up image to a file.
			 * If we crash, that file will be useful. */
			for (trycnt = 0; trycnt < 3; trycnt++) {
				f = fopen("after.test.failure.send.this.file."
				    "to.libarchive.maintainers.with.system.details", "wb");
				if (f != NULL)
					break;
#if defined(_WIN32) && !defined(__CYGWIN__)
				/*
				 * Sometimes previous close operation does not completely
				 * end at this time. So we should take a wait while
				 * the operation running.
				 */
				Sleep(100);
#endif
			}
			assertEqualInt((size_t)size, fwrite(image, 1, (size_t)size, f));
			fclose(f);

			// Try to read all headers and bodies.
			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 (0 == archive_read_open_memory(a, image, size)) {
				while(0 == archive_read_next_header(a, &ae)) {
					while (0 == archive_read_data_block(a,
						&blk, &blk_size, &blk_offset))
						continue;
				}
				archive_read_close(a);
			}
			archive_read_free(a);

			// Just list headers, skip bodies.
			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 (0 == archive_read_open_memory(a, image, size)) {
				while(0 == archive_read_next_header(a, &ae)) {
				}
				archive_read_close(a);
			}
			archive_read_free(a);
}
		free(image);
		free(rawimage);
	}
}
コード例 #20
0
static void
verify_contents(struct archive *a, int expect_details)
{
    char filedata[64];
    struct archive_entry *ae;

    /*
     * Read and verify first file.
     */
    assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
    assertEqualInt(1, archive_entry_mtime(ae));
    /* Zip doesn't store high-resolution mtime. */
    assertEqualInt(0, archive_entry_mtime_nsec(ae));
    assertEqualInt(0, archive_entry_atime(ae));
    assertEqualInt(0, archive_entry_ctime(ae));
    assertEqualString("file", archive_entry_pathname(ae));
    if (expect_details) {
        assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
        assertEqualInt(8, archive_entry_size(ae));
    } else {
        assertEqualInt(0, archive_entry_size(ae));
    }
    assertEqualIntA(a, 8,
                    archive_read_data(a, filedata, sizeof(filedata)));
    assertEqualMem(filedata, "12345678", 8);


    /*
     * Read the second file back.
     */
    assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
    assertEqualInt(1, archive_entry_mtime(ae));
    assertEqualInt(0, archive_entry_mtime_nsec(ae));
    assertEqualInt(0, archive_entry_atime(ae));
    assertEqualInt(0, archive_entry_ctime(ae));
    assertEqualString("file2", archive_entry_pathname(ae));
    if (expect_details) {
        assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
        assertEqualInt(4, archive_entry_size(ae));
    } else {
        assertEqualInt(0, archive_entry_size(ae));
    }
    assertEqualIntA(a, 4,
                    archive_read_data(a, filedata, sizeof(filedata)));
    assertEqualMem(filedata, "1234", 4);

    /*
     * Read the third file back.
     */
    assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
    assertEqualInt(1, archive_entry_mtime(ae));
    assertEqualInt(0, archive_entry_mtime_nsec(ae));
    assertEqualInt(0, archive_entry_atime(ae));
    assertEqualInt(0, archive_entry_ctime(ae));
    assertEqualString("symlink", archive_entry_pathname(ae));
    if (expect_details) {
        assertEqualInt(AE_IFLNK | 0755, archive_entry_mode(ae));
        assertEqualInt(0, archive_entry_size(ae));
        assertEqualString("file1", archive_entry_symlink(ae));
    } else {
        assertEqualInt(AE_IFREG | 0666, archive_entry_mode(ae));
        assertEqualInt(0, archive_entry_size(ae));
    }

    /*
     * Read the dir entry back.
     */
    assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
    assertEqualInt(11, archive_entry_mtime(ae));
    assertEqualInt(0, archive_entry_mtime_nsec(ae));
    assertEqualInt(0, archive_entry_atime(ae));
    assertEqualInt(0, archive_entry_ctime(ae));
    assertEqualString("dir/", archive_entry_pathname(ae));
    if (expect_details)
        assertEqualInt(AE_IFDIR | 0755, archive_entry_mode(ae));
    assertEqualInt(0, archive_entry_size(ae));
    assertEqualIntA(a, 0, archive_read_data(a, filedata, 10));

    /* Verify the end of the archive. */
    assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
    assertEqualInt(ARCHIVE_OK, archive_read_close(a));
    assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
コード例 #21
0
ファイル: unzip.c プロジェクト: AhmadTux/freebsd
/*
 * Main loop: open the zipfile, iterate over its contents and decide what
 * to do with each entry.
 */
static void
unzip(const char *fn)
{
	struct archive *a;
	struct archive_entry *e;
	int fd, ret;
	uintmax_t total_size, file_count, error_count;

	if (strcmp(fn, "-") == 0)
		fd = STDIN_FILENO;
	else if ((fd = open(fn, O_RDONLY)) < 0)
		error("%s", fn);

	if ((a = archive_read_new()) == NULL)
		error("archive_read_new failed");

	ac(archive_read_support_format_zip(a));
	ac(archive_read_open_fd(a, fd, 8192));

	if (!zipinfo_mode) {
		if (!p_opt && !q_opt)
			printf("Archive:  %s\n", fn);
		if (v_opt == 1) {
			printf("  Length     Date   Time    Name\n");
			printf(" --------    ----   ----    ----\n");
		} else if (v_opt == 2) {
			printf(" Length   Method    Size  Ratio   Date   Time   CRC-32    Name\n");
			printf("--------  ------  ------- -----   ----   ----   ------    ----\n");
		}
	}

	total_size = 0;
	file_count = 0;
	error_count = 0;
	for (;;) {
		ret = archive_read_next_header(a, &e);
		if (ret == ARCHIVE_EOF)
			break;
		ac(ret);
		if (!zipinfo_mode) {
			if (t_opt)
				error_count += test(a, e);
			else if (v_opt)
				list(a, e);
			else if (p_opt || c_opt)
				extract_stdout(a, e);
			else
				extract(a, e);
		} else {
			if (Z1_opt)
				list(a, e);
		}

		total_size += archive_entry_size(e);
		++file_count;
	}

	if (zipinfo_mode) {
		if (v_opt == 1) {
			printf(" --------                   -------\n");
			printf(" %8ju                   %ju file%s\n",
			    total_size, file_count, file_count != 1 ? "s" : "");
		} else if (v_opt == 2) {
			printf("--------          -------  ---                            -------\n");
			printf("%8ju          %7ju   0%%                            %ju file%s\n",
			    total_size, total_size, file_count,
			    file_count != 1 ? "s" : "");
		}
	}

	ac(archive_read_close(a));
	(void)archive_read_finish(a);

	if (fd != STDIN_FILENO && close(fd) != 0)
		error("%s", fn);

	if (t_opt) {
		if (error_count > 0) {
			errorx("%d checksum error(s) found.", error_count);
		}
		else {
			printf("No errors detected in compressed data of %s.\n",
			       fn);
		}
	}
}
コード例 #22
0
ファイル: read.c プロジェクト: coyizumi/cs111
/*
 * 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, 0, "%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)
            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, 0, "%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, 0, "%s",
                            archive_error_string(a));
        }
    }
    AC(archive_read_close(a));
    AC(archive_read_free(a));
}
コード例 #23
0
static void
test_open_filename_mbs(void)
{
	char buff[64];
	struct archive_entry *ae;
	struct archive *a;

	/* Write an archive through this FILE *. */
	assert((a = archive_write_new()) != NULL);
	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_none(a));
	assertEqualIntA(a, ARCHIVE_OK,
	    archive_write_open_filename(a, "test.tar"));

	/*
	 * Write a file to it.
	 */
	assert((ae = archive_entry_new()) != NULL);
	archive_entry_set_mtime(ae, 1, 0);
	archive_entry_copy_pathname(ae, "file");
	archive_entry_set_mode(ae, S_IFREG | 0755);
	archive_entry_set_size(ae, 8);
	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
	archive_entry_free(ae);
	assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9));

	/*
	 * Write a second file to it.
	 */
	assert((ae = archive_entry_new()) != NULL);
	archive_entry_copy_pathname(ae, "file2");
	archive_entry_set_mode(ae, S_IFREG | 0755);
	archive_entry_set_size(ae, 819200);
	assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae));
	archive_entry_free(ae);

	/* Close out the archive. */
	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/*
	 * Now, read the data back.
	 */
	assert((a = archive_read_new()) != NULL);
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
	assertEqualIntA(a, ARCHIVE_OK,
	    archive_read_open_filename(a, "test.tar", 512));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualInt(1, archive_entry_mtime(ae));
	assertEqualInt(0, archive_entry_mtime_nsec(ae));
	assertEqualInt(0, archive_entry_atime(ae));
	assertEqualInt(0, archive_entry_ctime(ae));
	assertEqualString("file", archive_entry_pathname(ae));
	assert((S_IFREG | 0755) == archive_entry_mode(ae));
	assertEqualInt(8, archive_entry_size(ae));
	assertEqualIntA(a, 8, archive_read_data(a, buff, 10));
	assertEqualMem(buff, "12345678", 8);

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("file2", archive_entry_pathname(ae));
	assert((S_IFREG | 0755) == archive_entry_mode(ae));
	assertEqualInt(819200, archive_entry_size(ae));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a));

	/* Verify the end of the archive. */
	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));

	/*
	 * Verify some of the error handling.
	 */
	assert((a = archive_read_new()) != NULL);
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a));
	assertEqualIntA(a, ARCHIVE_FATAL,
	    archive_read_open_filename(a, "nonexistent.tar", 512));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));

}
コード例 #24
0
/*
 * Extract a mixed archive file which has both LZMA and LZMA2 encoded files.
 *  LZMA: file1, file2, file3, file4
 *  LZMA2: zfile1, zfile2, zfile3, zfile4
 */
static void
test_extract_all_files2(const char *refname)
{
	struct archive_entry *ae;
	struct archive *a;
	char buff[128];

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

	/* Verify regular file1. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
	assertEqualString("dir1/file1", archive_entry_pathname(ae));
	assertEqualInt(86401, archive_entry_mtime(ae));
	assertEqualInt(13, archive_entry_size(ae));
	assertEqualInt(13, archive_read_data(a, buff, sizeof(buff)));
	assertEqualMem(buff, "aaaaaaaaaaaa\n", 13);

	/* Verify regular file2. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
	assertEqualString("file2", archive_entry_pathname(ae));
	assertEqualInt(86401, archive_entry_mtime(ae));
	assertEqualInt(26, archive_entry_size(ae));
	assertEqualInt(26, archive_read_data(a, buff, sizeof(buff)));
	assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\n", 26);

	/* Verify regular file3. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
	assertEqualString("file3", archive_entry_pathname(ae));
	assertEqualInt(86401, archive_entry_mtime(ae));
	assertEqualInt(39, archive_entry_size(ae));
	assertEqualInt(39, archive_read_data(a, buff, sizeof(buff)));
	assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\n", 39);

	/* Verify regular file4. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
	assertEqualString("file4", archive_entry_pathname(ae));
	assertEqualInt(86401, archive_entry_mtime(ae));
	assertEqualInt(52, archive_entry_size(ae));
	assertEqualInt(52, archive_read_data(a, buff, sizeof(buff)));
	assertEqualMem(buff,
	    "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\ndddddddddddd\n", 52);

	/* Verify regular zfile1. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
	assertEqualString("dir1/zfile1", archive_entry_pathname(ae));
	assertEqualInt(5184001, archive_entry_mtime(ae));
	assertEqualInt(13, archive_entry_size(ae));
	assertEqualInt(13, archive_read_data(a, buff, sizeof(buff)));
	assertEqualMem(buff, "aaaaaaaaaaaa\n", 13);

	/* Verify regular zfile2. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
	assertEqualString("zfile2", archive_entry_pathname(ae));
	assertEqualInt(5184001, archive_entry_mtime(ae));
	assertEqualInt(26, archive_entry_size(ae));
	assertEqualInt(26, archive_read_data(a, buff, sizeof(buff)));
	assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\n", 26);

	/* Verify regular zfile3. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
	assertEqualString("zfile3", archive_entry_pathname(ae));
	assertEqualInt(5184001, archive_entry_mtime(ae));
	assertEqualInt(39, archive_entry_size(ae));
	assertEqualInt(39, archive_read_data(a, buff, sizeof(buff)));
	assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\n", 39);

	/* Verify regular zfile4. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
	assertEqualString("zfile4", archive_entry_pathname(ae));
	assertEqualInt(5184001, archive_entry_mtime(ae));
	assertEqualInt(52, archive_entry_size(ae));
	assertEqualInt(52, archive_read_data(a, buff, sizeof(buff)));
	assertEqualMem(buff,
	    "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\ndddddddddddd\n", 52);

	/* Verify directory dir1. */
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae));
	assertEqualString("dir1/", archive_entry_pathname(ae));
	assertEqualInt(2764801, archive_entry_mtime(ae));

	assertEqualInt(9, archive_file_count(a));

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

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

	/* Close the archive. */
	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
コード例 #25
0
ファイル: cpio.c プロジェクト: edgar-pek/PerspicuOS
static void
mode_in(struct cpio *cpio)
{
	struct archive *a;
	struct archive_entry *entry;
	struct archive *ext;
	const char *destpath;
	int r;

	ext = archive_write_disk_new();
	if (ext == NULL)
		lafe_errc(1, 0, "Couldn't allocate restore object");
	r = archive_write_disk_set_options(ext, cpio->extract_flags);
	if (r != ARCHIVE_OK)
		lafe_errc(1, 0, "%s", archive_error_string(ext));
	a = archive_read_new();
	if (a == NULL)
		lafe_errc(1, 0, "Couldn't allocate archive object");
	archive_read_support_compression_all(a);
	archive_read_support_format_all(a);

	if (archive_read_open_file(a, cpio->filename, cpio->bytes_per_block))
		lafe_errc(1, archive_errno(a),
		    "%s", archive_error_string(a));
	for (;;) {
		r = archive_read_next_header(a, &entry);
		if (r == ARCHIVE_EOF)
			break;
		if (r != ARCHIVE_OK) {
			lafe_errc(1, archive_errno(a),
			    "%s", archive_error_string(a));
		}
		if (lafe_excluded(cpio->matching, archive_entry_pathname(entry)))
			continue;
		if (cpio->option_rename) {
			destpath = cpio_rename(archive_entry_pathname(entry));
			archive_entry_set_pathname(entry, destpath);
		} else
			destpath = archive_entry_pathname(entry);
		if (destpath == NULL)
			continue;
		if (cpio->verbose)
			fprintf(stdout, "%s\n", destpath);
		if (cpio->uid_override >= 0)
			archive_entry_set_uid(entry, cpio->uid_override);
		if (cpio->gid_override >= 0)
			archive_entry_set_gid(entry, cpio->gid_override);
		r = archive_write_header(ext, entry);
		if (r != ARCHIVE_OK) {
			fprintf(stderr, "%s: %s\n",
			    archive_entry_pathname(entry),
			    archive_error_string(ext));
		} else if (archive_entry_size(entry) > 0) {
			r = extract_data(a, ext);
			if (r != ARCHIVE_OK)
				cpio->return_value = 1;
		}
	}
	r = archive_read_close(a);
	if (r != ARCHIVE_OK)
		lafe_errc(1, 0, "%s", archive_error_string(a));
	r = archive_write_close(ext);
	if (r != ARCHIVE_OK)
		lafe_errc(1, 0, "%s", archive_error_string(ext));
	if (!cpio->quiet) {
		int64_t blocks = (archive_position_uncompressed(a) + 511)
			      / 512;
		fprintf(stderr, "%lu %s\n", (unsigned long)blocks,
		    blocks == 1 ? "block" : "blocks");
	}
	archive_read_finish(a);
	archive_write_finish(ext);
	exit(cpio->return_value);
}
コード例 #26
0
bool LibArchiveInterface::copyFiles(const QVariantList& files, const QString& destinationDirectory, ExtractionOptions options)
{
    kDebug() << "Changing current directory to " << destinationDirectory;
    QDir::setCurrent(destinationDirectory);

    const bool extractAll = files.isEmpty();
    const bool preservePaths = options.value(QLatin1String( "PreservePaths" )).toBool();

    QString rootNode = options.value(QLatin1String("RootNode"), QVariant()).toString();
    if ((!rootNode.isEmpty()) && (!rootNode.endsWith(QLatin1Char('/')))) {
        rootNode.append(QLatin1Char('/'));
    }

    ArchiveRead arch(archive_read_new());

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

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

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

    if (archive_read_open_filename(arch.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;
    }

    ArchiveWrite writer(archive_write_disk_new());
    if (!(writer.data())) {
        return false;
    }

    archive_write_disk_set_options(writer.data(), extractionFlags());

    int entryNr = 0;
    int totalCount = 0;

    if (extractAll) {
        if (!m_cachedArchiveEntryCount) {
            emit progress(0);
            //TODO: once information progress has been implemented, send
            //feedback here that the archive is being read
            kDebug() << "For getting progress information, the archive will be listed once";
            m_emitNoEntries = true;
            list();
            m_emitNoEntries = false;
        }
        totalCount = m_cachedArchiveEntryCount;
    } else {
        totalCount = files.size();
    }

    m_currentExtractedFilesSize = 0;

    bool overwriteAll = false; // Whether to overwrite all files
    bool skipAll = false; // Whether to skip all files
    struct archive_entry *entry;

    QString fileBeingRenamed;

    while (archive_read_next_header(arch.data(), &entry) == ARCHIVE_OK) {
        fileBeingRenamed.clear();

        // retry with renamed entry, fire an overwrite query again
        // if the new entry also exists
    retry:
        const bool entryIsDir = S_ISDIR(archive_entry_mode(entry));

        //we skip directories if not preserving paths
        if (!preservePaths && entryIsDir) {
            archive_read_data_skip(arch.data());
            continue;
        }

        //entryName is the name inside the archive, full path
        QString entryName = QDir::fromNativeSeparators(QFile::decodeName(archive_entry_pathname(entry)));

        if (entryName.startsWith(QLatin1Char( '/' ))) {
            //for now we just can't handle absolute filenames in a tar archive.
            //TODO: find out what to do here!!
            emit error(i18n("This archive contains archive entries with absolute paths, which are not yet supported by ark."));

            return false;
        }

        if (files.contains(entryName) || entryName == fileBeingRenamed || extractAll) {
            // entryFI is the fileinfo pointing to where the file will be
            // written from the archive
            QFileInfo entryFI(entryName);
            //kDebug() << "setting path to " << archive_entry_pathname( entry );

            const QString fileWithoutPath(entryFI.fileName());

            //if we DON'T preserve paths, we cut the path and set the entryFI
            //fileinfo to the one without the path
            if (!preservePaths) {
                //empty filenames (ie dirs) should have been skipped already,
                //so asserting
                Q_ASSERT(!fileWithoutPath.isEmpty());

                archive_entry_copy_pathname(entry, QFile::encodeName(fileWithoutPath).constData());
                entryFI = QFileInfo(fileWithoutPath);

                //OR, if the commonBase has been set, then we remove this
                //common base from the filename
            } else if (!rootNode.isEmpty()) {
                kDebug() << "Removing" << rootNode << "from" << entryName;

                const QString truncatedFilename(entryName.remove(0, rootNode.size()));
                archive_entry_copy_pathname(entry, QFile::encodeName(truncatedFilename).constData());

                entryFI = QFileInfo(truncatedFilename);
            }

            //now check if the file about to be written already exists
            if (!entryIsDir && entryFI.exists()) {
                if (skipAll) {
                    archive_read_data_skip(arch.data());
                    archive_entry_clear(entry);
                    continue;
                } else if (!overwriteAll && !skipAll) {
                    Kerfuffle::OverwriteQuery query(entryName);
                    emit userQuery(&query);
                    query.waitForResponse();

                    if (query.responseCancelled()) {
                        archive_read_data_skip(arch.data());
                        archive_entry_clear(entry);
                        break;
                    } else if (query.responseSkip()) {
                        archive_read_data_skip(arch.data());
                        archive_entry_clear(entry);
                        continue;
                    } else if (query.responseAutoSkip()) {
                        archive_read_data_skip(arch.data());
                        archive_entry_clear(entry);
                        skipAll = true;
                        continue;
                    } else if (query.responseRename()) {
                        const QString newName(query.newFilename());
                        fileBeingRenamed = newName;
                        archive_entry_copy_pathname(entry, QFile::encodeName(newName).constData());
                        goto retry;
                    } else if (query.responseOverwriteAll()) {
                        overwriteAll = true;
                    }
                }
            }

            //if there is an already existing directory:
            if (entryIsDir && entryFI.exists()) {
                if (entryFI.isWritable()) {
                    kDebug(1601) << "Warning, existing, but writable dir";
                } else {
                    kDebug(1601) << "Warning, existing, but non-writable dir. skipping";
                    archive_entry_clear(entry);
                    archive_read_data_skip(arch.data());
                    continue;
                }
            }

            int header_response;
            kDebug() << "Writing " << fileWithoutPath << " to " << archive_entry_pathname(entry);
            if ((header_response = archive_write_header(writer.data(), entry)) == ARCHIVE_OK) {
                //if the whole archive is extracted and the total filesize is
                //available, we use partial progress
                copyData(arch.data(), writer.data(), (extractAll && m_extractedFilesSize));
            } else if (header_response == ARCHIVE_WARN) {
                kDebug() << "Warning while writing " << entryName;
            } else {
                kDebug() << "Writing header failed with error code " << header_response
                << "While attempting to write " << entryName;
            }

            //if we only partially extract the archive and the number of
            //archive entries is available we use a simple progress based on
            //number of items extracted
            if (!extractAll && m_cachedArchiveEntryCount) {
                ++entryNr;
                emit progress(float(entryNr) / totalCount);
            }
            archive_entry_clear(entry);
        } else {
            archive_read_data_skip(arch.data());
        }
    }

    return archive_read_close(arch.data()) == ARCHIVE_OK;
}
コード例 #27
0
/*
 * Apple shipped a customized version of bsdtar starting with MacOS 10.6.
 */
static void
test_compat_mac_2(void)
{
	char name[] = "test_compat_mac-2.tar.Z";
	struct archive_entry *ae;
	struct archive *a;
	const void *attr;
	size_t attrSize;

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

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("./", archive_entry_pathname(ae));
	assertEqualInt(1303628303, archive_entry_mtime(ae));
	assertEqualInt(501, archive_entry_uid(ae));
	assertEqualString("tim", archive_entry_uname(ae));
	assertEqualInt(20, archive_entry_gid(ae));
	assertEqualString("staff", archive_entry_gname(ae));
	assertEqualInt(040755, archive_entry_mode(ae));

	attr = archive_entry_mac_metadata(ae, &attrSize);
	assert(attr == NULL);
	assertEqualInt(0, attrSize);

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("./mydir/", archive_entry_pathname(ae));
	assertEqualInt(1303628303, archive_entry_mtime(ae));
	assertEqualInt(501, archive_entry_uid(ae));
	assertEqualString("tim", archive_entry_uname(ae));
	assertEqualInt(20, archive_entry_gid(ae));
	assertEqualString("staff", archive_entry_gname(ae));
	assertEqualInt(040755, archive_entry_mode(ae));

	attr = archive_entry_mac_metadata(ae, &attrSize);
	assert(attr != NULL);
	assertEqualInt(267, attrSize);
	assertEqualMem("\x00\x05\x16\x07\x00\x02\x00\x00Mac OS X", attr, 16);

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString("./myfile", archive_entry_pathname(ae));
	assertEqualInt(1303628303, archive_entry_mtime(ae));
	assertEqualInt(501, archive_entry_uid(ae));
	assertEqualString("tim", archive_entry_uname(ae));
	assertEqualInt(20, archive_entry_gid(ae));
	assertEqualString("staff", archive_entry_gname(ae));
	assertEqualInt(0100644, archive_entry_mode(ae));

	attr = archive_entry_mac_metadata(ae, &attrSize);
	assert(attr != NULL);
	assertEqualInt(267, attrSize);
	assertEqualMem("\x00\x05\x16\x07\x00\x02\x00\x00Mac OS X", attr, 16);

	/* Verify the end-of-archive. */
	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));

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

	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
コード例 #28
0
ファイル: archive_handler.c プロジェクト: jyelloz/swupdate
static void *
extract(void *p)
{
    struct archive *a;
    struct archive *ext;
    struct archive_entry *entry;
    int r;
    int flags;
    struct extract_data *data = (struct extract_data *)p;
    flags = data->flags;

    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_all(a);
    archive_read_support_filter_all(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 ((r = archive_read_open_filename(a, FIFO, 4096))) {
        ERROR("archive_read_open_filename(): %s %d\n",
              archive_error_string(a), r);
        pthread_exit((void *)-1);
    }
    for (;;) {
        r = archive_read_next_header(a, &entry);
        if (r == ARCHIVE_EOF)
            break;
        if (r != ARCHIVE_OK) {
            ERROR("archive_read_next_header(): %s %d\n",
                  archive_error_string(a), 1);
            pthread_exit((void *)-1);
        }

        if (debug)
            TRACE("Extracting %s\n", archive_entry_pathname(entry));

        r = archive_write_header(ext, entry);
        if (r != ARCHIVE_OK)
            TRACE("archive_write_header(): %s\n",
                  archive_error_string(ext));
        else {
            copy_data(a, ext);
            r = archive_write_finish_entry(ext);
            if (r != ARCHIVE_OK)  {
                ERROR("archive_write_finish_entry(): %s\n",
                      archive_error_string(ext));
                pthread_exit((void *)-1);
            }
        }

    }

    archive_read_close(a);
    archive_read_free(a);
    pthread_exit((void *)0);
}
コード例 #29
0
static void
test_filename(const char *prefix, int dlen, int flen)
{
	char buff[8192];
	char filename[400];
	char dirname[400];
	struct archive_entry *ae;
	struct archive *a;
	size_t used;
	char *p;
	int i;

	p = filename;
	if (prefix) {
		strcpy(filename, prefix);
		p += strlen(p);
	}
	if (dlen > 0) {
		for (i = 0; i < dlen; i++)
			*p++ = 'a';
		*p++ = '/';
	}
	for (i = 0; i < flen; i++)
		*p++ = 'b';
	*p = '\0';

	strcpy(dirname, filename);

	/* Create a new archive in memory. */
	assert((a = archive_write_new()) != NULL);
	assertA(0 == archive_write_set_format_pax_restricted(a));
	assertA(0 == archive_write_add_filter_none(a));
	assertA(0 == archive_write_set_bytes_per_block(a,0));
	assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used));

	/*
	 * Write a file to it.
	 */
	assert((ae = archive_entry_new()) != NULL);
	archive_entry_copy_pathname(ae, filename);
	archive_entry_set_mode(ae, S_IFREG | 0755);
	failure("Pathname %d/%d", dlen, flen);
	assertA(0 == archive_write_header(a, ae));
	archive_entry_free(ae);

	/*
	 * Write a dir to it (without trailing '/').
	 */
	assert((ae = archive_entry_new()) != NULL);
	archive_entry_copy_pathname(ae, dirname);
	archive_entry_set_mode(ae, S_IFDIR | 0755);
	failure("Dirname %d/%d", dlen, flen);
	assertA(0 == archive_write_header(a, ae));
	archive_entry_free(ae);

	/* Tar adds a '/' to directory names. */
	strcat(dirname, "/");

	/*
	 * Write a dir to it (with trailing '/').
	 */
	assert((ae = archive_entry_new()) != NULL);
	archive_entry_copy_pathname(ae, dirname);
	archive_entry_set_mode(ae, S_IFDIR | 0755);
	failure("Dirname %d/%d", dlen, flen);
	assertA(0 == archive_write_header(a, ae));
	archive_entry_free(ae);

	/* Close out the archive. */
	assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a));
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/*
	 * Now, read the data back.
	 */
	assert((a = archive_read_new()) != NULL);
	assertA(0 == archive_read_support_format_all(a));
	assertA(0 == archive_read_support_filter_all(a));
	assertA(0 == archive_read_open_memory(a, buff, used));

	/* Read the file and check the filename. */
	assertA(0 == archive_read_next_header(a, &ae));
	assertEqualString(filename, archive_entry_pathname(ae));
	assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae));

	/*
	 * Read the two dirs and check the names.
	 *
	 * Both dirs should read back with the same name, since
	 * tar should add a trailing '/' to any dir that doesn't
	 * already have one.  We only report the first such failure
	 * here.
	 */
	assertA(0 == archive_read_next_header(a, &ae));
	assertEqualString(dirname, archive_entry_pathname(ae));
	assert((S_IFDIR | 0755) == archive_entry_mode(ae));

	assertA(0 == archive_read_next_header(a, &ae));
	assertEqualString(dirname, archive_entry_pathname(ae));
	assert((S_IFDIR | 0755) == archive_entry_mode(ae));

	/* Verify the end of the archive. */
	assert(1 == archive_read_next_header(a, &ae));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
コード例 #30
0
static void
test_read_format_mtree1(void)
{
	const char reffile[] = "test_read_format_mtree.mtree";
	char buff[16];
	struct archive_entry *ae;
	struct archive *a;
	FILE *f;

	extract_reference_file(reffile);

	/*
	 * An access error occurred on some platform when mtree
	 * format handling open a directory. It is for through
	 * the routine which open a directory that we create
	 * "dir" and "dir2" directories.
	 */
	assertMakeDir("dir", 0775);
	assertMakeDir("dir2", 0775);

	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));
	assertEqualIntA(a, ARCHIVE_OK, archive_read_open_file(a, reffile, 11));

	/*
	 * Read "file", whose data is available on disk.
	 */
	f = fopen("file", "wb");
	assert(f != NULL);
	assertEqualInt(3, fwrite("hi\n", 1, 3, f));
	fclose(f);
	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
	assertEqualString(archive_entry_pathname(ae), "file");
	assertEqualInt(archive_entry_uid(ae), 18);
	assertEqualInt(AE_IFREG, archive_entry_filetype(ae));
	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123);
	assertEqualInt(archive_entry_size(ae), 3);
	assertEqualInt(3, archive_read_data(a, buff, 3));
	assertEqualMem(buff, "hi\n", 3);

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString(archive_entry_pathname(ae), "dir");
	assertEqualInt(AE_IFDIR, archive_entry_filetype(ae));

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString(archive_entry_pathname(ae), "dir/file with space");

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString(archive_entry_pathname(ae), "file with space");

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString(archive_entry_pathname(ae), "dir2");

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString(archive_entry_pathname(ae), "dir2/dir3a");

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString(archive_entry_pathname(ae), "dir2/dir3a/indir3a");

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString(archive_entry_pathname(ae), "dir2/fullindir2");
	assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644);

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString(archive_entry_pathname(ae), "dir2/indir2");

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString(archive_entry_pathname(ae), "dir2/dir3b");

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString(archive_entry_pathname(ae), "dir2/dir3b/indir3b");

	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
	assertEqualString(archive_entry_pathname(ae), "notindir");

	assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
	assertEqualInt(ARCHIVE_OK, archive_read_close(a));
	assertEqualInt(ARCHIVE_OK, archive_read_finish(a));
}