Beispiel #1
0
/*
 * The function obtains size of the nvlist after nvlist_pack().
 */
size_t
nvlist_size(const nvlist_t *nvl)
{
	const nvlist_t *tmpnvl;
	const nvpair_t *nvp, *tmpnvp;
	void *cookie;
	size_t size;

	NVLIST_ASSERT(nvl);
	PJDLOG_ASSERT(nvl->nvl_error == 0);

	size = sizeof(struct nvlist_header);
	nvp = nvlist_first_nvpair(nvl);
	while (nvp != NULL) {
		size += nvpair_header_size();
		size += strlen(nvpair_name(nvp)) + 1;
		if (nvpair_type(nvp) == NV_TYPE_NVLIST) {
			size += sizeof(struct nvlist_header);
			size += nvpair_header_size() + 1;
			tmpnvl = nvpair_get_nvlist(nvp);
			PJDLOG_ASSERT(tmpnvl->nvl_error == 0);
			tmpnvp = nvlist_first_nvpair(tmpnvl);
			if (tmpnvp != NULL) {
				nvl = tmpnvl;
				nvp = tmpnvp;
				continue;
			}
		} else {
			size += nvpair_size(nvp);
		}

		while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
			cookie = NULL;
			nvl = nvlist_get_parent(nvl, &cookie);
			if (nvl == NULL)
				goto out;
			nvp = cookie;
		}
	}

out:
	return (size);
}
Beispiel #2
0
const char *
nvlist_next(const nvlist_t *nvl, int *typep, void **cookiep)
{
	nvpair_t *nvp;

	NVLIST_ASSERT(nvl);
	PJDLOG_ASSERT(cookiep != NULL);

	if (*cookiep == NULL)
		nvp = nvlist_first_nvpair(nvl);
	else
		nvp = nvlist_next_nvpair(nvl, *cookiep);
	if (nvp == NULL)
		return (NULL);
	if (typep != NULL)
		*typep = nvpair_type(nvp);
	*cookiep = nvp;
	return (nvpair_name(nvp));
}
Beispiel #3
0
void
nvlist_destroy(nvlist_t *nvl)
{
	nvpair_t *nvp;

	if (nvl == NULL)
		return;

	ERRNO_SAVE();

	NVLIST_ASSERT(nvl);

	while ((nvp = nvlist_first_nvpair(nvl)) != NULL) {
		nvlist_remove_nvpair(nvl, nvp);
		nvpair_free(nvp);
	}
	nvl->nvl_magic = 0;
	nv_free(nvl);

	ERRNO_RESTORE();
}
Beispiel #4
0
void
nvlist_destroy(nvlist_t *nvl)
{
	nvpair_t *nvp;
	int serrno;

	if (nvl == NULL)
		return;

	serrno = errno;

	NVLIST_ASSERT(nvl);

	while ((nvp = nvlist_first_nvpair(nvl)) != NULL) {
		nvlist_remove_nvpair(nvl, nvp);
		nvpair_free(nvp);
	}
	nvl->nvl_magic = 0;
	free(nvl);

	errno = serrno;
}
Beispiel #5
0
/*
 * The function obtains size of the nvlist after nvlist_pack().
 * Additional argument 'level' allows to track how deep are we as we obtain
 * size of the NV_TYPE_NVLIST elements using recursion. We allow at most
 * three levels of recursion.
 */
