Пример #1
0
void
write_archive(const char *outname, const char **filename)
{
	struct archive *a;
	struct archive_entry *entry;
	struct stat st;
	char buff[8192];
	int len;
	FILE* fd;

	a = archive_write_new();
	//archive_write_add_filter_gzip(a);
	//archive_write_set_format_pax_restricted(a); // Note 1
	archive_write_set_format_zip(a);
	//archive_write_add_filter_none(a);

	archive_write_open_filename(a, outname);
	while (*filename) {
		stat(*filename, &st);
		entry = archive_entry_new(); // Note 2
		myarch_set_entry( *filename, st.st_size, entry);
		archive_write_header(a, entry);
		fd = fopen(*filename, "rb");
		printf("Read File %s return fd %p\n", *filename, fd);
		while ((len = fread(buff, 1, sizeof(buff), fd)) > 0) {
			printf(" len %d\n", len);
			archive_write_data(a, buff, len);
		}
		fclose(fd);
		archive_entry_free(entry);
		filename++;
	}
	archive_write_close(a); // Note 4
	archive_write_finish(a); // Note 5
}
Пример #2
0
static void
verify_zip_filesize(uint64_t size, int expected)
{
	struct archive *a;
	struct archive_entry *ae;
	char buff[256];
	size_t used;

	/* Zip format: Create a new archive in memory. */
	assert((a = archive_write_new()) != NULL);
	assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a));
	/* Disable Zip64 extensions. */
	assertEqualIntA(a, ARCHIVE_OK,
	    archive_write_set_format_option(a, "zip", "zip64", NULL));
	assertEqualIntA(a, ARCHIVE_OK,
	    archive_write_open_memory(a, buff, sizeof(buff), &used));

	assert((ae = archive_entry_new()) != NULL);
	archive_entry_set_pathname(ae, "test");
	archive_entry_set_mode(ae, AE_IFREG | 0644);
	archive_entry_set_size(ae, size);
	assertEqualInt(expected, archive_write_header(a, ae));

	archive_entry_free(ae);

	/* Don't actually write 4GB! ;-) */
	assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a));
}
Пример #3
0
int StudioFrame::CreateZip(std::string zfile, std::vector<std::string> files) {
	struct archive *zip;

	zip = archive_write_new();
	if (zip == NULL) {
		wxMessageBox(_("archive_write_new error"));
		return -1;
	}
	archive_write_set_format_zip(zip);
//	archive_write_zip_set_compression_store(zip);
	archive_write_open_filename(zip, zfile.c_str());

	if (WriteDefsToZip(zip)) {
		archive_write_close(zip);
		archive_write_finish(zip);
		return -1;
	}

	for (size_t i=0; i<files.size(); i++) {
		if (WriteFileToZip(zip, files[i])) {
			archive_write_close(zip);
			archive_write_finish(zip);
			return -1;
		}
	}

	archive_write_close(zip);
	archive_write_finish(zip);

	return 0;
}
Пример #4
0
void write_archive(const char *outname, const char **filename) {
  struct archive *a;
  
  a = archive_write_new();
  archive_write_set_format_zip(a);
  archive_write_open_filename(a, outname);

  while(*filename) {
    file_to_archive(a, *filename);
    filename++;
  }

  archive_write_close(a);
  archive_write_free(a);
}
Пример #5
0
int test1()
{
	struct archive *a = archive_write_new();
	int ret = archive_write_set_format_zip(a);

	unsigned char buffer[100];
	int size;
	ret = archive_write_open_memory(a, buffer, 100, &size);

	// add a file
	struct archive_entry  *entry = archive_entry_new();

	archive_entry_set_pathname(entry, "hello.txt");
	archive_entry_set_size(entry, 5);
	archive_entry_set_filetype(entry, AE_IFREG);
	archive_entry_set_perm(entry, 0644);
	ret = archive_write_header(a, entry);
	printf("archive_write_header: ret=%d\n", ret);
	la_ssize_t n = archive_write_data(a, "world", 5);
	printf("archive_write_data: n=%d, error=%s\n", n, archive_error_string(a));


	// ad another file
	//
	archive_entry_clear(entry);
	archive_entry_set_pathname(entry, "somedir/yo.txt");
	archive_entry_set_size(entry, 5);
	archive_entry_set_filetype(entry, AE_IFREG);
	archive_entry_set_perm(entry, 0644);
	archive_write_header(a, entry);
	n = archive_write_data(a, "12345", 5);
	printf("archive_write_data: n=%d, error=%s\n", n, archive_error_string(a));

	archive_entry_free(entry);

	ret = archive_write_free(a);
	printf("archive_write_free: ret=%d, error=%s\n", ret, archive_error_string(a));

	printf("size=%d\n", size);
	write(1, buffer, size);
}
Пример #6
0
void Writer::set_format_helper(struct archive *ar, int format)
{
    std::string error_msg;

    switch(format) {
        case Archive::FORMAT_AR_BSD:
            archive_write_set_format_ar_bsd(ar);
            break;
        case Archive::FORMAT_AR_SVR4:
            archive_write_set_format_ar_svr4(ar);
            break;
        case Archive::FORMAT_CPIO:
            archive_write_set_format_cpio(ar);
            break;
        case Archive::FORMAT_CPIO_NEWC:
            archive_write_set_format_cpio_newc(ar);
            break;
        case Archive::FORMAT_MTREE:
            archive_write_set_format_mtree(ar);
            break;
        case Archive::FORMAT_TAR:
        case Archive::FORMAT_TAR_PAX_RESTRICTED:
            archive_write_set_format_pax_restricted(ar);
            break;
        case Archive::FORMAT_TAR_PAX_INTERCHANGE:
            archive_write_set_format_pax(ar);
            break;
        case Archive::FORMAT_TAR_USTAR:
            archive_write_set_format_ustar(ar);
            break;
        case Archive::FORMAT_RAW:
            archive_write_set_format_raw(ar);
            break;
        case Archive::FORMAT_ZIP:
            archive_write_set_format_zip(ar);
            break;
        default:
            error_msg = "unknown or unsupported archive format";
            throw Error(error_msg);
    }
}
Пример #7
0
int test2_with_write_callbacks()
{
	struct archive *a = archive_write_new();
	archive_write_set_format_zip(a);
	int ret = archive_write_open(a, NULL, myopen, mywrite, myclose);

	// add a file
	struct archive_entry  *entry = archive_entry_new();
	archive_entry_set_pathname(entry, "123.d/hello.txt");
	archive_entry_set_size(entry, 5);
	archive_entry_set_filetype(entry, AE_IFREG);
	archive_entry_set_perm(entry, 0644);
	ret = archive_write_header(a, entry);
	fprintf(stderr, "archive_write_header: ret=%d\n", ret);
	la_ssize_t n = archive_write_data(a, "world", 5);
	fprintf(stderr, "archive_write_data: n=%d, error=%s\n", n, archive_error_string(a));

	archive_entry_free(entry);

	ret = archive_write_free(a);
	fprintf(stderr, "archive_write_free: ret=%d, error=%s\n", ret, archive_error_string(a));
}
Пример #8
0
/*
 * Do not translate CP1251 into CP866 if non Windows platform.
 */
