int copy_data(struct archive *ar, struct archive *aw)
	{
		int r;
		const void *buff;
		size_t size;
		int64_t offset;

		while(true)
		{
			r = archive_read_data_block(ar, &buff, &size, &offset);
			if (r == ARCHIVE_EOF)
			{
				return (ARCHIVE_OK);
			}
			if (r < ARCHIVE_OK)
			{
				return (r);
			}
			r = archive_write_data_block(aw, buff, size, offset);
			if (r < ARCHIVE_OK) {
				fprintf(stderr, "%s\n", archive_error_string(aw));
				return (r);
			}
		}
	}
static void create_reg_file2(struct archive_entry *ae, const char *msg)
{
	const int datasize = 100000;
	char *data;
	struct archive *ad;
	int i;

	data = malloc(datasize);
	for (i = 0; i < datasize; i++)
		data[i] = (char)(i % 256);

	/* Write the entry to disk. */
	assert((ad = archive_write_disk_new()) != NULL);
	failure("%s", msg);
	/*
	 * See above for an explanation why this next call
	 * is necessary.
	 */
	archive_entry_set_size(ae, datasize);
	assertEqualIntA(ad, 0, archive_write_header(ad, ae));
	for (i = 0; i < datasize - 999; i += 1000) {
		assertEqualIntA(ad, ARCHIVE_OK,
		    archive_write_data_block(ad, data + i, 1000, i));
	}
	assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
	assertEqualInt(0, archive_write_finish(ad));

	/* Test the entries on disk. */
	assertIsReg(archive_entry_pathname(ae), archive_entry_mode(ae) & 0777);
	assertFileSize(archive_entry_pathname(ae), i);
	assertFileContents(data, datasize, archive_entry_pathname(ae));
	free(data);
}
static void create_reg_file4(struct archive_entry *ae, const char *msg)
{
	static const char data[]="abcdefghijklmnopqrstuvwxyz";
	struct archive *ad;
	struct stat st;

	/* Write the entry to disk. */
	assert((ad = archive_write_disk_new()) != NULL);
	/* Leave the size unset.  The data should not be truncated. */
	assertEqualIntA(ad, 0, archive_write_header(ad, ae));
	assertEqualInt(ARCHIVE_OK,
	    archive_write_data_block(ad, data, sizeof(data), 0));
	assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
#if ARCHIVE_VERSION_NUMBER < 2000000
	archive_write_finish(ad);
#else
	assertEqualInt(0, archive_write_finish(ad));
#endif
	/* Test the entry on disk. */
	assert(0 == stat(archive_entry_pathname(ae), &st));
	failure("st.st_mode=%o archive_entry_mode(ae)=%o",
	    st.st_mode, archive_entry_mode(ae));
#if !defined(_WIN32) || defined(__CYGWIN__)
	assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK));
#endif
	failure(msg);
	assertEqualInt(st.st_size, sizeof(data));
}
Exemple #4
0
int copy_data(struct archive* ar, struct archive* aw) {
  int r;
  const void* buff;
  size_t size;
#if ARCHIVE_VERSION >= 3000000
  int64_t offset;
#else
  off_t offset;
#endif

  for(;;) {
    r = archive_read_data_block(ar, &buff, &size, &offset);
    if(r == ARCHIVE_EOF) {
      return ARCHIVE_OK;
    }
    if(r != ARCHIVE_OK) {
      return (r);
    }
    r = archive_write_data_block(aw, buff, size, offset);
    if(r != ARCHIVE_OK) {
      printf("archive_write_data_block(): %s", archive_error_string(aw));
      return r;
    }
  }
}
Exemple #5
0
/*
 * Exits if there's a fatal error.  Returns ARCHIVE_OK
 * if everything is kosher.
 */