static size_t
nvlist_xsize(const nvlist_t *nvl, int level)
{
	const nvpair_t *nvp;
	size_t size;

	NVLIST_ASSERT(nvl);
	PJDLOG_ASSERT(nvl->nvl_error == 0);
	PJDLOG_ASSERT(level < 3);

	size = sizeof(struct nvlist_header);
	for (nvp = nvlist_first_nvpair(nvl); nvp != NULL;
	    nvp = nvlist_next_nvpair(nvl, nvp)) {
		size += nvpair_header_size();
		size += strlen(nvpair_name(nvp)) + 1;
		if (nvpair_type(nvp) == NV_TYPE_NVLIST)
			size += nvlist_xsize(nvpair_get_nvlist(nvp), level + 1);
		else
			size += nvpair_size(nvp);
	}

	return (size);
}
Beispiel #6
0
void *
nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep)
{
	unsigned char *buf, *ptr;
	size_t left, size;
	nvpair_t *nvp;

	NVLIST_ASSERT(nvl);

	if (nvl->nvl_error != 0) {
		errno = nvl->nvl_error;
		return (NULL);
	}

	size = nvlist_size(nvl);
	buf = malloc(size);
	if (buf == NULL)
		return (NULL);

	ptr = buf;
	left = size;

	ptr = nvlist_pack_header(nvl, ptr, &left);

	for (nvp = nvlist_first_nvpair(nvl); nvp != NULL;
	    nvp = nvlist_next_nvpair(nvl, nvp)) {
		ptr = nvpair_pack(nvp, ptr, fdidxp, &left);
		if (ptr == NULL) {
			free(buf);
			return (NULL);
		}
	}

	if (sizep != NULL)
		*sizep = size;
	return (buf);
}
Beispiel #7
0
static void *
nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep)
{
	unsigned char *buf, *ptr;
	size_t left, size;
	const nvlist_t *tmpnvl;
	nvpair_t *nvp, *tmpnvp;
	void *cookie;

	NVLIST_ASSERT(nvl);

	if (nvl->nvl_error != 0) {
		ERRNO_SET(nvl->nvl_error);
		return (NULL);
	}

	size = nvlist_size(nvl);
	buf = nv_malloc(size);
	if (buf == NULL)
		return (NULL);

	ptr = buf;
	left = size;

	ptr = nvlist_pack_header(nvl, ptr, &left);

	nvp = nvlist_first_nvpair(nvl);
	while (nvp != NULL) {
		NVPAIR_ASSERT(nvp);

		nvpair_init_datasize(nvp);
		ptr = nvpair_pack_header(nvp, ptr, &left);
		if (ptr == NULL) {
			nv_free(buf);
			return (NULL);
		}
		switch (nvpair_type(nvp)) {
		case NV_TYPE_NULL:
			ptr = nvpair_pack_null(nvp, ptr, &left);
			break;
		case NV_TYPE_BOOL:
			ptr = nvpair_pack_bool(nvp, ptr, &left);
			break;
		case NV_TYPE_NUMBER:
			ptr = nvpair_pack_number(nvp, ptr, &left);
			break;
		case NV_TYPE_STRING:
			ptr = nvpair_pack_string(nvp, ptr, &left);
			break;
		case NV_TYPE_NVLIST:
			tmpnvl = nvpair_get_nvlist(nvp);
			ptr = nvlist_pack_header(tmpnvl, ptr, &left);
			if (ptr == NULL)
				goto out;
			tmpnvp = nvlist_first_nvpair(tmpnvl);
			if (tmpnvp != NULL) {
				nvl = tmpnvl;
				nvp = tmpnvp;
				continue;
			}
			ptr = nvpair_pack_nvlist_up(ptr, &left);
			break;
#ifndef _KERNEL
		case NV_TYPE_DESCRIPTOR:
			ptr = nvpair_pack_descriptor(nvp, ptr, fdidxp, &left);
			break;
#endif
		case NV_TYPE_BINARY:
			ptr = nvpair_pack_binary(nvp, ptr, &left);
			break;
		default:
			PJDLOG_ABORT("Invalid type (%d).", nvpair_type(nvp));
		}
		if (ptr == NULL) {
			nv_free(buf);
			return (NULL);
		}
		while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
			cookie = NULL;
			nvl = nvlist_get_parent(nvl, &cookie);
			if (nvl == NULL)
				goto out;
			nvp = cookie;
			ptr = nvpair_pack_nvlist_up(ptr, &left);
			if (ptr == NULL)
				goto out;
		}
	}

out:
	if (sizep != NULL)
		*sizep = size;
	return (buf);
}
Beispiel #8
0
/*
 * Dump content of nvlist.
 */
