struct sparse_file *sparse_file_import(int fd, bool verbose, bool crc)
{
	int ret;
	sparse_header_t sparse_header;
	int64_t len;
	struct sparse_file *s;

	ret = read_all(fd, &sparse_header, sizeof(sparse_header));
	if (ret < 0) {
		verbose_error(verbose, ret, "header");
		return NULL;
	}

	if (sparse_header.magic != SPARSE_HEADER_MAGIC) {
		verbose_error(verbose, -EINVAL, "header magic");
		return NULL;
	}

	if (sparse_header.major_version != SPARSE_HEADER_MAJOR_VER) {
		verbose_error(verbose, -EINVAL, "header major version");
		return NULL;
	}

	if (sparse_header.file_hdr_sz < SPARSE_HEADER_LEN) {
		return NULL;
	}

	if (sparse_header.chunk_hdr_sz < sizeof(chunk_header_t)) {
		return NULL;
	}

	len = (int64_t)sparse_header.total_blks * sparse_header.blk_sz;
	s = sparse_file_new(sparse_header.blk_sz, len);
	if (!s) {
		verbose_error(verbose, -EINVAL, NULL);
		return NULL;
	}

	ret = lseek64(fd, 0, SEEK_SET);
	if (ret < 0) {
		verbose_error(verbose, ret, "seeking");
		sparse_file_destroy(s);
		return NULL;
	}

	s->verbose = verbose;

	ret = sparse_file_read(s, fd, true, crc);
	if (ret < 0) {
		sparse_file_destroy(s);
		return NULL;
	}

	return s;
}
Example #2
0
int img2simg_main(int argc, char *argv[])
{
  int in;
  int out;
  int ret;
  struct sparse_file *s;
  unsigned int block_size = 4096;
  off64_t len;

  if (argc < 3 || argc > 4) {
    img2simg_usage();
    return(-1);
  }

  if (argc == 4) {
    block_size = atoi(argv[3]);
  }

  if (block_size < 1024 || block_size % 4 != 0) {
    img2simg_usage();
    return(-1);
  }

  if (strcmp(argv[1], "-") == 0) {
    in = STDIN_FILENO;
  } else {
    in = open(argv[1], O_RDONLY | O_BINARY);
    if (in < 0) {
      fprintf(stderr, "Cannot open input file %s\n", argv[1]);
      return(-1);
    }
  }

  if (strcmp(argv[2], "-") == 0) {
    out = STDOUT_FILENO;
  } else {
    out = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0664);
    if (out < 0) {
      fprintf(stderr, "Cannot open output file %s\n", argv[2]);
      return(-1);
    }
  }

  len = lseek64(in, 0, SEEK_END);
  lseek64(in, 0, SEEK_SET);

  s = sparse_file_new(block_size, len);
  if (!s) {
    fprintf(stderr, "Failed to create sparse file\n");
    return(-1);
  }

  sparse_file_verbose(s);
  ret = sparse_file_read(s, in, false, false);
  if (ret) {
    fprintf(stderr, "Failed to read file\n");
    return(-1);
  }

  ret = sparse_file_write(s, out, false, true, false);
  if (ret) {
    fprintf(stderr, "Failed to write sparse file\n");
    return(-1);
  }

  close(in);
  close(out);

  return(0);
}