예제 #1
0
static int crypto_xz_decompress(struct crypto_tfm *tfm, const u8 *src,
				unsigned int slen, u8 *dst, unsigned int *dlen)
{
	struct xz_comp_ctx *dctx = crypto_tfm_ctx(tfm);
	struct xz_buf *xz_buf = &dctx->decomp_buf;
	int ret;

	memset(xz_buf, '\0', sizeof(struct xz_buf));

	xz_buf->in = (u8 *) src;
	xz_buf->in_pos = 0;
	xz_buf->in_size = slen;
	xz_buf->out = (u8 *) dst;
	xz_buf->out_pos = 0;
	xz_buf->out_size = *dlen;

	ret = xz_dec_run(dctx->decomp_state, xz_buf);
	if (ret != XZ_STREAM_END) {
		ret = -EINVAL;
		goto out;
	}

	*dlen = xz_buf->out_pos;
	ret = 0;

out:
	return ret;
}
예제 #2
0
파일: xzio.c 프로젝트: Spacy/grub-fuse
/* Function xz_dec_run() should consume header and ask for more (XZ_OK)
 * else file is corrupted (or options not supported) or not xz.  */
static int
test_header (grub_file_t file)
{
  grub_xzio_t xzio = file->data;
  xzio->buf.in_size = grub_file_read (xzio->file, xzio->inbuf,
				      STREAM_HEADER_SIZE);

  if (xzio->buf.in_size != STREAM_HEADER_SIZE)
    {
      grub_error (GRUB_ERR_BAD_FILE_TYPE, "no xz magic found");
      return 0;
    }

  enum xz_ret ret = xz_dec_run (xzio->dec, &xzio->buf);

  if (ret == XZ_FORMAT_ERROR)
    {
      grub_error (GRUB_ERR_BAD_FILE_TYPE, "no xz magic found");
      return 0;
    }

  if (ret != XZ_OK)
    {
      grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "not supported xz options");
      return 0;
    }

  return 1;
}
예제 #3
0
파일: buftest.c 프로젝트: 2asoft/freebsd
int main(void)
{
	struct xz_buf b;
	struct xz_dec *s;
	enum xz_ret ret;

	xz_crc32_init();

	s = xz_dec_init(XZ_SINGLE, 0);
	if (s == NULL) {
		fputs("Initialization failed", stderr);
		return 1;
	}

	b.in = in;
	b.in_pos = 0;
	b.in_size = fread(in, 1, sizeof(in), stdin);
	b.out = out;
	b.out_pos = 0;
	b.out_size = sizeof(out);

	ret = xz_dec_run(s, &b);
	xz_dec_end(s);

	fwrite(out, 1, b.out_pos, stdout);
	fprintf(stderr, "%d\n", ret);

	return 0;
}
예제 #4
0
파일: unxz.c 프로젝트: Acidburn0zzz/libxmp
static int decrunch_xz(FILE *in, FILE *out)
{
	struct xz_buf b;
	struct xz_dec *state;
	unsigned char *membuf;
	int ret = 0;

	crc32_init_A();

	memset(&b, 0, sizeof(b));
	if ((membuf = malloc(2 * BUFFER_SIZE)) == NULL)
		return -1;

	b.in = membuf;
	b.out = membuf + BUFFER_SIZE;
	b.out_size = BUFFER_SIZE;

	/* Limit memory usage to 16M */
	state = xz_dec_init(XZ_DYNALLOC, 16 * 1024 * 1024);

	while (1) {
		enum xz_ret r;

		if (b.in_pos == b.in_size) {
			int rd = fread(membuf, 1, BUFFER_SIZE, in);
			if (rd < 0) {
				ret = -1;
				break;
			}
			b.in_size = rd;
			b.in_pos = 0;
		}

		r = xz_dec_run(state, &b);

		if (b.out_pos) {
			fwrite(b.out, 1, b.out_pos, out);
			b.out_pos = 0;
		}

		if (r == XZ_STREAM_END) {
			break;
		}

		if (r != XZ_OK && r != XZ_UNSUPPORTED_CHECK) {
			ret = -1;
			break;
		}
	}

	xz_dec_end(state);
	free(membuf);

	return ret;
}
예제 #5
0
size_t XzStreamReader::Read(void* buffer, size_t length)
{
	bool freemem = false;							// Flag to free buffer

#ifdef _WIN64
	if(length > UINT32_MAX) throw std::invalid_argument("length");
#endif

	if((length == 0) || (m_finished)) return 0;		// Nothing to do

	// The caller can specify NULL if the output data is irrelevant, but xz
	// expects to be able to write the decompressed data somewhere ...
	if(!buffer) {

		buffer = malloc(length);
		if(!buffer) throw std::bad_alloc();
		freemem = true;
	}

	// Set the output buffer pointer and length for xz
	m_buffer.out = reinterpret_cast<uint8_t*>(buffer);
	m_buffer.out_pos = 0;
	m_buffer.out_size = length;

	// Decompress up to the requested number of bytes from the compressed stream
	xz_ret result = xz_dec_run(m_decoder, &m_buffer);
	if(freemem) free(buffer);

	// Check the result from xz_dec_run for memory errors
	if((result == XZ_MEM_ERROR) || (result == XZ_MEMLIMIT_ERROR)) throw std::bad_alloc();

	// Assume any other bad thing that happened was due to a corrupt/unsupported input file
	if((result != XZ_OK) && (result != XZ_STREAM_END)) throw std::exception("xz: decompression stream data is corrupt");

	// XZ will raise an error on an attempt to read beyond the end
	if(result == XZ_STREAM_END) m_finished = true;

	m_position += m_buffer.out_pos;
	return m_buffer.out_pos;
}
예제 #6
0
파일: xzio.c 프로젝트: jnbek/grub2-fedora
/* Function xz_dec_run() should consume header and ask for more (XZ_OK)
 * else file is corrupted (or options not supported) or not xz.  */
