示例#1
0
/* XXX Investigate possibility of in-place decompression to reduce memory
 * footprint. Or try to uncompress directly to buf if possible.  */
static int
uncompress_block (struct grub_lzopio *lzopio)
{
  lzo_uint usize = lzopio->block.usize;

  if (read_block_data (lzopio) < 0)
    return -1;

  /* Incompressible data. */
  if (lzopio->block.csize == lzopio->block.usize)
    {
      lzopio->block.udata = lzopio->block.cdata;
      lzopio->block.cdata = NULL;
    }
  else
    {
      lzopio->block.udata = grub_malloc (lzopio->block.usize);
      if (!lzopio->block.udata)
	return -1;

      if (lzo1x_decompress_safe (lzopio->block.cdata, lzopio->block.csize,
				 lzopio->block.udata, &usize, NULL)
	  != LZO_E_OK)
	return -1;

      if (lzopio->ucheck_fun)
	{
	  grub_uint8_t computed_hash[GRUB_CRYPTO_MAX_MDLEN];

	  if (lzopio->ucheck_fun->mdlen > GRUB_CRYPTO_MAX_MDLEN)
	    return -1;

	  grub_crypto_hash (lzopio->ucheck_fun, computed_hash,
			    lzopio->block.udata,
			    lzopio->block.usize);

	  if (grub_memcmp
	      (computed_hash, &lzopio->block.ucheck,
	       sizeof (lzopio->block.ucheck)) != 0)
	    return -1;
	}

      /* Compressed data can be free now.  */
      grub_free (lzopio->block.cdata);
      lzopio->block.cdata = NULL;
    }

  return 0;
}
示例#2
0
int i2cdump_main(int argc UNUSED_PARAM, char **argv)
{
	const unsigned opt_f = (1 << 0), opt_y = (1 << 1),
			      opt_r = (1 << 2);
	const char *const optstr = "fyr:";

	int bus_num, bus_addr, mode = I2C_SMBUS_BYTE_DATA, even = 0, pec = 0;
	unsigned first = 0x00, last = 0xff, opts;
	int *block = (int *)bb_common_bufsiz1;
	char *opt_r_str, *dash;
	int fd, res;

        opt_complementary = "-2:?3"; /* from 2 to 3 args */
	opts = getopt32(argv, optstr, &opt_r_str);
	argv += optind;

	bus_num = i2c_bus_lookup(argv[0]);
	bus_addr = i2c_parse_bus_addr(argv[1]);

	if (argv[2]) {
		switch (argv[2][0]) {
		case 'b': /* Already set. */			break;
		case 'c': mode = I2C_SMBUS_BYTE;		break;
		case 'w': mode = I2C_SMBUS_WORD_DATA;		break;
		case 'W':
			mode = I2C_SMBUS_WORD_DATA;
			even = 1;
			break;
		case 's': mode = I2C_SMBUS_BLOCK_DATA;		break;
		case 'i': mode = I2C_SMBUS_I2C_BLOCK_DATA;	break;
		default:
			bb_error_msg_and_die("invalid mode");
		}

		if (argv[2][1] == 'p') {
			if (argv[2][0] == 'W' || argv[2][0] == 'i') {
				bb_error_msg_and_die(
					"pec not supported for -W and -i");
			} else {
				pec = 1;
			}
		}
	}

	if (opts & opt_r) {
		first = strtol(opt_r_str, &dash, 0);
		if (dash == opt_r_str || *dash != '-' || first > 0xff)
			bb_error_msg_and_die("invalid range");
		last = xstrtou_range(++dash, 0, first, 0xff);

		/* Range is not available for every mode. */
		switch (mode) {
		case I2C_SMBUS_BYTE:
		case I2C_SMBUS_BYTE_DATA:
			break;
		case I2C_SMBUS_WORD_DATA:
			if (!even || (!(first % 2) && last % 2))
				break;
			/* Fall through */
		default:
			bb_error_msg_and_die(
				"range not compatible with selected mode");
		}
	}

	fd = i2c_dev_open(bus_num);
	check_read_funcs(fd, mode, -1 /* data_addr */, pec);
	i2c_set_slave_addr(fd, bus_addr, opts & opt_f);

	if (pec)
		i2c_set_pec(fd, 1);

	if (!(opts & opt_y))
		confirm_action(bus_addr, mode, -1 /* data_addr */, pec);

	/* All but word data. */
	if (mode != I2C_SMBUS_WORD_DATA || even) {
		int blen = 0;

		if (mode == I2C_SMBUS_BLOCK_DATA || mode == I2C_SMBUS_I2C_BLOCK_DATA)
			blen = read_block_data(fd, mode, block);

		if (mode == I2C_SMBUS_BYTE) {
			res = i2c_smbus_write_byte(fd, first);
			if (res < 0)
				bb_perror_msg_and_die("write start address");
		}

		dump_data(fd, mode, first, last, block, blen);
	} else {
		dump_word_data(fd, first, last);
	}

	return 0;
}