static void
test_zip_filename_encoding_ru_RU_CP1251(void)
{
  	struct archive *a;
  	struct archive_entry *entry;
	char buff[4096];
	size_t used;

	if (NULL == setlocale(LC_ALL, "ru_RU.CP1251")) {
		skipping("Russian_Russia locale not available on this system.");
		return;
	}

	/*
	 * Verify that CP1251 filenames are not translated into any
	 * other character-set, in particular, CP866.
	 */
	a = archive_write_new();
	assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
	assertEqualInt(ARCHIVE_OK,
	    archive_write_open_memory(a, buff, sizeof(buff), &used));

	entry = archive_entry_new2(a);
	/* Set a CP1251 filename. */
	archive_entry_set_pathname(entry, "\xEF\xF0\xE8");
	archive_entry_set_filetype(entry, AE_IFREG);
	archive_entry_set_size(entry, 0);
	assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
	archive_entry_free(entry);
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/* A bit 11 of general purpose flag should be 0,
	 * which indicates the filename charset is unknown. */
	assertEqualInt(0, buff[7]);
	/* Above three characters in CP1251 should not translate into
	 * any other character-set. */
	assertEqualMem(buff + 30, "\xEF\xF0\xE8", 3);
}
Пример #9
0
//********************************************************************************************************
void write_archive(const char* const outname, char** filename, int nFiles) {
  // Adapted from
  // https://github.com/libarchive/libarchive/wiki/Examples#A_Basic_Write_Example
  struct archive *a;
  struct archive_entry *entry;
  struct stat st;
  int err;
  char buff[8192];
  int len;
  FILE* fd;


  //printf("Writing outname='%s'\n",outname);

  a = archive_write_new(); //Constructs the archive in memory? If so, may be problematic for large archives.
  //For tar.gz:
  // archive_write_add_filter_gzip(a);
  // archive_write_set_format_pax_restricted(a); // Note 1
  //For .zip:
  archive_write_set_format_zip(a);

  archive_write_open_filename(a, outname);
  entry = archive_entry_new();
  for (int i=0;i<nFiles;i++){
    //printf("Compressing filename='%s'... ",filename[i]);

    //Write the header
#ifdef __WIN32
    LARGE_INTEGER filesize_union;
    HANDLE hFile = CreateFile(filename[i], GENERIC_READ,
			      FILE_SHARE_READ | FILE_SHARE_WRITE,
			      NULL, OPEN_EXISTING,
			      FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE) continue;
    if(!GetFileSizeEx(hFile, &filesize_union)) {
      fprintf(stderr, "CRITICAL ERROR in write_archive(): GetFileSizeEx failed.");
      exit(EXIT_FAILURE);
    }
    CloseHandle(hFile);
    LONGLONG filesize = filesize_union.QuadPart;
#else
    off_t filesize = 0;
    err = stat(filename[i], &st);
    //printf("stat reported err=%i\n", err);
    if(err != 0) continue;
    filesize = st.st_size;
#endif

    archive_entry_set_pathname(entry, filename[i]);
    archive_entry_set_size(entry, filesize);
    archive_entry_set_filetype(entry, AE_IFREG);
    archive_entry_set_perm(entry, 0644);
    archive_write_header(a, entry);

    //Write the data
    int len_total = 0;
    fd = fopen(filename[i], "rb");
    len = fread(buff, 1,sizeof(buff), fd);
    len_total = len;
    while ( len > 0 ) {
      err=archive_write_data(a, buff, len);
      if (err < 0){
	fprintf(stderr, "CRITICAL ERROR in write_archive(): When writing file, got err=%i\n",err);
	fprintf(stderr, "CRITICAL ERROR in write_archive(): %s\n",archive_error_string(a));
	exit(EXIT_FAILURE);
      }
      len = fread(buff, 1,sizeof(buff), fd);
      len_total += len;
    }
    fclose(fd);
    archive_entry_clear(entry);

    //printf("Wrote file '%s', len_total = %i, filesize = %i\n", filename[i], len_total, filesize);
    if (len_total != filesize) {
      fprintf(stderr, "CRITICAL ERROR in write_archive(): When writing file '%s', got len_total = %i but filesize = %i\n", filename[i], len_total, filesize);
    }
  }
  archive_entry_free(entry);
  //printf("Complete!\n");
  archive_write_close(a); // Note 4
  archive_write_free(a); // called archive_write_finish() in old versions of libarchive
}
Пример #10
0
	RESULTCODE ArchiveProcessorImpl::Compress()
	{
		const char* tpath = GetArchivePath();
		if(tpath==NULL)
		{
			return AG_FAILURE;
		}

		struct archive *a;
		struct archive_entry *entry;
		struct stat st;
		char buff[AUGE_BUFFER_MAX];
		int len;
		int fd;

		a = archive_write_new();
		if(a==NULL)
		{
			return AG_FAILURE;
		}
		//archive_write_add_filter_gzip(a);
		archive_write_set_format_zip(a);
		archive_write_set_format_pax_restricted(a);
		archive_write_open_filename(a,tpath);

		const char* fpath = NULL;
		char name[AUGE_NAME_MAX];
		char ext[AUGE_EXT_MAX];
		char fname[AUGE_NAME_MAX];
		std::vector<std::string>::iterator iter;
		for(iter=m_paths.begin(); iter!=m_paths.end();iter++)
		{
			fpath = (*iter).c_str();
			memset(fname,0,AUGE_NAME_MAX);
			memset(name,0,AUGE_NAME_MAX);
			memset(name,0,AUGE_EXT_MAX);
			auge_split_path(fpath, NULL, NULL, name, ext);
			auge_make_path(fname, NULL, NULL, name, ext);
			if(strlen(fname)==0)
			{
				continue;
			}

			stat(fpath,&st);

			entry = archive_entry_new();
			archive_entry_set_pathname(entry,fname);
			archive_entry_set_size(entry,st.st_size);
			archive_entry_set_filetype(entry, AE_IFREG);
			archive_entry_set_perm(entry,0644);
			archive_write_header(a,entry);

			fd = open(fpath,O_RDONLY);
			len = read(fd,buff,sizeof(buff));
			while(len>0)
			{
				archive_write_data(a,buff, len);
				len = read(fd,buff,sizeof(buff));
			}
			close(fd);
			archive_entry_free(entry);
		}

		archive_write_close(a);	
		archive_write_free(a);	

		return AG_SUCCESS;
	}