static int
extract_data(struct archive *ar, struct archive *aw)
{
	int r;
	size_t size;
	const void *block;
	off_t offset;

	for (;;) {
		r = archive_read_data_block(ar, &block, &size, &offset);
		if (r == ARCHIVE_EOF)
			return (ARCHIVE_OK);
		if (r != ARCHIVE_OK) {
			lafe_warnc(archive_errno(ar),
			    "%s", archive_error_string(ar));
			exit(1);
		}
		r = archive_write_data_block(aw, block, size, offset);
		if (r != ARCHIVE_OK) {
			lafe_warnc(archive_errno(aw),
			    "%s", archive_error_string(aw));
			return (r);
		}
	}
}
Exemple #6
0
// -----------------------------------------------------------------------------
bool copyData(archive* sorc, archive* dest)
{
    DEBUGLOGB;

    int         retc;
    const void* buff;
    size_t      size;
    int64_t     offs;
    bool        okay = false;

    while( true )
    {
        if( (retc = archive_read_data_block (sorc, &buff, &size, &offs)) == ARCHIVE_EOF )
        {
            okay = true;
            break;
        }

        if( retc != ARCHIVE_OK )
            break;

        if( (retc = archive_write_data_block(dest,  buff,  size,  offs)) != ARCHIVE_OK )
            break;
    }

    DEBUGLOGE;
    return okay;
}
Exemple #7
0
static int copy_data(struct archive *ar, struct archive *aw)
{
    int r;
    const void *buff;
    size_t size;
#if ARCHIVE_VERSION_NUMBER >= 3000000
    int64_t offset;
#else
    off_t offset;
#endif

    for (;;) {
        r = archive_read_data_block(ar, &buff, &size, &offset);
        if (r == ARCHIVE_EOF) {
            return ARCHIVE_OK;
        }

        if (r != ARCHIVE_OK) {
            return r;
        }

        r = archive_write_data_block(aw, buff, size, offset);

        if (r != ARCHIVE_OK) {
            return r;
        }
    }

    return ARCHIVE_OK;
}
Exemple #8
0
static int
copy_data(struct archive *ar, struct archive *aw)
{
    int r;
    const void *buff;
    size_t size;
#if ARCHIVE_VERSION >= 3000000
    int64_t offset;
#else
    off_t offset;
#endif

    for (;;)
    {
        r = archive_read_data_block(ar, &buff, &size, &offset);

        if (r == ARCHIVE_EOF)
            return ARCHIVE_OK;

        if (r != ARCHIVE_OK)
            return r;

        r = archive_write_data_block(aw, buff, size, offset);

        if (r != ARCHIVE_OK)
        {
            ereport(WARNING,
                    (errcode(ERRCODE_IO_ERROR),
                     errmsg("%s", archive_error_string(aw))));
            return r;
        }
    }
}
static int
copy_data(struct archive *ar, struct archive *aw)
{
	int64_t offset;
	const void *buff;
	struct archive_read_extract *extract;
	size_t size;
	int r;

	extract = __archive_read_get_extract((struct archive_read *)ar);
	if (extract == NULL)
		return (ARCHIVE_FATAL);
	for (;;) {
		r = archive_read_data_block(ar, &buff, &size, &offset);
		if (r == ARCHIVE_EOF)
			return (ARCHIVE_OK);
		if (r != ARCHIVE_OK)
			return (r);
		r = (int)archive_write_data_block(aw, buff, size, offset);
		if (r < ARCHIVE_WARN)
			r = ARCHIVE_WARN;
		if (r < ARCHIVE_OK) {
			archive_set_error(ar, archive_errno(aw),
			    "%s", archive_error_string(aw));
			return (r);
		}
		if (extract->extract_progress)
			(extract->extract_progress)
			    (extract->extract_progress_user_data);
	}
}
Exemple #10
0
static int
copy_data(struct archive *ar, struct archive *aw)
{
	int r;
	const void *buff;
	size_t size;
#if ARCHIVE_VERSION_NUMBER >= 3000000
	int64_t offset;
#else
	off_t offset;
#endif

	for (;;) {
		r = archive_read_data_block(ar, &buff, &size, &offset);
		if (r == ARCHIVE_EOF)
			return (ARCHIVE_OK);
		if (r != ARCHIVE_OK)
			return (r);
		r = archive_write_data_block(aw, buff, size, offset);
		if (r != ARCHIVE_OK) {
			warn("archive_write_data_block()",
			    archive_error_string(aw));
			return (r);
		}
	}
}
Exemple #11
0
static void extract_recovery(char *ramdisk_path)
{
    // Delete everything in the current root
    DIR *root = opendir("/");
    struct dirent *dp;
    while ((dp = readdir(root)) != NULL)
    {
        unlink(dp->d_name);
    }
    closedir(root);

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

        while (1)
        {
            struct archive_entry *entry;

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

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

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

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

        archive_write_free(ext);
    }

    archive_read_free(a);
}
Exemple #12
0
static int archive_copy_data(struct archive* in, struct archive* out) {
	const void* buf;
	size_t size;
	off_t offset;
	int res = ARCHIVE_OK;

	while (res == ARCHIVE_OK) {
		res = archive_read_data_block(in, &buf, &size, &offset);
		if (res == ARCHIVE_OK) {
			res = archive_write_data_block(out, buf, size, offset);
		}
	}
	return (res == ARCHIVE_EOF) ? ARCHIVE_OK : res;
}
static void create_reg_file2(struct archive_entry *ae, const char *msg)
{
	const int datasize = 100000;
	char *data;
	char *compare;
	struct archive *ad;
	struct stat st;
	int i, fd;

	data = malloc(datasize);
	for (i = 0; i < datasize; i++)
		data[i] = (char)(i % 256);

	/* Write the entry to disk. */
	assert((ad = archive_write_disk_new()) != NULL);
	failure("%s", msg);
	/*
	 * See above for an explanation why this next call
	 * is necessary.
	 */
	archive_entry_set_size(ae, datasize);
	assertEqualIntA(ad, 0, archive_write_header(ad, ae));
	for (i = 0; i < datasize - 999; i += 1000) {
		assertEqualIntA(ad, ARCHIVE_OK,
		    archive_write_data_block(ad, data + i, 1000, i));
	}
	assertEqualIntA(ad, 0, archive_write_finish_entry(ad));
#if ARCHIVE_API_VERSION > 1
	assertEqualInt(0, archive_write_finish(ad));
#else
	archive_write_finish(ad);
#endif
	/* Test the entries on disk. */
	assert(0 == stat(archive_entry_pathname(ae), &st));
	failure("st.st_mode=%o archive_entry_mode(ae)=%o",
	    st.st_mode, archive_entry_mode(ae));
	assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK));
	assertEqualInt(st.st_size, i);

	compare = malloc(datasize);
	fd = open(archive_entry_pathname(ae), O_RDONLY);
	assertEqualInt(datasize, read(fd, compare, datasize));
	close(fd);
	assert(memcmp(compare, data, datasize) == 0);
	free(compare);
	free(data);
}
Exemple #14
0
static int CopyArchiveData(struct archive *ar, struct archive *aw)
{
  const void *buff;
  size_t size;
  __int64 offset;

  while (true)
  {
     int r = archive_read_data_block(ar, &buff, &size, &offset);
     if (r == ARCHIVE_EOF)
        return ARCHIVE_OK;
     if (r != ARCHIVE_OK)
        return r;
     r = archive_write_data_block(aw, buff, size, offset);
     if (r != ARCHIVE_OK)
        return r;
  }
}
Exemple #15
0
// Based on libarchive's public example code.
// https://github.com/libarchive/libarchive/wiki/Examples#wiki-Constructing_Objects_On_Disk
ssize_t GuiZipper::copyData(struct archive *ar, struct archive *aw,
                            const char *userDirPath) throw (ZipperException*) {
  ssize_t r;
  const void *buff;
  size_t size;
  int64_t offset;
  for (;;) {
    r = archive_read_data_block(ar, &buff, &size, &offset);
    if (r == ARCHIVE_EOF) {
      return (ARCHIVE_OK);
    }
    if (r != ARCHIVE_OK) {
      return (r);
    }
    r = archive_write_data_block(aw, buff, size, offset);
    checkForErrors("Error writing archive data block", ar, r);
    return r;
  }
}
static int emb_ruby_uncompress_copy_data(struct archive *ar, struct archive *aw)
{
  int r;
  const void *buff;
  size_t size;
  off_t offset;

  for (;;) {
    r = archive_read_data_block(ar, &buff, &size, &offset);
    if (r == ARCHIVE_EOF)
      return (ARCHIVE_OK);
    if (r < ARCHIVE_OK)
      return (r);
    r = archive_write_data_block(aw, buff, size, offset);
    if (r < ARCHIVE_OK) {
      fprintf(stderr, "%s\n", archive_error_string(aw));
      return (r);
    }
  }
}
Exemple #17
0
static int
copy_data(struct archive *ar, struct archive *aw)
{
	int r;
	const void *buff;
	size_t size;
	off_t offset;

	for (;;) {
		r = archive_read_data_block(ar, &buff, &size, &offset);
		if (r == ARCHIVE_EOF)
			return (ARCHIVE_OK);
		if (r != ARCHIVE_OK)
			return (r);
		r = archive_write_data_block(aw, buff, size, offset);
		if (r != ARCHIVE_OK) {
			die(archive_error_string(aw));
			return (r);
		}
	}
}
static void
copy_archive (struct archive *ar,
              struct archive *aw)
{
  int r;
  const void *buff;
  size_t size;
  int64_t offset;

