Exemple #1
0
static bool
nvlist_check_header(struct nvlist_header *nvlhdrp)
{

	if (nvlhdrp->nvlh_magic != NVLIST_HEADER_MAGIC) {
		ERRNO_SET(EINVAL);
		return (false);
	}
	if ((nvlhdrp->nvlh_flags & ~NV_FLAG_ALL_MASK) != 0) {
		ERRNO_SET(EINVAL);
		return (false);
	}
#if BYTE_ORDER == BIG_ENDIAN
	if ((nvlhdrp->nvlh_flags & NV_FLAG_BIG_ENDIAN) == 0) {
		nvlhdrp->nvlh_size = le64toh(nvlhdrp->nvlh_size);
		nvlhdrp->nvlh_descriptors = le64toh(nvlhdrp->nvlh_descriptors);
	}
#else
	if ((nvlhdrp->nvlh_flags & NV_FLAG_BIG_ENDIAN) != 0) {
		nvlhdrp->nvlh_size = be64toh(nvlhdrp->nvlh_size);
		nvlhdrp->nvlh_descriptors = be64toh(nvlhdrp->nvlh_descriptors);
	}
#endif
	return (true);
}
Exemple #2
0
void
nvlist_move_nvlist_array(nvlist_t *nvl, const char *name, nvlist_t **value,
    size_t nitems)
{
	nvpair_t *nvp;
	size_t i;

	if (nvlist_error(nvl) != 0) {
		if (value != NULL) {
			for (i = 0; i < nitems; i++) {
				if (nvlist_get_pararr(value[i], NULL) == NULL)
					nvlist_destroy(value[i]);
			}
		}
		nv_free(value);
		ERRNO_SET(nvlist_error(nvl));
		return;
	}

	nvp = nvpair_move_nvlist_array(name, value, nitems);
	if (nvp == NULL) {
		nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
		ERRNO_SET(nvl->nvl_error);
	} else {
		(void)nvlist_move_nvpair(nvl, nvp);
	}
}
Exemple #3
0
void
nvlist_add_nvpair(nvlist_t *nvl, const nvpair_t *nvp)
{
	nvpair_t *newnvp;

	NVPAIR_ASSERT(nvp);

	if (nvlist_error(nvl) != 0) {
		ERRNO_SET(nvlist_error(nvl));
		return;
	}
	if ((nvl->nvl_flags & NV_FLAG_NO_UNIQUE) == 0) {
		if (nvlist_exists(nvl, nvpair_name(nvp))) {
			nvl->nvl_error = EEXIST;
			ERRNO_SET(nvlist_error(nvl));
			return;
		}
	}

	newnvp = nvpair_clone(nvp);
	if (newnvp == NULL) {
		nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
		ERRNO_SET(nvlist_error(nvl));
		return;
	}

	nvpair_insert(&nvl->nvl_head, newnvp, nvl);
}
Exemple #4
0
void
nvlist_move_descriptor_array(nvlist_t *nvl, const char *name, int *value,
    size_t nitems)
{
	nvpair_t *nvp;
	size_t i;

	if (nvlist_error(nvl) != 0) {
		if (value != 0) {
			for (i = 0; i < nitems; i++)
				close(value[i]);
			nv_free(value);
		}

		ERRNO_SET(nvlist_error(nvl));
		return;
	}

	nvp = nvpair_move_descriptor_array(name, value, nitems);
	if (nvp == NULL) {
		nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
		ERRNO_SET(nvl->nvl_error);
	} else {
		(void)nvlist_move_nvpair(nvl, nvp);
	}
}
Exemple #5
0
nvlist_t *
nvlist_clone(const nvlist_t *nvl)
{
	nvlist_t *newnvl;
	nvpair_t *nvp, *newnvp;

	NVLIST_ASSERT(nvl);

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

	newnvl = nvlist_create(nvl->nvl_flags & NV_FLAG_PUBLIC_MASK);
	for (nvp = nvlist_first_nvpair(nvl); nvp != NULL;
	    nvp = nvlist_next_nvpair(nvl, nvp)) {
		newnvp = nvpair_clone(nvp);
		if (newnvp == NULL)
			break;
		nvlist_move_nvpair(newnvl, newnvp);
	}
	if (nvp != NULL) {
		nvlist_destroy(newnvl);
		return (NULL);
	}
	return (newnvl);
}
Exemple #6
0
static nvpair_t *
nvlist_find(const nvlist_t *nvl, int type, const char *name)
{
	nvpair_t *nvp;

	NVLIST_ASSERT(nvl);
	PJDLOG_ASSERT(nvl->nvl_error == 0);
	PJDLOG_ASSERT(type == NV_TYPE_NONE ||
	    (type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST));

	for (nvp = nvlist_first_nvpair(nvl); nvp != NULL;
	    nvp = nvlist_next_nvpair(nvl, nvp)) {
		if (type != NV_TYPE_NONE && nvpair_type(nvp) != type)
			continue;
		if ((nvl->nvl_flags & NV_FLAG_IGNORE_CASE) != 0) {
			if (strcasecmp(nvpair_name(nvp), name) != 0)
				continue;
		} else {
			if (strcmp(nvpair_name(nvp), name) != 0)
				continue;
		}
		break;
	}

	if (nvp == NULL)
		ERRNO_SET(ENOENT);

	return (nvp);
}
Exemple #7
0
static nvpair_t *
nvpair_allocv(const char *name, int type, uint64_t data, size_t datasize,
    size_t nitems)
{
	nvpair_t *nvp;
	size_t namelen;

	PJDLOG_ASSERT(type >= NV_TYPE_FIRST && type <= NV_TYPE_LAST);

	namelen = strlen(name);
	if (namelen >= NV_NAME_MAX) {
		ERRNO_SET(ENAMETOOLONG);
		return (NULL);
	}

	nvp = nv_calloc(1, sizeof(*nvp) + namelen + 1);
	if (nvp != NULL) {
		nvp->nvp_name = (char *)(nvp + 1);
		memcpy(nvp->nvp_name, name, namelen);
		nvp->nvp_name[namelen] = '\0';
		nvp->nvp_type = type;
		nvp->nvp_data = data;
		nvp->nvp_datasize = datasize;
		nvp->nvp_nitems = nitems;
		nvp->nvp_magic = NVPAIR_MAGIC;
	}

	return (nvp);
}
Exemple #8
0
void
nvlist_add_null(nvlist_t *nvl, const char *name)
{
	nvpair_t *nvp;

	if (nvlist_error(nvl) != 0) {
		ERRNO_SET(nvlist_error(nvl));
		return;
	}

	nvp = nvpair_create_null(name);
	if (nvp == NULL) {
		nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
		ERRNO_SET(nvl->nvl_error);
	} else {
		nvlist_move_nvpair(nvl, nvp);
	}
}
Exemple #9
0
void *
nvlist_pack(const nvlist_t *nvl, size_t *sizep)
{

	NVLIST_ASSERT(nvl);

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

	if (nvlist_ndescriptors(nvl) > 0) {
		ERRNO_SET(EOPNOTSUPP);
		return (NULL);
	}

	return (nvlist_xpack(nvl, NULL, sizep));
}
Exemple #10
0
void
nvlist_move_binary(nvlist_t *nvl, const char *name, void *value, size_t size)
{
	nvpair_t *nvp;

	if (nvlist_error(nvl) != 0) {
		nv_free(value);
		ERRNO_SET(nvlist_error(nvl));
		return;
	}

	nvp = nvpair_move_binary(name, value, size);
	if (nvp == NULL) {
		nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
		ERRNO_SET(nvl->nvl_error);
	} else {
		nvlist_move_nvpair(nvl, nvp);
	}
}
Exemple #11
0
void
nvlist_move_descriptor(nvlist_t *nvl, const char *name, int value)
{
	nvpair_t *nvp;

	if (nvlist_error(nvl) != 0) {
		close(value);
		ERRNO_SET(nvlist_error(nvl));
		return;
	}

	nvp = nvpair_move_descriptor(name, value);
	if (nvp == NULL) {
		nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
		ERRNO_SET(nvl->nvl_error);
	} else {
		nvlist_move_nvpair(nvl, nvp);
	}
}
Exemple #12
0
void
nvlist_add_stringv(nvlist_t *nvl, const char *name, const char *valuefmt,
    va_list valueap)
{
	nvpair_t *nvp;

	if (nvlist_error(nvl) != 0) {
		ERRNO_SET(nvlist_error(nvl));
		return;
	}

	nvp = nvpair_create_stringv(name, valuefmt, valueap);
	if (nvp == NULL) {
		nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
		ERRNO_SET(nvl->nvl_error);
	} else {
		nvlist_move_nvpair(nvl, nvp);
	}
}
Exemple #13
0
void
nvlist_move_number_array(nvlist_t *nvl, const char *name, uint64_t *value,
    size_t nitems)
{
	nvpair_t *nvp;

	if (nvlist_error(nvl) != 0) {
		nv_free(value);
		ERRNO_SET(nvlist_error(nvl));
		return;
	}

	nvp = nvpair_move_number_array(name, value, nitems);
	if (nvp == NULL) {
		nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
		ERRNO_SET(nvl->nvl_error);
	} else {
		(void)nvlist_move_nvpair(nvl, nvp);
	}
}
Exemple #14
0
void
nvlist_move_nvlist(nvlist_t *nvl, const char *name, nvlist_t *value)
{
	nvpair_t *nvp;

	if (nvlist_error(nvl) != 0) {
		if (value != NULL && nvlist_get_nvpair_parent(value) != NULL)
			nvlist_destroy(value);
		ERRNO_SET(nvlist_error(nvl));
		return;
	}

	nvp = nvpair_move_nvlist(name, value);
	if (nvp == NULL) {
		nvl->nvl_error = ERRNO_OR_DEFAULT(ENOMEM);
		ERRNO_SET(nvl->nvl_error);
	} else {
		nvlist_move_nvpair(nvl, nvp);
	}
}
Exemple #15
0
void
nvlist_move_nvpair(nvlist_t *nvl, nvpair_t *nvp)
{

	NVPAIR_ASSERT(nvp);
	PJDLOG_ASSERT(nvpair_nvlist(nvp) == NULL);

	if (nvlist_error(nvl) != 0) {
		nvpair_free(nvp);
		ERRNO_SET(nvlist_error(nvl));
		return;
	}
	if ((nvl->nvl_flags & NV_FLAG_NO_UNIQUE) == 0) {
		if (nvlist_exists(nvl, nvpair_name(nvp))) {
			nvpair_free(nvp);
			nvl->nvl_error = EEXIST;
			ERRNO_SET(nvl->nvl_error);
			return;
		}
	}

	nvpair_insert(&nvl->nvl_head, nvp, nvl);
}
Exemple #16
0
int
nvlist_send(int sock, const nvlist_t *nvl)
{
	size_t datasize, nfds;
	int *fds;
	void *data;
	int64_t fdidx;
	int ret;

	if (nvlist_error(nvl) != 0) {
		ERRNO_SET(nvlist_error(nvl));
		return (-1);
	}

	fds = nvlist_descriptors(nvl, &nfds);
	if (fds == NULL)
		return (-1);

	ret = -1;
	data = NULL;
	fdidx = 0;

	data = nvlist_xpack(nvl, &fdidx, &datasize);
	if (data == NULL)
		goto out;

	if (buf_send(sock, data, datasize) == -1)
		goto out;

	if (nfds > 0) {
		if (fd_send(sock, fds, nfds) == -1)
			goto out;
	}

	ret = 0;
out:
	ERRNO_SAVE();
	nv_free(fds);
	nv_free(data);
	ERRNO_RESTORE();
	return (ret);
}
Exemple #17
0
const unsigned char *
nvlist_unpack_header(nvlist_t *nvl, const unsigned char *ptr, size_t nfds,
    bool *isbep, size_t *leftp)
{
	struct nvlist_header nvlhdr;
	int inarrayf;

	if (*leftp < sizeof(nvlhdr))
		goto fail;

	memcpy(&nvlhdr, ptr, sizeof(nvlhdr));

	if (!nvlist_check_header(&nvlhdr))
		goto fail;

	if (nvlhdr.nvlh_size != *leftp - sizeof(nvlhdr))
		goto fail;

	/*
	 * nvlh_descriptors might be smaller than nfds in embedded nvlists.
	 */
	if (nvlhdr.nvlh_descriptors > nfds)
		goto fail;

	if ((nvlhdr.nvlh_flags & ~NV_FLAG_ALL_MASK) != 0)
		goto fail;

	inarrayf = (nvl->nvl_flags & NV_FLAG_IN_ARRAY);
	nvl->nvl_flags = (nvlhdr.nvlh_flags & NV_FLAG_PUBLIC_MASK) | inarrayf;

	ptr += sizeof(nvlhdr);
	if (isbep != NULL)
		*isbep = (((int)nvlhdr.nvlh_flags & NV_FLAG_BIG_ENDIAN) != 0);
	*leftp -= sizeof(nvlhdr);

	return (ptr);
fail:
	ERRNO_SET(EINVAL);
	return (NULL);
}
Exemple #18
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);
}
Exemple #19
0
static nvlist_t *
nvlist_xunpack(const void *buf, size_t size, const int *fds, size_t nfds,
    int flags)
{
	const unsigned char *ptr;
	nvlist_t *nvl, *retnvl, *tmpnvl;
	nvpair_t *nvp;
	size_t left;
	bool isbe;

	PJDLOG_ASSERT((flags & ~(NV_FLAG_PUBLIC_MASK)) == 0);

	left = size;
	ptr = buf;

	tmpnvl = NULL;
	nvl = retnvl = nvlist_create(0);
	if (nvl == NULL)
		goto failed;

	ptr = nvlist_unpack_header(nvl, ptr, nfds, &isbe, &left);
	if (ptr == NULL)
		goto failed;
	if (nvl->nvl_flags != flags) {
		ERRNO_SET(EILSEQ);
		goto failed;
	}

	while (left > 0) {
		ptr = nvpair_unpack(isbe, ptr, &left, &nvp);
		if (ptr == NULL)
			goto failed;
		switch (nvpair_type(nvp)) {
		case NV_TYPE_NULL:
			ptr = nvpair_unpack_null(isbe, nvp, ptr, &left);
			break;
		case NV_TYPE_BOOL:
			ptr = nvpair_unpack_bool(isbe, nvp, ptr, &left);
			break;
		case NV_TYPE_NUMBER:
			ptr = nvpair_unpack_number(isbe, nvp, ptr, &left);
			break;
		case NV_TYPE_STRING:
			ptr = nvpair_unpack_string(isbe, nvp, ptr, &left);
			break;
		case NV_TYPE_NVLIST:
			ptr = nvpair_unpack_nvlist(isbe, nvp, ptr, &left, nfds,
			    &tmpnvl);
			nvlist_set_parent(tmpnvl, nvp);
			break;
#ifndef _KERNEL
		case NV_TYPE_DESCRIPTOR:
			ptr = nvpair_unpack_descriptor(isbe, nvp, ptr, &left,
			    fds, nfds);
			break;
#endif
		case NV_TYPE_BINARY:
			ptr = nvpair_unpack_binary(isbe, nvp, ptr, &left);
			break;
		case NV_TYPE_NVLIST_UP:
			if (nvl->nvl_parent == NULL)
				goto failed;
			nvl = nvpair_nvlist(nvl->nvl_parent);
			nvpair_free_structure(nvp);
			continue;
		default:
			PJDLOG_ABORT("Invalid type (%d).", nvpair_type(nvp));
		}
		if (ptr == NULL)
			goto failed;
		nvlist_move_nvpair(nvl, nvp);
		if (tmpnvl != NULL) {
			nvl = tmpnvl;
			tmpnvl = NULL;
		}
	}

	return (retnvl);
failed:
	nvlist_destroy(retnvl);
	return (NULL);
}
Exemple #20
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);
}