static int
test_header (grub_file_t file)
{
  grub_xzio_t xzio = file->data;
  enum xz_ret ret;

  xzio->buf.in_size = grub_file_read (xzio->file, xzio->inbuf,
				      STREAM_HEADER_SIZE);

  if (xzio->buf.in_size != STREAM_HEADER_SIZE)
    return 0;

  ret = xz_dec_run (xzio->dec, &xzio->buf);

  if (ret == XZ_FORMAT_ERROR)
    return 0;

  if (ret != XZ_OK)
    return 0;

  return 1;
}
예제 #7
0
파일: xzio.c 프로젝트: Spacy/grub-fuse
static grub_ssize_t
grub_xzio_read (grub_file_t file, char *buf, grub_size_t len)
{
  grub_ssize_t ret = 0;
  grub_ssize_t readret;
  enum xz_ret xzret;
  grub_xzio_t xzio = file->data;
  grub_off_t current_offset;

  /* If seek backward need to reset decoder and start from beginning of file.
     TODO Possible improvement by jumping blocks.  */
  if (file->offset < xzio->saved_offset)
    {
      xz_dec_reset (xzio->dec);
      xzio->saved_offset = 0;
      xzio->buf.out_pos = 0;
      xzio->buf.in_pos = 0;
      xzio->buf.in_size = 0;
      grub_file_seek (xzio->file, 0);
    }

  current_offset = xzio->saved_offset;

  while (len > 0)
    {
      xzio->buf.out_size = grub_min (file->offset + ret + len - current_offset,
				     XZBUFSIZ);

      /* Feed input.  */
      if (xzio->buf.in_pos == xzio->buf.in_size)
	{
	  readret = grub_file_read (xzio->file, xzio->inbuf, XZBUFSIZ);
	  if (readret < 0)
	    return -1;
	  xzio->buf.in_size = readret;
	  xzio->buf.in_pos = 0;
	}

      xzret = xz_dec_run (xzio->dec, &xzio->buf);
      switch (xzret)
	{
	case XZ_MEMLIMIT_ERROR:
	case XZ_FORMAT_ERROR:
	case XZ_OPTIONS_ERROR:
	case XZ_DATA_ERROR:
	case XZ_BUF_ERROR:
	  grub_error (GRUB_ERR_BAD_COMPRESSED_DATA,
		      "file corrupted or unsupported block options");
	  return -1;
	default:
	  break;
	}

      {
	grub_off_t new_offset = current_offset + xzio->buf.out_pos;
	
	if (file->offset <= new_offset)
	  /* Store first chunk of data in buffer.  */
	  {
	    grub_size_t delta = new_offset - (file->offset + ret);
	    grub_memmove (buf, xzio->buf.out + (xzio->buf.out_pos - delta),
			  delta);
	    len -= delta;
	    buf += delta;
	    ret += delta;
	  }
	current_offset = new_offset;
      }
      xzio->buf.out_pos = 0;

      if (xzret == XZ_STREAM_END)	/* Stream end, EOF.  */
	break;
    }

  if (ret >= 0)
    xzio->saved_offset = file->offset + ret;

  return ret;
}
예제 #8
0
/*
 * This function implements the API defined in <linux/decompress/generic.h>.
 *
 * This wrapper will automatically choose single-call or multi-call mode
 * of the native XZ decoder API. The single-call mode can be used only when
 * both input and output buffers are available as a single chunk, i.e. when
 * fill() and flush() won't be used.
 */