void
nvlist_dump(const nvlist_t *nvl, int fd)
{
	const nvlist_t *tmpnvl;
	nvpair_t *nvp, *tmpnvp;
	void *cookie;
	int level;

	level = 0;
	if (nvlist_dump_error_check(nvl, fd, level))
		return;

	nvp = nvlist_first_nvpair(nvl);
	while (nvp != NULL) {
		dprintf(fd, "%*s%s (%s):", level * 4, "", nvpair_name(nvp),
		    nvpair_type_string(nvpair_type(nvp)));
		switch (nvpair_type(nvp)) {
		case NV_TYPE_NULL:
			dprintf(fd, " null\n");
			break;
		case NV_TYPE_BOOL:
			dprintf(fd, " %s\n", nvpair_get_bool(nvp) ?
			    "TRUE" : "FALSE");
			break;
		case NV_TYPE_NUMBER:
			dprintf(fd, " %ju (%jd) (0x%jx)\n",
			    (uintmax_t)nvpair_get_number(nvp),
			    (intmax_t)nvpair_get_number(nvp),
			    (uintmax_t)nvpair_get_number(nvp));
			break;
		case NV_TYPE_STRING:
			dprintf(fd, " [%s]\n", nvpair_get_string(nvp));
			break;
		case NV_TYPE_NVLIST:
			dprintf(fd, "\n");
			tmpnvl = nvpair_get_nvlist(nvp);
			if (nvlist_dump_error_check(tmpnvl, fd, level + 1))
				break;
			tmpnvp = nvlist_first_nvpair(tmpnvl);
			if (tmpnvp != NULL) {
				nvl = tmpnvl;
				nvp = tmpnvp;
				level++;
				continue;
			}
			break;
		case NV_TYPE_DESCRIPTOR:
			dprintf(fd, " %d\n", nvpair_get_descriptor(nvp));
			break;
		case NV_TYPE_BINARY:
		    {
			const unsigned char *binary;
			unsigned int ii;
			size_t size;

			binary = nvpair_get_binary(nvp, &size);
			dprintf(fd, " %zu ", size);
			for (ii = 0; ii < size; ii++)
				dprintf(fd, "%02hhx", binary[ii]);
			dprintf(fd, "\n");
			break;
		    }
		default:
			PJDLOG_ABORT("Unknown type: %d.", nvpair_type(nvp));
		}

		while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
			cookie = NULL;
			nvl = nvlist_get_parent(nvl, &cookie);
			if (nvl == NULL)
				return;
			nvp = cookie;
			level--;
		}
	}
}
Beispiel #9
0
static void *
nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep)
{
	unsigned char *buf, *ptr;
	size_t left, size;
	const nvlist_t *tmpnvl;
	nvpair_t *nvp, *tmpnvp;
	void *cookie;

	NVLIST_ASSERT(nvl);

	if (nvl->nvl_error != 0) {
		ERRNO_SET(nvl->nvl_error);
		return (NULL);
	}

	size = nvlist_size(nvl);
	buf = nv_malloc(size);
	if (buf == NULL)
		return (NULL);

	ptr = buf;
	left = size;

	ptr = nvlist_pack_header(nvl, ptr, &left);

	nvp = nvlist_first_nvpair(nvl);
	while (nvp != NULL) {
		NVPAIR_ASSERT(nvp);

		nvpair_init_datasize(nvp);
		ptr = nvpair_pack_header(nvp, ptr, &left);
		if (ptr == NULL)
			goto fail;
		switch (nvpair_type(nvp)) {
		case NV_TYPE_NULL:
			ptr = nvpair_pack_null(nvp, ptr, &left);
			break;
		case NV_TYPE_BOOL:
			ptr = nvpair_pack_bool(nvp, ptr, &left);
			break;
		case NV_TYPE_NUMBER:
			ptr = nvpair_pack_number(nvp, ptr, &left);
			break;
		case NV_TYPE_STRING:
			ptr = nvpair_pack_string(nvp, ptr, &left);
			break;
		case NV_TYPE_NVLIST:
			tmpnvl = nvpair_get_nvlist(nvp);
			ptr = nvlist_pack_header(tmpnvl, ptr, &left);
			if (ptr == NULL)
				goto fail;
			tmpnvp = nvlist_first_nvpair(tmpnvl);
			if (tmpnvp != NULL) {
				nvl = tmpnvl;
				nvp = tmpnvp;
				continue;
			}
			ptr = nvpair_pack_nvlist_up(ptr, &left);
			break;
#ifndef _KERNEL
		case NV_TYPE_DESCRIPTOR:
			ptr = nvpair_pack_descriptor(nvp, ptr, fdidxp, &left);
			break;
		case NV_TYPE_DESCRIPTOR_ARRAY:
			ptr = nvpair_pack_descriptor_array(nvp, ptr, fdidxp,
			    &left);
			break;
#endif
		case NV_TYPE_BINARY:
			ptr = nvpair_pack_binary(nvp, ptr, &left);
			break;
		case NV_TYPE_BOOL_ARRAY:
			ptr = nvpair_pack_bool_array(nvp, ptr, &left);
			break;
		case NV_TYPE_NUMBER_ARRAY:
			ptr = nvpair_pack_number_array(nvp, ptr, &left);
			break;
		case NV_TYPE_STRING_ARRAY:
			ptr = nvpair_pack_string_array(nvp, ptr, &left);
			break;
		case NV_TYPE_NVLIST_ARRAY:
		    {
			const nvlist_t * const * value;
			size_t nitems;
			unsigned int ii;

			tmpnvl = NULL;
			value = nvpair_get_nvlist_array(nvp, &nitems);
			for (ii = 0; ii < nitems; ii++) {
				ptr = nvlist_pack_header(value[ii], ptr, &left);
				if (ptr == NULL)
					goto out;
				tmpnvp = nvlist_first_nvpair(value[ii]);
				if (tmpnvp != NULL) {
					tmpnvl = value[ii];
					break;
				}
				ptr = nvpair_pack_nvlist_array_next(ptr, &left);
				if (ptr == NULL)
					goto out;
			}
			if (tmpnvl != NULL) {
				nvl = tmpnvl;
				nvp = tmpnvp;
				continue;
			}
			break;
		    }
		default:
			PJDLOG_ABORT("Invalid type (%d).", nvpair_type(nvp));
		}
		if (ptr == NULL)
			goto fail;
		while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
			do {
				cookie = NULL;
				if (nvlist_in_array(nvl)) {
					ptr = nvpair_pack_nvlist_array_next(ptr,
					    &left);
					if (ptr == NULL)
						goto fail;
				}
				nvl = nvlist_get_pararr(nvl, &cookie);
				if (nvl == NULL)
					goto out;
				if (nvlist_in_array(nvl) && cookie == NULL) {
					nvp = nvlist_first_nvpair(nvl);
					ptr = nvlist_pack_header(nvl, ptr,
					    &left);
					if (ptr == NULL)
						goto fail;
				} else if (nvpair_type((nvpair_t *)cookie) !=
				    NV_TYPE_NVLIST_ARRAY) {
					ptr = nvpair_pack_nvlist_up(ptr, &left);
					if (ptr == NULL)
						goto fail;
					nvp = cookie;
				} else {
					nvp = cookie;
				}
			} while (nvp == NULL);
			if (nvlist_in_array(nvl) && cookie == NULL)
				break;
		}
	}