  while (1)
    {
      r = archive_read_data_block (ar, &buff, &size, &offset);
      if (r == ARCHIVE_EOF)
        break;
      if (r != ARCHIVE_OK)
        die_with_libarchive (ar, "archive_write_data_block: %s");

      r = archive_write_data_block (aw, buff, size, offset);
      if (r != ARCHIVE_OK)
        die_with_libarchive (aw, "archive_write_data_block: %s");
    }
}
Exemple #19
0
static int copy_data(struct archive* ar, struct archive* aw)
{
    const void* buff;
    size_t size;
    off_t offset;
    for (;;) {
        int r = archive_read_data_block(ar, &buff, &size, &offset);
        if (r == ARCHIVE_EOF) {
            return ARCHIVE_OK;
        }
        if (r != ARCHIVE_OK) {
            return r;
        }

        r = archive_write_data_block(aw, buff, size, offset);
        if (r != ARCHIVE_OK) {
            errmsg(archive_error_string(ar));
            return r;
        }
    }
    return 0;
}
int libarchive_copy_data(archive *in, archive *out, archive_entry *entry)
{
    const void *buff;
    size_t size;
    int64_t offset;
    int ret;

    while ((ret = archive_read_data_block(
            in, &buff, &size, &offset)) == ARCHIVE_OK) {
        if (archive_write_data_block(out, buff, size, offset) != ARCHIVE_OK) {
            LOGE("%s: Failed to write data: %s", archive_entry_pathname(entry),
                 archive_error_string(out));
            return ARCHIVE_FAILED;
        }
    }

    if (ret != ARCHIVE_EOF) {
        LOGE("%s: Data copy ended without reaching EOF: %s",
             archive_entry_pathname(entry), archive_error_string(in));
        return ARCHIVE_FAILED;
    }

    return ARCHIVE_OK;
}
Exemple #21
0
/*
 * As above, but using the archive_write_data_block() call.
 */