STATIC int decompress_unxz(unsigned char *in, int in_size,
		     int (*fill)(void *dest, unsigned int size),
		     int (*flush)(void *src, unsigned int size),
		     unsigned char *out, int *in_used,
		     void (*error)(char *x))
{
	struct xz_buf b;
	struct xz_dec *s;
	enum xz_ret ret;
	bool must_free_in = false;

#if XZ_INTERNAL_CRC32
	xz_crc32_init();
#endif

	if (in_used != NULL)
		*in_used = 0;

	if (fill == NULL && flush == NULL)
		s = xz_dec_init(XZ_SINGLE, 0);
	else
		s = xz_dec_init(XZ_DYNALLOC, (uint32_t)-1);

	if (s == NULL)
		goto error_alloc_state;

	if (flush == NULL) {
		b.out = out;
		b.out_size = (size_t)-1;
	} else {
		b.out_size = XZ_IOBUF_SIZE;
		b.out = MALLOC(XZ_IOBUF_SIZE);
		if (b.out == NULL)
			goto error_alloc_out;
	}

	if (in == NULL) {
		must_free_in = true;
		in = MALLOC(XZ_IOBUF_SIZE);
		if (in == NULL)
			goto error_alloc_in;
	}

	b.in = in;
	b.in_pos = 0;
	b.in_size = in_size;
	b.out_pos = 0;

	if (fill == NULL && flush == NULL) {
		ret = xz_dec_run(s, &b);
	} else {
		do {
			if (b.in_pos == b.in_size && fill != NULL) {
				if (in_used != NULL)
					*in_used += b.in_pos;

				b.in_pos = 0;

				in_size = fill(in, XZ_IOBUF_SIZE);
				if (in_size < 0) {
					/*
					 * This isn't an optimal error code
					 * but it probably isn't worth making
					 * a new one either.
					 */
					ret = XZ_BUF_ERROR;
					break;
				}

				b.in_size = in_size;
			}

			ret = xz_dec_run(s, &b);

			if (flush != NULL && (b.out_pos == b.out_size
					|| (ret != XZ_OK && b.out_pos > 0))) {
				/*
				 * Setting ret here may hide an error
				 * returned by xz_dec_run(), but probably
				 * it's not too bad.
				 */
				if (flush(b.out, b.out_pos) != (long)b.out_pos)
					ret = XZ_BUF_ERROR;

				b.out_pos = 0;
			}
		} while (ret == XZ_OK);

		if (must_free_in)
			FREE(in);

		if (flush != NULL)
			FREE(b.out);
	}

	if (in_used != NULL)
		*in_used += b.in_pos;

	xz_dec_end(s);

	switch (ret) {
	case XZ_STREAM_END:
		return 0;

	case XZ_MEM_ERROR:
		/* This can occur only in multi-call mode. */
		error("XZ decompressor ran out of memory");
		break;

	case XZ_FORMAT_ERROR:
		error("Input is not in the XZ format (wrong magic bytes)");
		break;

	case XZ_OPTIONS_ERROR:
		error("Input was encoded with settings that are not "
				"supported by this XZ decoder");
		break;

	case XZ_DATA_ERROR:
	case XZ_BUF_ERROR:
		error("XZ-compressed data is corrupt");
		break;

	default:
		error("Bug in the XZ decompressor");
		break;
	}

	return -1;

error_alloc_in:
	if (flush != NULL)
		FREE(b.out);

error_alloc_out:
	xz_dec_end(s);

error_alloc_state:
	error("XZ decompressor ran out of memory");
	return -1;
}
예제 #9
0
static errlHndl_t load_pnor_section(PNOR::SectionId i_section,
        uint64_t i_physAddr)
{
    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,ENTER_MRK"load_pnor_section()");
    errlHndl_t err = nullptr;

#ifdef CONFIG_SECUREBOOT
    // Securely load section
    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,"load_pnor_section: secure section load of secId=0x%X (%s)",
              i_section, PNOR::SectionIdToString(i_section));
    err = PNOR::loadSecureSection(i_section);
    if (err)
    {
        return err;
    }
    // Do not need to unload since we have plenty of memory at this point.
#endif

    // Get the section info from PNOR.
    PNOR::SectionInfo_t pnorSectionInfo;
    err = PNOR::getSectionInfo( i_section, pnorSectionInfo );
    if( err != nullptr )
    {
        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                 "load_pnor_section: Could not get section info from %x",
                  i_section);
        return err;
    }

    // XZ repository: http:git.tukaani.org/xz.git
    // Header specifics can be found in xz/doc/xz-file-format.txt
    const uint8_t HEADER_MAGIC[]= { 0xFD, '7', 'z', 'X', 'Z', 0x00 };
    uint8_t* l_pnor_header = reinterpret_cast<uint8_t *>(pnorSectionInfo.vaddr);

    bool l_pnor_is_XZ_compressed = (0 == memcmp(l_pnor_header,
                               HEADER_MAGIC, sizeof(HEADER_MAGIC)));

    TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
             "load_pnor_section: is XZ_compressed: %d",
              l_pnor_is_XZ_compressed);

    // This assumes that the maximum decompression ratio will always be less
    // than 1:16 (compressed:uncompressed).  This works because XZ compression
    // is usually 14.1%, the decompressor does not need the exact size, and
    // we have all of mainstore memory at this point.
    uint32_t uncompressedPayloadSize = l_pnor_is_XZ_compressed ?
            (pnorSectionInfo.size * 16) : pnorSectionInfo.size;


    const uint32_t originalPayloadSize = pnorSectionInfo.size;

    printk( "Loading PNOR section %d (%s) %d bytes @0x%lx\n",
            i_section,
            pnorSectionInfo.name,
            originalPayloadSize,
            i_physAddr );

    void * loadAddr = NULL;
    // Map in the physical memory we are loading into.
    // If we are not xz compressed, the uncompressedSize
    // is equal to the original size.
    loadAddr = mm_block_map( reinterpret_cast<void*>( i_physAddr ),
                             uncompressedPayloadSize );

    // Print out inital progress bar.