out:
	if (sizep != NULL)
		*sizep = size;
	return (buf);
fail:
	nv_free(buf);
	return (NULL);
}
Beispiel #10
0
/*
 * The function obtains size of the nvlist after nvlist_pack().
 */
size_t
nvlist_size(const nvlist_t *nvl)
{
	const nvlist_t *tmpnvl;
	const nvlist_t * const *nvlarray;
	const nvpair_t *nvp, *tmpnvp;
	void *cookie;
	size_t size, nitems;
	unsigned int ii;

	NVLIST_ASSERT(nvl);
	PJDLOG_ASSERT(nvl->nvl_error == 0);

	size = sizeof(struct nvlist_header);
	nvp = nvlist_first_nvpair(nvl);
	while (nvp != NULL) {
		size += nvpair_header_size();
		size += strlen(nvpair_name(nvp)) + 1;
		if (nvpair_type(nvp) == NV_TYPE_NVLIST) {
			size += sizeof(struct nvlist_header);
			size += nvpair_header_size() + 1;
			tmpnvl = nvpair_get_nvlist(nvp);
			PJDLOG_ASSERT(tmpnvl->nvl_error == 0);
			tmpnvp = nvlist_first_nvpair(tmpnvl);
			if (tmpnvp != NULL) {
				nvl = tmpnvl;
				nvp = tmpnvp;
				continue;
			}
		} else if (nvpair_type(nvp) == NV_TYPE_NVLIST_ARRAY) {
			nvlarray = nvpair_get_nvlist_array(nvp, &nitems);
			PJDLOG_ASSERT(nitems > 0);

			size += (nvpair_header_size() + 1) * nitems;
			size += sizeof(struct nvlist_header) * nitems;

			tmpnvl = NULL;
			tmpnvp = NULL;
			for (ii = 0; ii < nitems; ii++) {
				PJDLOG_ASSERT(nvlarray[ii]->nvl_error == 0);
				tmpnvp = nvlist_first_nvpair(nvlarray[ii]);
				if (tmpnvp != NULL) {
					tmpnvl = nvlarray[ii];
					break;
				}
			}
			if (tmpnvp != NULL) {
				nvp = tmpnvp;
				nvl = tmpnvl;
				continue;
			}

		} else {
			size += nvpair_size(nvp);
		}

		while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
			do {
				cookie = NULL;
				nvl = nvlist_get_pararr(nvl, &cookie);
				if (nvl == NULL)
					goto out;
				if (nvlist_in_array(nvl) && cookie == NULL) {
					nvp = nvlist_first_nvpair(nvl);
				} else {
					nvp = cookie;
				}
			} while (nvp == NULL);
			if (nvlist_in_array(nvl) && cookie == NULL)
				break;
		}
	}