static void
verify_write_data_block(struct archive *a, int sparse)
{
    static const char data[]="abcdefghijklmnopqrstuvwxyz";
    struct stat st;
    struct archive_entry *ae;
    size_t buff_size = 64 * 1024;
    char *buff, *p;
    const char *msg = sparse ? "sparse" : "non-sparse";
    FILE *f;

    buff = malloc(buff_size);
    assert(buff != NULL);

    ae = archive_entry_new();
    assert(ae != NULL);
    archive_entry_set_size(ae, 8 * buff_size);
    archive_entry_set_pathname(ae, "test_write_data_block");
    archive_entry_set_mode(ae, AE_IFREG | 0755);
    assertEqualIntA(a, 0, archive_write_header(a, ae));

    /* Use archive_write_data_block() to write three
       relatively sparse blocks. */

    /* First has non-null data at beginning. */
    memset(buff, 0, buff_size);
    memcpy(buff, data, sizeof(data));
    failure("%s", msg);
    assertEqualInt(ARCHIVE_OK,
                   archive_write_data_block(a, buff, buff_size, 100));

    /* Second has non-null data in the middle. */
    memset(buff, 0, buff_size);
    memcpy(buff + buff_size / 2 - 3, data, sizeof(data));
    failure("%s", msg);
    assertEqualInt(ARCHIVE_OK,
                   archive_write_data_block(a, buff, buff_size, buff_size + 200));

    /* Third has non-null data at the end. */
    memset(buff, 0, buff_size);
    memcpy(buff + buff_size - sizeof(data), data, sizeof(data));
    failure("%s", msg);
    assertEqualInt(ARCHIVE_OK,
                   archive_write_data_block(a, buff, buff_size, buff_size * 2 + 300));

    failure("%s", msg);
    assertEqualIntA(a, 0, archive_write_finish_entry(a));

    /* Test the entry on disk. */
    assert(0 == stat(archive_entry_pathname(ae), &st));
    assertEqualInt(st.st_size, 8 * buff_size);
    f = fopen(archive_entry_pathname(ae), "rb");
    if (!assert(f != NULL))
        return;

    /* Check 100-byte gap at beginning */
    assertEqualInt(100, fread(buff, 1, 100, f));
    failure("%s", msg);
    for (p = buff; p < buff + 100; ++p) {
        failure("offset: %d, %s", (int)(p - buff), msg);
        if (!assertEqualInt(0, *p))
            break;
    }

    /* Check first block. */
    assertEqualInt(buff_size, fread(buff, 1, buff_size, f));
    failure("%s", msg);
    assertEqualMem(buff, data, sizeof(data));
    for (p = buff + sizeof(data); p < buff + buff_size; ++p) {
        failure("offset: %d, %s", (int)(p - buff), msg);
        if (!assertEqualInt(0, *p))
            break;
    }

    /* Check 100-byte gap */
    assertEqualInt(100, fread(buff, 1, 100, f));
    failure("%s", msg);
    for (p = buff; p < buff + 100; ++p) {
        failure("offset: %d, %s", (int)(p - buff), msg);
        if (!assertEqualInt(0, *p))
            break;
    }

    /* Check second block. */
    assertEqualInt(buff_size, fread(buff, 1, buff_size, f));
    for (p = buff; p < buff + buff_size; ++p) {
        failure("offset: %d, %s", (int)(p - buff), msg);
        if (p == buff + buff_size / 2 - 3) {
            assertEqualMem(p, data, sizeof(data));
            p += sizeof(data);
        } else if (!assertEqualInt(0, *p))
            break;
    }

    /* Check 100-byte gap */
    assertEqualInt(100, fread(buff, 1, 100, f));
    failure("%s", msg);
    for (p = buff; p < buff + 100; ++p) {
        failure("offset: %d, %s", (int)(p - buff), msg);
        if (!assertEqualInt(0, *p))
            break;
    }

    /* Check third block. */
    assertEqualInt(buff_size, fread(buff, 1, buff_size, f));
    for (p = buff; p < buff + buff_size - sizeof(data); ++p) {
        failure("offset: %d, %s", (int)(p - buff), msg);
        if (!assertEqualInt(0, *p))
            break;
    }
    failure("%s", msg);
    assertEqualMem(buff + buff_size - sizeof(data), data, sizeof(data));

    /* Check another block size beyond last we wrote. */
    assertEqualInt(buff_size, fread(buff, 1, buff_size, f));
    failure("%s", msg);
    for (p = buff; p < buff + buff_size; ++p) {
        failure("offset: %d, %s", (int)(p - buff), msg);
        if (!assertEqualInt(0, *p))
            break;
    }


    /* XXX more XXX */

    assertEqualInt(0, fclose(f));
    free(buff);
    archive_entry_free(ae);
}
//********************************************************************************************************
void read_archive(const char* const infile, const char* const extractFolder){
  // Strongly inspired by
  // https://github.com/libarchive/libarchive/wiki/Examples#A_Complete_Extractor

  //printf("Opening archive '%s' for extracting to folder '%s'...\n",infile,extractFolder);

  //Check that the archive exists

  //Check that the folder exists, if not then create it

  struct archive* a = archive_read_new();
  archive_read_support_format_zip(a);
  struct archive* ext = archive_write_disk_new();
  archive_write_disk_set_options(ext,ARCHIVE_EXTRACT_TIME|ARCHIVE_EXTRACT_PERM|ARCHIVE_EXTRACT_ACL|ARCHIVE_EXTRACT_FFLAGS);
  archive_write_disk_set_standard_lookup(ext);

  int err;
  err = archive_read_open_filename(a, infile, 10240);
  if (err != ARCHIVE_OK) {
    fprintf(stderr, "CRITICAL ERROR in read_archive(): When opening archive '%s', err=%i\n",infile,err);
    fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a));
    exit(EXIT_FAILURE);
  }

  struct archive_entry *entry;

  const int fcount_max = 1000;
  char fcompleted=0; //C-Boolean
  for(int fcount=0; fcount<fcount_max;fcount++){
    err = archive_read_next_header(a,&entry);
    if (err == ARCHIVE_EOF){
      fcompleted=1;
      break;
    }
    else if (err != ARCHIVE_OK){
      fprintf(stderr, "CRITICAL ERROR in read_archive(): When reading archive, err=%i\n",err);
      fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a));
      exit(EXIT_FAILURE);
    }
    //printf("Found file: '%s'\n",archive_entry_pathname(entry));

    //Avoid clobbering files in current directory - solution from
    // http://stackoverflow.com/questions/4496001/libarchive-to-extract-to-a-specified-folder
    char newPath[PATH_MAX];
    int buff_used = snprintf(newPath, PATH_MAX, "%s/%s",extractFolder,archive_entry_pathname(entry));
    if (buff_used >= PATH_MAX || buff_used < 0){
      fprintf(stderr, "CRITICAL ERROR in read_archive(): Buffer overflow or other error when creating the path.\n");
      fprintf(stderr, "CRITICAL ERROR in read_archive(): buff_used=%i\n",buff_used);
      exit(EXIT_FAILURE);
    }
    archive_entry_set_pathname(entry,newPath);

    err = archive_write_header(ext, entry);
    if (err != ARCHIVE_OK){
      fprintf(stderr, "CRITICAL ERROR in read_archive(): when extracting archive (creating new file), err=%i\n",err);
      fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(ext));
      exit(EXIT_FAILURE);
    }

    //Write the data!
    const void* buff;
    size_t size;
    la_int64_t offset;

    const int bcount_max = 100000000;
    char bcompleted = 0; //C boolean
    for (int bcount=0; bcount<bcount_max;bcount++){
      err = archive_read_data_block(a,&buff,&size, &offset);
      if ( err == ARCHIVE_EOF ) {
	bcompleted=1;
	break;
      }
      else if (err != ARCHIVE_OK){
	fprintf(stderr, "CRITICAL ERROR in read_archive(): When extracting archive (reading data), err=%i\n",err);
	fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a));
	exit(EXIT_FAILURE);
      }

      err = archive_write_data_block(ext,buff,size,offset);
      if (err != ARCHIVE_OK){
	fprintf(stderr, "CRITICAL ERROR in read_archive(): When extracting archive (writing data), err=%i\n",err);
	fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a));
	exit(EXIT_FAILURE);
      }
    }
    if (!bcompleted){
      fprintf(stderr, "CRITICAL ERROR in read_archive(): The file writing block loop was aborted by the infinite loop guard\n");
      exit(EXIT_FAILURE);
    }

    err=archive_write_finish_entry(ext);
    if (err != ARCHIVE_OK) {
      fprintf(stderr, "CRITICAL ERROR in read_archive(): When extracting archive (closing new file), err=%i\n",err);
      fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(ext));
      exit(EXIT_FAILURE);
    }
  }

  archive_read_close(a);
  err=archive_read_free(a);
  if (err != ARCHIVE_OK){
    fprintf(stderr, "CRITICAL ERROR in read_archive(): When calling archive_read_free(a), err=%i\n",err);
    fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a));
    exit(EXIT_FAILURE);
  }
  archive_write_close(ext);
  err = archive_write_free(ext);
  if (err != ARCHIVE_OK){
    fprintf(stderr, "CRITICAL ERROR in read_archive(): When calling archive_read_free(ext), err=%i\n",err);
    fprintf(stderr, "CRITICAL ERROR in read_archive(): %s\n",archive_error_string(a));
    exit(EXIT_FAILURE);
  }

  if (!fcompleted) {
    fprintf(stderr, "CRITICAL ERROR in read_archive(): The file header loop was aborted by the infinite loop guard\n");
    exit(EXIT_FAILURE);
  }
}
bool extract_archive(const char *filename, const char *target)
{
    struct archive *in = NULL;
    struct archive *out = NULL;
    struct archive_entry *entry;
    int ret;
    char *cwd = NULL;

    if (!(in = archive_read_new())) {
        LOGE("Out of memory");
        goto error;
    }

    // Add more as needed
    //archive_read_support_format_all(in);
    //archive_read_support_filter_all(in);
    archive_read_support_format_tar(in);
    archive_read_support_format_zip(in);
    archive_read_support_filter_xz(in);

    if (archive_read_open_filename(in, filename, 10240) != ARCHIVE_OK) {
        LOGE("%s: Failed to open archive: %s", filename, archive_error_string(in));
        goto error;
    }

    if (!(out = archive_write_disk_new())) {
        LOGE("Out of memory");
        goto error;
    }

    archive_write_disk_set_options(out,
                                   ARCHIVE_EXTRACT_ACL |
                                   ARCHIVE_EXTRACT_FFLAGS |
                                   ARCHIVE_EXTRACT_PERM |
                                   ARCHIVE_EXTRACT_SECURE_NODOTDOT |
                                   ARCHIVE_EXTRACT_SECURE_SYMLINKS |
                                   ARCHIVE_EXTRACT_TIME |
                                   ARCHIVE_EXTRACT_UNLINK |
                                   ARCHIVE_EXTRACT_XATTR);

    if (!(cwd = getcwd(NULL, 0))) {
        LOGE("Failed to get cwd: %s", strerror(errno));
        goto error;
    }

    if (chdir(target) < 0) {
        LOGE("%s: Failed to change to target directory: %s",
             target, strerror(errno));
        goto error;
    }

    while ((ret = archive_read_next_header(in, &entry)) == ARCHIVE_OK) {
        if ((ret = archive_write_header(out, entry)) != ARCHIVE_OK) {
            LOGE("Failed to write header: %s", archive_error_string(out));
            goto error;
        }

        const void *buff;
        size_t size;
        int64_t offset;
        int ret;

        while ((ret = archive_read_data_block(
                in, &buff, &size, &offset)) == ARCHIVE_OK) {
            if (archive_write_data_block(out, buff, size, offset) != ARCHIVE_OK) {
                LOGE("Failed to write data: %s", archive_error_string(out));
                goto error;
            }
        }

        if (ret != ARCHIVE_EOF) {
            LOGE("Data copy ended without reaching EOF: %s",
                 archive_error_string(in));
            goto error;
        }
    }

    if (ret != ARCHIVE_EOF) {
        LOGE("Archive extraction ended without reaching EOF: %s",
             archive_error_string(in));
        goto error;
    }

    chdir(cwd);

    archive_read_free(in);
    archive_write_free(out);

    return true;

error:
    if (cwd) {
        chdir(cwd);
    }

    archive_read_free(in);
    archive_write_free(out);

    return false;
}
Exemple #24
0
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;
}
Exemple #25
0
void Package::readPackageFile(const std::string &package_path)
{
    if (!package_path.empty())
        mPackagePath = package_path;

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

    const void *buf;

    int r;

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

    archive_read_support_compression_bzip2(a);
    archive_read_support_format_tar(a);


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

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

    while (true) {

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

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

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

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

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


            r = archive_write_finish_entry(ext);
            if (r < ARCHIVE_OK)
                std::cerr << archive_error_string(ext) << std::endl;
            if (r < ARCHIVE_WARN) {
                archive_read_free(a);
                archive_write_free(ext);
                throw Exception(std::string(archive_error_string(ext)));
            }
        }
    }
    archive_read_close(a);
    archive_read_free(a);
    archive_write_close(ext);
    archive_write_free(ext);
}