#ifdef CONFIG_CONSOLE
    const int progressSteps = 80;
    int progress = 0;
    for ( int i = 0; i < progressSteps; ++i )
    {
        printk( "." );
    }
    printk( "\r" );
#endif

    if(!l_pnor_is_XZ_compressed)
    {
        // Load the data block by block and update the progress bar.
        const uint32_t BLOCK_SIZE = 4096;
        for ( uint32_t i = 0; i < originalPayloadSize; i += BLOCK_SIZE )
        {
            memcpy( reinterpret_cast<void*>(
                      reinterpret_cast<uint64_t>(loadAddr) + i ),
                    reinterpret_cast<void*>( pnorSectionInfo.vaddr + i ),
                    std::min( originalPayloadSize - i, BLOCK_SIZE ) );
#ifdef CONFIG_CONSOLE
            for ( int new_progress = (i * progressSteps) /
                  originalPayloadSize;
                  progress <= new_progress; progress++ )
            {
                printk( "=" );
            }
#endif
        }
#ifdef CONFIG_CONSOLE
        printk( "\n" );
#endif
    }

    if(l_pnor_is_XZ_compressed)
    {
        struct xz_buf b;
        struct xz_dec *s;
        enum xz_ret ret;

        xz_crc32_init();
        s = xz_dec_init(XZ_SINGLE, 0);
        if(s == NULL)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,ERR_MRK
                     "load_pnor_section: XZ Embedded Initialization failed");
            return err;
        }

        static const uint64_t compressed_SIZE = originalPayloadSize;
        static const uint64_t decompressed_SIZE = uncompressedPayloadSize;

        b.in = reinterpret_cast<uint8_t *>( pnorSectionInfo.vaddr);
        b.in_pos = 0;
        b.in_size = compressed_SIZE;
        b.out = reinterpret_cast<uint8_t *>(loadAddr);
        b.out_pos = 0;
        b.out_size = decompressed_SIZE;

        ret = xz_dec_run(s, &b);

        if(ret == XZ_STREAM_END)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                     "load_pnor_section: The %s section was decompressed.",
                      pnorSectionInfo.name);
        }else
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,ERR_MRK
                     "load_pnor_section: xz-embedded returned an error, ",
                     "the ret is %d",ret);

            /*@
             * @errortype
             * @reasoncode       fapi::RC_INVALID_RETURN_XZ_CODE
             * @severity         ERRORLOG::ERRL_SEV_UNRECOVERABLE
             * @moduleid         fapi::MOD_START_XZ_PAYLOAD
             * @devdesc          xz-embedded has returned an error.
             *                   the return code can be found in xz.h
             * @custdesc         Error uncompressing payload image from
             *                   boot flash
             * @userdata1        Return code from xz-embedded
             * @userdata2[0:31]  Original Payload Size
             * @userdata2[32:63] Uncompressed Payload Size
             */
            err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                            fapi::MOD_START_XZ_PAYLOAD,
                            fapi::RC_INVALID_RETURN_XZ_CODE,
                            ret,TWO_UINT32_TO_UINT64(
                                    originalPayloadSize,
                                    uncompressedPayloadSize));
            err->addProcedureCallout(HWAS::EPUB_PRC_PHYP_CODE,
                            HWAS::SRCI_PRIORITY_HIGH);

        }
        //Clean up memory
        xz_dec_end(s);

    }

    int rc = 0;
    rc = mm_block_unmap(reinterpret_cast<void *>(loadAddr));
    if(rc)
    {
        TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,ERR_MRK
                 "load_pnor_section: mm_block_unmap returned 1");

        /*@
         * @errortype
         * @reasoncode      fapi::RC_MM_UNMAP_ERR
         * @severity        ERRORLOG::ERRL_SEV_UNRECOVERABLE
         * @moduleid        fapi::MOD_START_XZ_PAYLOAD
         * @devdesc         mm_block_unmap returned incorrectly with 0
         * @custdesc        Error unmapping memory section
         */
        err = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                      fapi::MOD_START_XZ_PAYLOAD,
                                      fapi::RC_MM_UNMAP_ERR,
                                      0,0,0);
    }
    return err;
}
예제 #10
0
/*
 * Decode the data given to us from the userspace. CRC32 of the uncompressed
 * data is calculated and is printed at the end of successful decoding. The
 * uncompressed data isn't stored anywhere for further use.
 *
 * The .xz file must have exactly one Stream and no Stream Padding. The data
 * after the first Stream is considered to be garbage.
 */