out:
	return (size);
}
Beispiel #11
0
/*
 * Dump content of nvlist.
 */
void
nvlist_dump(const nvlist_t *nvl, int fd)
{
	const nvlist_t *tmpnvl;
	nvpair_t *nvp, *tmpnvp;
	void *cookie;
	int level;

	level = 0;
	if (nvlist_dump_error_check(nvl, fd, level))
		return;

	nvp = nvlist_first_nvpair(nvl);
	while (nvp != NULL) {
		dprintf(fd, "%*s%s (%s):", level * 4, "", nvpair_name(nvp),
		    nvpair_type_string(nvpair_type(nvp)));
		switch (nvpair_type(nvp)) {
		case NV_TYPE_NULL:
			dprintf(fd, " null\n");
			break;
		case NV_TYPE_BOOL:
			dprintf(fd, " %s\n", nvpair_get_bool(nvp) ?
			    "TRUE" : "FALSE");
			break;
		case NV_TYPE_NUMBER:
			dprintf(fd, " %ju (%jd) (0x%jx)\n",
			    (uintmax_t)nvpair_get_number(nvp),
			    (intmax_t)nvpair_get_number(nvp),
			    (uintmax_t)nvpair_get_number(nvp));
			break;
		case NV_TYPE_STRING:
			dprintf(fd, " [%s]\n", nvpair_get_string(nvp));
			break;
		case NV_TYPE_NVLIST:
			dprintf(fd, "\n");
			tmpnvl = nvpair_get_nvlist(nvp);
			if (nvlist_dump_error_check(tmpnvl, fd, level + 1))
				break;
			tmpnvp = nvlist_first_nvpair(tmpnvl);
			if (tmpnvp != NULL) {
				nvl = tmpnvl;
				nvp = tmpnvp;
				level++;
				continue;
			}
			break;
		case NV_TYPE_DESCRIPTOR:
			dprintf(fd, " %d\n", nvpair_get_descriptor(nvp));
			break;
		case NV_TYPE_BINARY:
		    {
			const unsigned char *binary;
			unsigned int ii;
			size_t size;

			binary = nvpair_get_binary(nvp, &size);
			dprintf(fd, " %zu ", size);
			for (ii = 0; ii < size; ii++)
				dprintf(fd, "%02hhx", binary[ii]);
			dprintf(fd, "\n");
			break;
		    }
		case NV_TYPE_BOOL_ARRAY:
		    {
			const bool *value;
			unsigned int ii;
			size_t nitems;

			value = nvpair_get_bool_array(nvp, &nitems);
			dprintf(fd, " [ ");
			for (ii = 0; ii < nitems; ii++) {
				dprintf(fd, "%s", value[ii] ? "TRUE" : "FALSE");
				if (ii != nitems - 1)
					dprintf(fd, ", ");
			}
			dprintf(fd, " ]\n");
			break;
		    }
		case NV_TYPE_STRING_ARRAY:
		    {
			const char * const *value;
			unsigned int ii;
			size_t nitems;

			value = nvpair_get_string_array(nvp, &nitems);
			dprintf(fd, " [ ");
			for (ii = 0; ii < nitems; ii++) {
				if (value[ii] == NULL)
					dprintf(fd, "NULL");
				else
					dprintf(fd, "\"%s\"", value[ii]);
				if (ii != nitems - 1)
					dprintf(fd, ", ");
			}
			dprintf(fd, " ]\n");
			break;
		    }
		case NV_TYPE_NUMBER_ARRAY:
		    {
			const uint64_t *value;
			unsigned int ii;
			size_t nitems;

			value = nvpair_get_number_array(nvp, &nitems);
			dprintf(fd, " [ ");
			for (ii = 0; ii < nitems; ii++) {
				dprintf(fd, "%ju (%jd) (0x%jx)",
				    value[ii], value[ii], value[ii]);
				if (ii != nitems - 1)
					dprintf(fd, ", ");
			}
			dprintf(fd, " ]\n");
			break;
		    }
		case NV_TYPE_DESCRIPTOR_ARRAY:
		    {
			const int *value;
			unsigned int ii;
			size_t nitems;

			value = nvpair_get_descriptor_array(nvp, &nitems);
			dprintf(fd, " [ ");
			for (ii = 0; ii < nitems; ii++) {
				dprintf(fd, "%d", value[ii]);
				if (ii != nitems - 1)
					dprintf(fd, ", ");
			}
			dprintf(fd, " ]\n");
			break;
		    }
		case NV_TYPE_NVLIST_ARRAY:
		    {
			const nvlist_t * const *value;
			unsigned int ii;
			size_t nitems;

			value = nvpair_get_nvlist_array(nvp, &nitems);
			dprintf(fd, " %zu\n", nitems);
			tmpnvl = NULL;
			tmpnvp = NULL;
			for (ii = 0; ii < nitems; ii++) {
				if (nvlist_dump_error_check(value[ii], fd,
				    level + 1)) {
					break;
				}

				if (tmpnvl == NULL) {
					tmpnvp = nvlist_first_nvpair(value[ii]);
					if (tmpnvp != NULL) {
						tmpnvl = value[ii];
					} else {
						dprintf(fd, "%*s,\n",
						    (level + 1) * 4, "");
					}
				}
			}
			if (tmpnvp != NULL) {
				nvl = tmpnvl;
				nvp = tmpnvp;
				level++;
				continue;
			}
			break;
		    }
		default:
			PJDLOG_ABORT("Unknown type: %d.", nvpair_type(nvp));
		}

		while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
			do {
				cookie = NULL;
				if (nvlist_in_array(nvl))
					dprintf(fd, "%*s,\n", level * 4, "");
				nvl = nvlist_get_pararr(nvl, &cookie);
				if (nvl == NULL)
					return;
				if (nvlist_in_array(nvl) && cookie == NULL) {
					nvp = nvlist_first_nvpair(nvl);
				} else {
					nvp = cookie;
					level--;
				}
			} while (nvp == NULL);
			if (nvlist_in_array(nvl) && cookie == NULL)
				break;
		}
	}
}