nvlist_t * nvlist_recv(int sock, int flags) { struct nvlist_header nvlhdr; nvlist_t *nvl, *ret; unsigned char *buf; size_t nfds, size, i; int *fds; if (buf_recv(sock, &nvlhdr, sizeof(nvlhdr)) == -1) return (NULL); if (!nvlist_check_header(&nvlhdr)) return (NULL); nfds = (size_t)nvlhdr.nvlh_descriptors; size = sizeof(nvlhdr) + (size_t)nvlhdr.nvlh_size; buf = nv_malloc(size); if (buf == NULL) return (NULL); memcpy(buf, &nvlhdr, sizeof(nvlhdr)); ret = NULL; fds = NULL; if (buf_recv(sock, buf + sizeof(nvlhdr), size - sizeof(nvlhdr)) == -1) goto out; if (nfds > 0) { fds = nv_malloc(nfds * sizeof(fds[0])); if (fds == NULL) goto out; if (fd_recv(sock, fds, nfds) == -1) goto out; } nvl = nvlist_xunpack(buf, size, fds, nfds, flags); if (nvl == NULL) { ERRNO_SAVE(); for (i = 0; i < nfds; i++) close(fds[i]); ERRNO_RESTORE(); goto out; } ret = nvl; out: ERRNO_SAVE(); nv_free(buf); nv_free(fds); ERRNO_RESTORE(); return (ret); }
nvlist_t * nvlist_recv(int sock) { struct nvlist_header nvlhdr; nvlist_t *nvl, *ret; unsigned char *buf; size_t nfds, size; int serrno, *fds; if (buf_recv(sock, &nvlhdr, sizeof(nvlhdr)) == -1) return (NULL); if (!nvlist_check_header(&nvlhdr)) return (NULL); nfds = (size_t)nvlhdr.nvlh_descriptors; size = sizeof(nvlhdr) + (size_t)nvlhdr.nvlh_size; buf = malloc(size); if (buf == NULL) return (NULL); memcpy(buf, &nvlhdr, sizeof(nvlhdr)); ret = NULL; fds = NULL; if (buf_recv(sock, buf + sizeof(nvlhdr), size - sizeof(nvlhdr)) == -1) goto out; if (nfds > 0) { fds = malloc(nfds * sizeof(fds[0])); if (fds == NULL) goto out; if (fd_recv(sock, fds, nfds) == -1) goto out; } nvl = nvlist_xunpack(buf, size, fds, nfds); if (nvl == NULL) goto out; ret = nvl; out: serrno = errno; free(buf); free(fds); errno = serrno; return (ret); }
static int fmd_ckpt_restore_suspects(fmd_ckpt_t *ckp, fmd_case_t *cp, fcf_secidx_t sid) { const fcf_nvl_t *fcfn, *endn; const fcf_sec_t *sp; nvlist_t *nvl; int err, i; if ((sp = fmd_ckpt_secptr(ckp, sid, FCF_SECT_NVLISTS)) == NULL) { fmd_ckpt_error(ckp, EFMD_CKPT_INVAL, "invalid link to section %u: expected nvlists\n", sid); } fcfn = fmd_ckpt_dataptr(ckp, sp); endn = fmd_ckpt_datalim(ckp, sp); for (i = 0; fcfn < endn; i++) { char *data = (char *)fcfn + sp->fcfs_entsize; size_t size = (size_t)fcfn->fcfn_size; if (fcfn->fcfn_size > (size_t)((char *)endn - data)) { fmd_ckpt_error(ckp, EFMD_CKPT_INVAL, "nvlist %u [%d] " "size %u exceeds buffer\n", sid, i, size); } if ((err = nvlist_xunpack(data, size, &nvl, &fmd.d_nva)) != 0) { fmd_ckpt_error(ckp, EFMD_CKPT_INVAL, "failed to " "unpack nvlist %u [%d]: %s\n", sid, i, fmd_strerror(err)); } fmd_case_insert_suspect(cp, nvl); size = sp->fcfs_entsize + fcfn->fcfn_size; size = P2ROUNDUP(size, sizeof (uint64_t)); fcfn = (fcf_nvl_t *)((uintptr_t)fcfn + size); } return (i); }
nvlist_t * nvlist_unpack(const void *buf, size_t size, int flags) { return (nvlist_xunpack(buf, size, NULL, 0, flags)); }
nvlist_t * nvlist_unpack(const void *buf, size_t size) { return (nvlist_xunpack(buf, size, NULL, 0)); }