Пример #11
0
static void
test_zip_filename_encoding_CP932(void)
{
  	struct archive *a;
  	struct archive_entry *entry;
	char buff[4096];
	size_t used;

	if (NULL == setlocale(LC_ALL, "Japanese_Japan") &&
	    NULL == setlocale(LC_ALL, "ja_JP.SJIS")) {
		skipping("CP932/SJIS locale not available on this system.");
		return;
	}

	/*
	 * Verify that EUC-JP filenames are correctly translated to UTF-8.
	 */
	a = archive_write_new();
	assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
	if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
		skipping("This system cannot convert character-set"
		    " from CP932/SJIS to UTF-8.");
		archive_write_free(a);
		return;
	}
	assertEqualInt(ARCHIVE_OK,
	    archive_write_open_memory(a, buff, sizeof(buff), &used));

	entry = archive_entry_new2(a);
	/* Set a CP932/SJIS filename. */
	archive_entry_set_pathname(entry, "\x95\x5C.txt");
	/* Check the Unicode version. */
	archive_entry_set_filetype(entry, AE_IFREG);
	archive_entry_set_size(entry, 0);
	assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
	archive_entry_free(entry);
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/* A bit 11 of general purpose flag should be 0x08,
	 * which indicates the filename charset is UTF-8. */
	assertEqualInt(0x08, buff[7]);
	/* Check UTF-8 version. */
	assertEqualMem(buff + 30, "\xE8\xA1\xA8.txt", 7);

	/*
	 * Verify that CP932/SJIS filenames are not translated to UTF-8.
	 */
	a = archive_write_new();
	assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
	assertEqualInt(ARCHIVE_OK,
	    archive_write_open_memory(a, buff, sizeof(buff), &used));

	entry = archive_entry_new2(a);
	/* Set a CP932/SJIS filename. */
	archive_entry_set_pathname(entry, "\x95\x5C.txt");
	/* Check the Unicode version. */
	archive_entry_set_filetype(entry, AE_IFREG);
	archive_entry_set_size(entry, 0);
	assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
	archive_entry_free(entry);
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/* A bit 11 of general purpose flag should be 0,
	 * which indicates the filename charset is unknown. */
	assertEqualInt(0, buff[7]);
	/* Above three characters in CP932/SJIS should not translate to
	 * any character-set. */
	assertEqualMem(buff + 30, "\x95\x5C.txt", 6);

	/*
	 * Verify that A bit 11 of general purpose flag is not set
	 * when ASCII filenames are stored even if hdrcharset=UTF-8
	 * is specified.
	 */
	a = archive_write_new();
	assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
	if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
		skipping("This system cannot convert character-set"
		    " from CP932/SJIS to UTF-8.");
		archive_write_free(a);
		return;
	}
	assertEqualInt(ARCHIVE_OK,
	    archive_write_open_memory(a, buff, sizeof(buff), &used));

	entry = archive_entry_new2(a);
	/* Set an ASCII filename. */
	archive_entry_set_pathname(entry, "abcABC");
	/* Check the Unicode version. */
	archive_entry_set_filetype(entry, AE_IFREG);
	archive_entry_set_size(entry, 0);
	assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
	archive_entry_free(entry);
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/* A bit 11 of general purpose flag should be 0,
	 * which indicates the filename charset is unknown. */
	assertEqualInt(0, buff[7]);
	assertEqualMem(buff + 30, "abcABC", 6);
}
Пример #12
0
/*
 * Other archiver applications on Windows translate CP1251 filenames
 * into CP866 filenames and store it in the zip file.
 * Test above behavior works well.
 */