static ssize_t xz_dec_test_write(struct file *file, const char __user *buf,
				 size_t size, loff_t *pos)
{
	size_t remaining;

	if (ret != XZ_OK) {
		if (size > 0)
			printk(KERN_INFO DEVICE_NAME ": %zu bytes of "
					"garbage at the end of the file\n",
					size);

		return -ENOSPC;
	}

	printk(KERN_INFO DEVICE_NAME ": decoding %zu bytes of input\n",
			size);

	remaining = size;
	while ((remaining > 0 || buffers.out_pos == buffers.out_size)
			&& ret == XZ_OK) {
		if (buffers.in_pos == buffers.in_size) {
			buffers.in_pos = 0;
			buffers.in_size = min(remaining, sizeof(buffer_in));
			if (copy_from_user(buffer_in, buf, buffers.in_size))
				return -EFAULT;

			buf += buffers.in_size;
			remaining -= buffers.in_size;
		}

		buffers.out_pos = 0;
		ret = xz_dec_run(state, &buffers);
		crc = crc32(crc, buffer_out, buffers.out_pos);
	}

	switch (ret) {
	case XZ_OK:
		printk(KERN_INFO DEVICE_NAME ": XZ_OK\n");
		return size;

	case XZ_STREAM_END:
		printk(KERN_INFO DEVICE_NAME ": XZ_STREAM_END, "
				"CRC32 = 0x%08X\n", ~crc);
		return size - remaining - (buffers.in_size - buffers.in_pos);

	case XZ_MEMLIMIT_ERROR:
		printk(KERN_INFO DEVICE_NAME ": XZ_MEMLIMIT_ERROR\n");
		break;

	case XZ_FORMAT_ERROR:
		printk(KERN_INFO DEVICE_NAME ": XZ_FORMAT_ERROR\n");
		break;

	case XZ_OPTIONS_ERROR:
		printk(KERN_INFO DEVICE_NAME ": XZ_OPTIONS_ERROR\n");
		break;

	case XZ_DATA_ERROR:
		printk(KERN_INFO DEVICE_NAME ": XZ_DATA_ERROR\n");
		break;

	case XZ_BUF_ERROR:
		printk(KERN_INFO DEVICE_NAME ": XZ_BUF_ERROR\n");
		break;

	default:
		printk(KERN_INFO DEVICE_NAME ": Bug detected!\n");
		break;
	}

	return -EIO;
}
예제 #11
0
int main(int argc, char **argv, char *envp[])
{
	struct xz_buf b;
	struct xz_dec *s;
	enum xz_ret ret;
	const char *msg;

	if (argc >= 2 && strcmp(argv[1], "--help") == 0) {
		fputs("Uncompress a .xz file from stdin to stdout.\n"
				"Arguments other than `--help' are ignored.\n",
				stdout);
		return 0;
	}

	xz_crc32_init();

	/*
	 * Support up to 64 MiB dictionary. The actually needed memory
	 * is allocated once the headers have been parsed.
	 */
	s = xz_dec_init(XZ_DYNALLOC, 1 << 26);
	if (s == NULL) {
		msg = "Memory allocation failed\n";
		goto error;
	}

	b.in = in;
	b.in_pos = 0;
	b.in_size = BUFSIZ;
	b.out = out;
	b.out_pos = 0;
	b.out_size = BUFSIZ;
//     TODO add error checking
        char temp_dir_name[] = "/tmp/unv_installer_XXXXXX"; /* TODO: find tmpdir, don't assume it is /tmp */
        mkdtemp(temp_dir_name);
        char temp_file_name[256];
        sprintf(temp_file_name, "%s/installer", temp_dir_name);
        FILE* temp_fp = fopen(temp_file_name, "w");
        while (true) {
		ret = xz_dec_run(s, &b);
		/*So that xz_dec_run will consume another BUFSIZ bytes (it reads from b.in_pos till b.in_size)*/
                if (fwrite(b.out, 1, b.out_pos, temp_fp) != b.out_pos) {
                        msg = "Write error\n";
                        goto error;
                    }

		if (ret == XZ_OK){
                    b.in_size+=BUFSIZ;
                    b.out_pos=0;
                    continue;
                }

#ifdef XZ_DEC_ANY_CHECK
		if (ret == XZ_UNSUPPORTED_CHECK) {
			fputs(argv[0], stderr);
			fputs(": ", stderr);
			fputs("Unsupported check; not verifying "
					"file integrity\n", stderr);
			continue;
		}
#endif

		switch (ret) {
		case XZ_STREAM_END:
			xz_dec_end(s);
                        chmod(temp_file_name, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
                        fclose(temp_fp);
                        printf("%s\n", temp_file_name);
                        int i = 0;
                        while (envp[i] != NULL){
                            i++;
                        }
                        char **env = malloc((i+1)*sizeof(char *));
                        memcpy(env, envp, i*sizeof(char *));
                        char var[256];
                        sprintf(var, "LD_LIBRARY_PATH=%s", temp_dir_name);
                        env[i] = var;
                        env[i+1] = (char*) NULL;
//                         {"LD_LIBRARY_PATH=", (char *) NULL};
                        execle(temp_file_name, temp_file_name, (char*) NULL, env);
                        printf("Weird\n");
                        return 1;  /*Will only occur if execl call failed.*/

		case XZ_MEM_ERROR:
			msg = "Memory allocation failed\n";
			goto error;

		case XZ_MEMLIMIT_ERROR:
			msg = "Memory usage limit reached\n";
			goto error;

		case XZ_FORMAT_ERROR:
			msg = "Not a .xz file\n";
			goto error;

		case XZ_OPTIONS_ERROR:
			msg = "Unsupported options in the .xz headers\n";
			goto error;

		case XZ_DATA_ERROR:
		case XZ_BUF_ERROR:
			msg = "File is corrupt\n";
			goto error;

		default:
			msg = "Bug!\n";
			goto error;
		}
	}


error:
	xz_dec_end(s);
	fputs(argv[0], stderr);
	fputs(": ", stderr);
	fputs(msg, stderr);
	return 1;
}
예제 #12
0
/**
 * Compress command: tar -c car/ | xz --check=crc32 --lzma2=preset=6e,dict=512Ki > car.tar.xz
 *																				 | ./iap 0.0.0.0 'target file'
 *
 * Decompress command: dxz 'src file' 'dest file'
 *                     dxz 'src file' | tar xv -C 
 */
int dxz_file(FILE *src, FILE *dest)
{
	struct xz_buf b;
	struct xz_dec *s;
	int ret;
	int show_flag = 0;

	xz_crc32_init();
	s = xz_dec_init(XZ_PREALLOC, XZ_IN_BUFFSIZE);
	if (NULL == s)
	{
		DBG("Can not initialzation decompress object!\n");
		return -1;
	}

	b.in = xz_ibuf;
	b.in_pos = 0;
	b.out = xz_obuf;
	b.out_pos = 0;
	b.out_size = sizeof(xz_obuf);
	do {
		if (0 == b.in_pos)
		{
			while(!CAN_READ_FILE(fileno(src), 10));

			b.in_size = fread(xz_ibuf, 1, sizeof(xz_ibuf), src);

			if (!b.in_size)
			{
				return -1;
			}

			if (!show_flag)
			{
				show_flag = ~show_flag;
				disp_share_stat("正在解包.");
			}
		}

		ret = xz_dec_run(s, &b);

		disp_share_process();

		if (b.in_pos == b.in_size)
			b.in_pos = 0;

		if (b.out_pos == b.out_size)
		{
			if (fwrite(xz_obuf, 1, b.out_size, dest) != b.out_size)
			{
				DBG("Write file fail!\n");
				ret = -1;
				goto end;
			}
			b.out_pos = 0;
	
		}

	}while (XZ_OK == ret);

	if (XZ_STREAM_END == ret)
	{
		if (b.out_pos)
		{
			if (fwrite(xz_obuf, 1, b.out_pos, dest) != b.out_pos)
			{
				DBG("Write file fail!\n");
				ret = -1;
				goto end;
			}
		}
		ret = 0;
		disp_share_stat("解包完成!\n");
	}
	else
	{
		DBG("Decompress fail!(ret: %d)\n", ret);
		ret = -1;
	}

end:
	xz_dec_end(s);
	if (ret != 0)
	{
		DBG("Processing fail!\n");
		disp_share_stat("解包失败!\n");
		sleep(2);
	}
	return ret;
}
예제 #13
0
/*
 * This function implements the API defined in <linux/decompress/generic.h>.
 *
 * This wrapper will automatically choose single-call or multi-call mode
 * of the native XZ decoder API. The single-call mode can be used only when
 * both input and output buffers are available as a single chunk, i.e. when
 * fill() and flush() won't be used.
 *
 * This API doesn't provide a way to specify the maximum dictionary size
 * for the multi-call mode of the native XZ decoder API. We will use
 * DICT_MAX bytes, which will be allocated with vmalloc().
 */
STATIC int XZ_FUNC unxz(/*const*/ unsigned char *in, int in_size,
		int (*fill)(void *dest, unsigned int size),
		int (*flush)(/*const*/ void *src, unsigned int size),
		unsigned char *out, int *in_used,
		void (*error)(/*const*/ char *x))
{
	struct xz_buf b;
	struct xz_dec *s;
	enum xz_ret ret;

	xz_crc32_init();

	if (in != NULL && out != NULL)
		s = xz_dec_init(XZ_SINGLE, 0);
	else
		s = xz_dec_init(XZ_PREALLOC /*FIXME*/, DICT_MAX);

	if (s == NULL)
		goto error_alloc_state;

	b.in = in;
	b.in_pos = 0;
	b.in_size = in_size;
	b.out_pos = 0;

	if (in_used != NULL)
		*in_used = 0;

	if (fill == NULL && flush == NULL) {
		b.out = out;
		b.out_size = (size_t)-1;
		ret = xz_dec_run(s, &b);
	} else {
		b.out_size = XZ_IOBUF_SIZE;
		b.out = kmalloc(XZ_IOBUF_SIZE, GFP_KERNEL);
		if (b.out == NULL)
			goto error_alloc_out;

		if (fill != NULL) {
			in = kmalloc(XZ_IOBUF_SIZE, GFP_KERNEL);
			if (in == NULL)
				goto error_alloc_in;

			b.in = in;
		}

		do {
			if (b.in_pos == b.in_size && fill != NULL) {
				if (in_used != NULL)
					*in_used += b.in_pos;

				b.in_pos = 0;

				in_size = fill(in, XZ_IOBUF_SIZE);
				if (in_size < 0) {
					/*
					 * This isn't an optimal error code
					 * but it probably isn't worth making
					 * a new one either.
					 */
					ret = XZ_BUF_ERROR;
					break;
				}

				b.in_size = in_size;
			}

			ret = xz_dec_run(s, &b);

			if (b.out_pos == b.out_size || ret != XZ_OK) {
				/*
				 * Setting ret here may hide an error
				 * returned by xz_dec_run(), but probably
				 * it's not too bad.
				 */
				if (flush(b.out, b.out_pos) != (int)b.out_pos)
					ret = XZ_BUF_ERROR;

				b.out_pos = 0;
			}
		} while (ret == XZ_OK);

		if (fill != NULL)
			kfree(in);

		kfree(b.out);
	}

	if (in_used != NULL)
		*in_used += b.in_pos;

	xz_dec_end(s);

	switch (ret) {
	case XZ_STREAM_END:
		return 0;

	case XZ_MEMLIMIT_ERROR:
		/* This can occur only in multi-call mode. */
		error("Multi-call XZ decompressor limits "
				"the LZMA2 dictionary to 1 MiB");
		break;

	case XZ_FORMAT_ERROR:
		error("Input is not in the XZ format (wrong magic bytes)");
		break;

	case XZ_OPTIONS_ERROR:
		error("Input was encoded with settings that are not "
				"supported by this XZ decoder");
		break;

	case XZ_DATA_ERROR:
		error("XZ-compressed data is corrupt");
		break;

	case XZ_BUF_ERROR:
		error("Output buffer is too small or the "
				"XZ-compressed data is corrupt");
		break;

	default:
		error("Bug in the XZ decompressor");
		break;
	}

	return -1;

error_alloc_in:
	kfree(b.out);

error_alloc_out:
	xz_dec_end(s);

error_alloc_state:
	error("XZ decompressor ran out of memory");
	return -1;
}
예제 #14
0
static int decompressor_xz_consumebhs(struct microfs_sb_info* sbi,
	void* data, struct buffer_head** bhs, __u32 nbhs, __u32* length,
	__u32* bh, __u32* bh_offset, __u32* inflated, int* implerr)
{
	int err = 0;
	
	struct decompressor_xz_data* xzdat = data;
	
	__u32 prev_out_pos = xzdat->xz_buf.out_pos;
	
	pr_spam("decompressor_xz_consumebhs: sbi=0x%p, bhs=0x%p, nbhs=%u\n", sbi, bhs, nbhs);
	pr_spam("decompressor_xz_consumebhs: xzdat=0x%p\n", xzdat);
	pr_spam("decompressor_xz_consumebhs: *length=%u, *bh=%u, *bh_offset=%u, *inflated=%u\n",
		*length, *bh, *bh_offset, *inflated);
	
	do {
		if (xzdat->xz_buf.in_size == xzdat->xz_buf.in_pos) {
			pr_spam("decompressor_xz_consumebhs: *bh=%u, bhs[*bh]=0x%p\n", *bh, bhs[*bh]);
			xzdat->xz_buf.in_pos = 0;
			xzdat->xz_buf.in_size = min_t(__u32, *length, PAGE_SIZE - *bh_offset);
			xzdat->xz_buf.in = bhs[*bh]->b_data + *bh_offset;
			*bh += 1;
			*length -= xzdat->xz_buf.in_size;
			*bh_offset = 0;
		}
		
		pr_spam("decompressor_xz_consumebhs: *length=%u\n", *length);
		
		pr_spam("decompressor_xz_consumebhs: pre;"
			" xzdat->xz_buf.out_size=%zu, xzdat->xz_buf.out=0x%p\n",
			xzdat->xz_buf.out_size, xzdat->xz_buf.out);
		pr_spam("decompressor_xz_consumebhs: pre;"
			" xzdat->xz_buf.in_size=%zu, xzdat->xz_buf.in=0x%p\n",
			xzdat->xz_buf.in_size, xzdat->xz_buf.in);
		pr_spam("decompressor_xz_consumebhs: pre;"
			" prev_out_pos=%u, xzdat->xz_totalout=%u\n",
			prev_out_pos, xzdat->xz_totalout);
		
		*implerr = xz_dec_run(xzdat->xz_state, &xzdat->xz_buf);
		
		xzdat->xz_totalout += xzdat->xz_buf.out_pos - prev_out_pos;
		prev_out_pos = xzdat->xz_buf.out_pos;
		
		pr_spam("decompressor_xz_consumebhs: post;"
			" xzdat->xz_buf.out_size=%zu, xzdat->xz_buf.out=0x%p\n",
			xzdat->xz_buf.out_size, xzdat->xz_buf.out);
		pr_spam("decompressor_xz_consumebhs: post;"
			" xzdat->xz_buf.in_size=%zu, xzdat->xz_buf.in=0x%p\n",
			xzdat->xz_buf.in_size, xzdat->xz_buf.in);
		pr_spam("decompressor_xz_consumebhs: post;"
			"prev_out_pos=%u, xzdat->xz_totalout=%u\n",
			prev_out_pos, xzdat->xz_totalout);
		
		pr_spam("decompressor_xz_consumebhs: *implerr=%d\n", *implerr);
		
		if (xzdat->xz_buf.out_size == xzdat->xz_buf.out_pos) {
			/* The output buffer must be refilled.
			 */
			break;
		}
		
	} while (*implerr == XZ_OK);
	
	if (*implerr == XZ_STREAM_END) {
		*inflated += xzdat->xz_totalout;
		pr_spam("decompressor_xz_consumebhs: at streams end, %u bytes inflated, %u bytes total",
			xzdat->xz_totalout, *inflated);
		xzdat->xz_totalout = 0;
		sbi->si_decompressor->dc_reset(sbi, data);
	} else if (*implerr != XZ_OK) {
		pr_err("decompressor_xz_consumebhs: failed to inflate data, implerr %d\n", *implerr);
		err = -EIO;
	}
	
	return err;
}
예제 #15
0
int xz_decompress(unsigned char *encoded, int encoded_size,
    unsigned char **decoded, int *decoded_size)
{
    static int xz_initialized = 0;
    enum xz_ret ret;
    struct xz_dec *xz;
    struct xz_buf buf;
    unsigned char *dec_buffer;
    unsigned char *temp;
    int dec_size;

    if (!xz_initialized)
    {
        xz_crc32_init();
        xz_initialized = 1;
    }

    *decoded = NULL;
    *decoded_size = 0;

    buf.in = encoded;
    buf.in_pos = 0;
    buf.in_size = encoded_size;

    dec_size = BUFFER_INCREMENT;
    dec_buffer = (unsigned char *)malloc(dec_size);
    if (!dec_buffer)
    {
        return 0;
    }

    buf.out = dec_buffer;
    buf.out_pos = 0;
    buf.out_size = dec_size;

    xz = xz_dec_init(XZ_DYNALLOC, (uint32_t)-1);
    if (!xz)
    {
        free(dec_buffer);
        return 0;
    }

    do
    {
        ret = xz_dec_run(xz, &buf);
        if (ret == XZ_OK)
        {
            /* things are okay, but more buffer space is needed */
            dec_size += BUFFER_INCREMENT;
            temp = realloc(dec_buffer, dec_size);
            if (!temp)
            {
                free(dec_buffer);
                xz_dec_end(xz);
                return 0;
            }
            else
                dec_buffer = temp;
            buf.out_size = dec_size;
            buf.out = dec_buffer;
        }
        else
        {
            /* any other status is an exit condition (either error or stream end) */
            break;
        }
    } while (ret != XZ_STREAM_END);

    if (ret == XZ_STREAM_END)
    {
        /* resize the final buffer */
        dec_size = buf.out_pos;
        temp = realloc(dec_buffer, dec_size);
        if (!temp)
        {
            free(dec_buffer);
            xz_dec_end(xz);
            return 0;
        }
        *decoded = temp;
        *decoded_size = dec_size;
        xz_dec_end(xz);
        return 1;
    }
    else
    {
        xz_dec_end(xz);
        free(dec_buffer);
        return 0;
    }
}