static void
test_zip_filename_encoding_Russian_Russia(void)
{
  	struct archive *a;
  	struct archive_entry *entry;
	char buff[4096];
	size_t used;

	if (NULL == setlocale(LC_ALL, "Russian_Russia")) {
		skipping("Russian_Russia locale not available on this system.");
		return;
	}

	/*
	 * Verify that Russian_Russia(CP1251) filenames are correctly translated
	 * to UTF-8.
	 */
	a = archive_write_new();
	assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
	if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
		skipping("This system cannot convert character-set"
		    " from Russian_Russia.CP1251 to UTF-8.");
		archive_write_free(a);
		return;
	}
	assertEqualInt(ARCHIVE_OK,
	    archive_write_open_memory(a, buff, sizeof(buff), &used));

	entry = archive_entry_new2(a);
	/* Set a CP1251 filename. */
	archive_entry_set_pathname(entry, "\xEF\xF0\xE8");
	archive_entry_set_filetype(entry, AE_IFREG);
	archive_entry_set_size(entry, 0);
	assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
	archive_entry_free(entry);
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/* A bit 11 of general purpose flag should be 0x08,
	 * which indicates the filename charset is UTF-8. */
	assertEqualInt(0x08, buff[7]);
	/* Above three characters in CP1251 should translate to the following
	 * three characters (two bytes each) in UTF-8. */
	assertEqualMem(buff + 30, "\xD0\xBF\xD1\x80\xD0\xB8", 6);

	/*
	 * Verify that Russian_Russia(CP1251) filenames are correctly translated
	 * to CP866.
	 */
	a = archive_write_new();
	assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
	assertEqualInt(ARCHIVE_OK,
	    archive_write_open_memory(a, buff, sizeof(buff), &used));

	entry = archive_entry_new2(a);
	/* Set a CP1251 filename. */
	archive_entry_set_pathname(entry, "\xEF\xF0\xE8");
	archive_entry_set_filetype(entry, AE_IFREG);
	archive_entry_set_size(entry, 0);
	assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
	archive_entry_free(entry);
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/* A bit 11 of general purpose flag should be 0,
	 * which indicates the filename charset is unknown. */
	assertEqualInt(0, buff[7]);
	/* Above three characters in CP1251 should translate to the following
	 * three characters in CP866. */
	assertEqualMem(buff + 30, "\xAF\xE0\xA8", 3);
}
Пример #13
0
static void
test_zip_filename_encoding_UTF8(void)
{
  	struct archive *a;
  	struct archive_entry *entry;
	char buff[4096];
	size_t used;

	if (NULL == setlocale(LC_ALL, "en_US.UTF-8")) {
		skipping("en_US.UTF-8 locale not available on this system.");
		return;
	}

	/*
	 * Verify that UTF-8 filenames are correctly stored with
	 * hdrcharset=UTF-8 option.
	 */
	a = archive_write_new();
	assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
	if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
		skipping("This system cannot convert character-set"
		    " for UTF-8.");
		archive_write_free(a);
		return;
	}
	assertEqualInt(ARCHIVE_OK,
	    archive_write_open_memory(a, buff, sizeof(buff), &used));

	entry = archive_entry_new2(a);
	/* Set a UTF-8 filename. */
	archive_entry_set_pathname(entry, "\xD0\xBF\xD1\x80\xD0\xB8");
	archive_entry_set_filetype(entry, AE_IFREG);
	archive_entry_set_size(entry, 0);
	assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
	archive_entry_free(entry);
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/* A bit 11 of general purpose flag should be 0x08,
	 * which indicates the filename charset is UTF-8. */
	assertEqualInt(0x08, buff[7]);
	assertEqualMem(buff + 30, "\xD0\xBF\xD1\x80\xD0\xB8", 6);

	/*
	 * Verify that UTF-8 filenames are correctly stored without
	 * hdrcharset=UTF-8 option.
	 */
	a = archive_write_new();
	assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
	assertEqualInt(ARCHIVE_OK,
	    archive_write_open_memory(a, buff, sizeof(buff), &used));

	entry = archive_entry_new2(a);
	/* Set a UTF-8 filename. */
	archive_entry_set_pathname(entry, "\xD0\xBF\xD1\x80\xD0\xB8");
	archive_entry_set_filetype(entry, AE_IFREG);
	archive_entry_set_size(entry, 0);
	assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
	archive_entry_free(entry);
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/* A bit 11 of general purpose flag should be 0x08,
	 * which indicates the filename charset is UTF-8. */
	assertEqualInt(0x08, buff[7]);
	assertEqualMem(buff + 30, "\xD0\xBF\xD1\x80\xD0\xB8", 6);

	/*
	 * Verify that A bit 11 of general purpose flag is not set
	 * when ASCII filenames are stored.
	 */
	a = archive_write_new();
	assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
	assertEqualInt(ARCHIVE_OK,
	    archive_write_open_memory(a, buff, sizeof(buff), &used));

	entry = archive_entry_new2(a);
	/* Set an ASCII filename. */
	archive_entry_set_pathname(entry, "abcABC");
	archive_entry_set_filetype(entry, AE_IFREG);
	archive_entry_set_size(entry, 0);
	assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
	archive_entry_free(entry);
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/* A bit 11 of general purpose flag should be 0,
	 * which indicates the filename charset is unknown. */
	assertEqualInt(0, buff[7]);
	assertEqualMem(buff + 30, "abcABC", 6);
}
Пример #14
0
static void
test_zip_filename_encoding_KOI8R(void)
{
  	struct archive *a;
  	struct archive_entry *entry;
	char buff[4096];
	size_t used;

	if (NULL == setlocale(LC_ALL, "ru_RU.KOI8-R")) {
		skipping("KOI8-R locale not available on this system.");
		return;
	}

	/*
	 * Verify that KOI8-R filenames are correctly translated to UTF-8.
	 */
	a = archive_write_new();
	assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
	if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
		skipping("This system cannot convert character-set"
		    " from KOI8-R to UTF-8.");
		archive_write_free(a);
		return;
	}
	assertEqualInt(ARCHIVE_OK,
	    archive_write_open_memory(a, buff, sizeof(buff), &used));

	entry = archive_entry_new2(a);
	/* Set a KOI8-R filename. */
	archive_entry_set_pathname(entry, "\xD0\xD2\xC9");
	archive_entry_set_filetype(entry, AE_IFREG);
	archive_entry_set_size(entry, 0);
	assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
	archive_entry_free(entry);
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/* A bit 11 of general purpose flag should be 0x08,
	 * which indicates the filename charset is UTF-8. */
	assertEqualInt(0x08, buff[7]);
	/* Above three characters in KOI8-R should translate to the following
	 * three characters (two bytes each) in UTF-8. */
	assertEqualMem(buff + 30, "\xD0\xBF\xD1\x80\xD0\xB8", 6);

	/*
	 * Verify that KOI8-R filenames are not translated to UTF-8.
	 */
	a = archive_write_new();
	assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
	assertEqualInt(ARCHIVE_OK,
	    archive_write_open_memory(a, buff, sizeof(buff), &used));

	entry = archive_entry_new2(a);
	/* Set a KOI8-R filename. */
	archive_entry_set_pathname(entry, "\xD0\xD2\xC9");
	archive_entry_set_filetype(entry, AE_IFREG);
	archive_entry_set_size(entry, 0);
	assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
	archive_entry_free(entry);
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/* A bit 11 of general purpose flag should be 0,
	 * which indicates the filename charset is unknown. */
	assertEqualInt(0, buff[7]);
	/* Above three characters in KOI8-R should not translate to
	 * any character-set. */
	assertEqualMem(buff + 30, "\xD0\xD2\xC9", 3);

	/*
	 * Verify that A bit 11 of general purpose flag is not set
	 * when ASCII filenames are stored even if hdrcharset=UTF-8
	 * is specified.
	 */
	a = archive_write_new();
	assertEqualInt(ARCHIVE_OK, archive_write_set_format_zip(a));
	if (archive_write_set_options(a, "hdrcharset=UTF-8") != ARCHIVE_OK) {
		skipping("This system cannot convert character-set"
		    " from KOI8-R to UTF-8.");
		archive_write_free(a);
		return;
	}
	assertEqualInt(ARCHIVE_OK,
	    archive_write_open_memory(a, buff, sizeof(buff), &used));

	entry = archive_entry_new2(a);
	/* Set an ASCII filename. */
	archive_entry_set_pathname(entry, "abcABC");
	archive_entry_set_filetype(entry, AE_IFREG);
	archive_entry_set_size(entry, 0);
	assertEqualInt(ARCHIVE_OK, archive_write_header(a, entry));
	archive_entry_free(entry);
	assertEqualInt(ARCHIVE_OK, archive_write_free(a));

	/* A bit 11 of general purpose flag should be 0,
	 * which indicates the filename charset is unknown. */
	assertEqualInt(0, buff[7]);
	assertEqualMem(buff + 30, "abcABC", 6);
}