Deleted Added
sdiff udiff text old ( 217732 ) new ( 225787 )
full compact
1/*-
2 * Copyright (c) 2009-2010 The FreeBSD Foundation
3 * All rights reserved.
4 *
5 * This software was developed by Pawel Jakub Dawidek under sponsorship from
6 * the FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sbin/hastd/nv.c 217732 2011-01-22 22:38:18Z pjd $");
32
33#include <sys/param.h>
34#include <sys/endian.h>
35
36#include <assert.h>
37#include <bitstring.h>
38#include <errno.h>
39#include <stdarg.h>
40#include <stdbool.h>
41#include <stdint.h>
42#include <stdlib.h>
43#include <string.h>
44#include <unistd.h>
45
46#include <ebuf.h>
47#include <nv.h>
48
49#define NV_TYPE_NONE 0
50
51#define NV_TYPE_INT8 1
52#define NV_TYPE_UINT8 2
53#define NV_TYPE_INT16 3
54#define NV_TYPE_UINT16 4
55#define NV_TYPE_INT32 5
56#define NV_TYPE_UINT32 6

--- 36 unchanged lines hidden (view full) ---

93 (sizeof(struct nvhdr) + roundup2((nvh)->nvh_namesize, 8))
94#define NVH_DSIZE(nvh) \
95 (((nvh)->nvh_type & NV_ORDER_MASK) == NV_ORDER_HOST ? \
96 (nvh)->nvh_dsize : \
97 le32toh((nvh)->nvh_dsize))
98#define NVH_SIZE(nvh) (NVH_HSIZE(nvh) + roundup2(NVH_DSIZE(nvh), 8))
99
100#define NV_CHECK(nv) do { \
101 assert((nv) != NULL); \
102 assert((nv)->nv_magic == NV_MAGIC); \
103} while (0)
104
105static void nv_add(struct nv *nv, const unsigned char *value, size_t vsize,
106 int type, const char *name);
107static void nv_addv(struct nv *nv, const unsigned char *value, size_t vsize,
108 int type, const char *namefmt, va_list nameap);
109static struct nvhdr *nv_find(struct nv *nv, int type, const char *namefmt,
110 va_list nameap);

--- 84 unchanged lines hidden (view full) ---

195 int error;
196
197 if (nv == NULL) {
198 errno = ENOMEM;
199 return (-1);
200 }
201
202 NV_CHECK(nv);
203 assert(nv->nv_error == 0);
204
205 /* TODO: Check that names are unique? */
206
207 error = 0;
208 ptr = ebuf_data(nv->nv_ebuf, &size);
209 while (size > 0) {
210 /*
211 * Zeros at the end of the buffer are acceptable.

--- 91 unchanged lines hidden (view full) ---

303 break;
304 }
305 if (strlen((char *)data) != dsize - 1) {
306 error = EINVAL;
307 break;
308 }
309 break;
310 default:
311 assert(!"invalid condition");
312 }
313 if (error != 0)
314 break;
315 ptr += NVH_SIZE(nvh);
316 size -= NVH_SIZE(nvh);
317 }
318 if (error != 0) {
319 errno = error;

--- 13 unchanged lines hidden (view full) ---

333struct ebuf *
334nv_hton(struct nv *nv)
335{
336 struct nvhdr *nvh;
337 unsigned char *ptr;
338 size_t size;
339
340 NV_CHECK(nv);
341 assert(nv->nv_error == 0);
342
343 ptr = ebuf_data(nv->nv_ebuf, &size);
344 while (size > 0) {
345 /*
346 * Minimum size at this point is size of nvhdr structure,
347 * one character long name plus terminating '\0'.
348 */
349 assert(size >= sizeof(*nvh) + 2);
350 nvh = (struct nvhdr *)ptr;
351 assert(NVH_SIZE(nvh) <= size);
352 nv_swap(nvh, false);
353 ptr += NVH_SIZE(nvh);
354 size -= NVH_SIZE(nvh);
355 }
356
357 return (nv->nv_ebuf);
358}
359
360/*
361 * Create nv structure based on ebuf received from the network.
362 */
363struct nv *
364nv_ntoh(struct ebuf *eb)
365{
366 struct nv *nv;
367 size_t extra;
368 int rerrno;
369
370 assert(eb != NULL);
371
372 nv = malloc(sizeof(*nv));
373 if (nv == NULL)
374 return (NULL);
375 nv->nv_error = 0;
376 nv->nv_ebuf = eb;
377 nv->nv_magic = NV_MAGIC;
378

--- 110 unchanged lines hidden (view full) ---

489 va_list nameap; \
490 type##_t value; \
491 \
492 va_start(nameap, namefmt); \
493 nvh = nv_find(nv, NV_TYPE_##TYPE, namefmt, nameap); \
494 va_end(nameap); \
495 if (nvh == NULL) \
496 return (0); \
497 assert((nvh->nvh_type & NV_ORDER_MASK) == NV_ORDER_HOST); \
498 assert(sizeof(value) == nvh->nvh_dsize); \
499 bcopy(NVH_DATA(nvh), &value, sizeof(value)); \
500 \
501 return (value); \
502}
503
504NV_DEFINE_GET(int8, INT8)
505NV_DEFINE_GET(uint8, UINT8)
506NV_DEFINE_GET(int16, INT16)

--- 13 unchanged lines hidden (view full) ---

520 struct nvhdr *nvh; \
521 va_list nameap; \
522 \
523 va_start(nameap, namefmt); \
524 nvh = nv_find(nv, NV_TYPE_##TYPE##_ARRAY, namefmt, nameap); \
525 va_end(nameap); \
526 if (nvh == NULL) \
527 return (NULL); \
528 assert((nvh->nvh_type & NV_ORDER_MASK) == NV_ORDER_HOST); \
529 assert((nvh->nvh_dsize % sizeof(type##_t)) == 0); \
530 if (sizep != NULL) \
531 *sizep = nvh->nvh_dsize / sizeof(type##_t); \
532 return ((type##_t *)(void *)NVH_DATA(nvh)); \
533}
534
535NV_DEFINE_GET_ARRAY(int8, INT8)
536NV_DEFINE_GET_ARRAY(uint8, UINT8)
537NV_DEFINE_GET_ARRAY(int16, INT16)

--- 12 unchanged lines hidden (view full) ---

550 va_list nameap;
551 char *str;
552
553 va_start(nameap, namefmt);
554 nvh = nv_find(nv, NV_TYPE_STRING, namefmt, nameap);
555 va_end(nameap);
556 if (nvh == NULL)
557 return (NULL);
558 assert((nvh->nvh_type & NV_ORDER_MASK) == NV_ORDER_HOST);
559 assert(nvh->nvh_dsize >= 1);
560 str = NVH_DATA(nvh);
561 assert(str[nvh->nvh_dsize - 1] == '\0');
562 assert(strlen(str) == nvh->nvh_dsize - 1);
563 return (str);
564}
565
566static bool
567nv_vexists(struct nv *nv, const char *namefmt, va_list nameap)
568{
569 struct nvhdr *nvh;
570 int snverror, serrno;

--- 26 unchanged lines hidden (view full) ---

597}
598
599void
600nv_assert(struct nv *nv, const char *namefmt, ...)
601{
602 va_list nameap;
603
604 va_start(nameap, namefmt);
605 assert(nv_vexists(nv, namefmt, nameap));
606 va_end(nameap);
607}
608
609/*
610 * Dump content of the nv structure.
611 */
612void
613nv_dump(struct nv *nv)

--- 5 unchanged lines hidden (view full) ---

619 bool swap;
620
621 if (nv_validate(nv, NULL) < 0) {
622 printf("error: %d\n", errno);
623 return;
624 }
625
626 NV_CHECK(nv);
627 assert(nv->nv_error == 0);
628
629 ptr = ebuf_data(nv->nv_ebuf, &size);
630 while (size > 0) {
631 assert(size >= sizeof(*nvh) + 2);
632 nvh = (struct nvhdr *)ptr;
633 assert(size >= NVH_SIZE(nvh));
634 swap = ((nvh->nvh_type & NV_ORDER_MASK) == NV_ORDER_NETWORK);
635 dsize = NVH_DSIZE(nvh);
636 data = NVH_DATA(nvh);
637 printf(" %s", nvh->nvh_name);
638 switch (nvh->nvh_type & NV_TYPE_MASK) {
639 case NV_TYPE_INT8:
640 printf("(int8): %jd", (intmax_t)(*(int8_t *)data));
641 break;

--- 87 unchanged lines hidden (view full) ---

729 (uintmax_t)le64toh(((uint64_t *)(void *)data)[ii]) :
730 (uintmax_t)((uint64_t *)(void *)data)[ii]);
731 }
732 break;
733 case NV_TYPE_STRING:
734 printf("(string): %s", (char *)data);
735 break;
736 default:
737 assert(!"invalid condition");
738 }
739 printf("\n");
740 ptr += NVH_SIZE(nvh);
741 size -= NVH_SIZE(nvh);
742 }
743}
744
745/*

--- 25 unchanged lines hidden (view full) ---

771 }
772 nvh->nvh_type = NV_ORDER_HOST | type;
773 nvh->nvh_namesize = (uint8_t)namesize;
774 nvh->nvh_dsize = (uint32_t)vsize;
775 bcopy(name, nvh->nvh_name, namesize);
776
777 /* Add header first. */
778 if (ebuf_add_tail(nv->nv_ebuf, nvh, NVH_HSIZE(nvh)) < 0) {
779 assert(errno != 0);
780 if (nv->nv_error == 0)
781 nv->nv_error = errno;
782 free(nvh);
783 return;
784 }
785 free(nvh);
786 /* Add the actual data. */
787 if (ebuf_add_tail(nv->nv_ebuf, value, vsize) < 0) {
788 assert(errno != 0);
789 if (nv->nv_error == 0)
790 nv->nv_error = errno;
791 return;
792 }
793 /* Align the data (if needed). */
794 vsize = roundup2(vsize, 8) - vsize;
795 if (vsize == 0)
796 return;
797 assert(vsize > 0 && vsize <= sizeof(align));
798 if (ebuf_add_tail(nv->nv_ebuf, align, vsize) < 0) {
799 assert(errno != 0);
800 if (nv->nv_error == 0)
801 nv->nv_error = errno;
802 return;
803 }
804}
805
806static void
807nv_addv(struct nv *nv, const unsigned char *value, size_t vsize, int type,
808 const char *namefmt, va_list nameap)
809{
810 char name[255];
811 size_t namesize;
812
813 namesize = vsnprintf(name, sizeof(name), namefmt, nameap);
814 assert(namesize > 0 && namesize < sizeof(name));
815
816 nv_add(nv, value, vsize, type, name);
817}
818
819static struct nvhdr *
820nv_find(struct nv *nv, int type, const char *namefmt, va_list nameap)
821{
822 char name[255];

--- 4 unchanged lines hidden (view full) ---

827 if (nv == NULL) {
828 errno = ENOMEM;
829 return (NULL);
830 }
831
832 NV_CHECK(nv);
833
834 namesize = vsnprintf(name, sizeof(name), namefmt, nameap);
835 assert(namesize > 0 && namesize < sizeof(name));
836 namesize++;
837
838 ptr = ebuf_data(nv->nv_ebuf, &size);
839 while (size > 0) {
840 assert(size >= sizeof(*nvh) + 2);
841 nvh = (struct nvhdr *)ptr;
842 assert(size >= NVH_SIZE(nvh));
843 nv_swap(nvh, true);
844 if (strcmp(nvh->nvh_name, name) == 0) {
845 if (type != NV_TYPE_NONE &&
846 (nvh->nvh_type & NV_TYPE_MASK) != type) {
847 errno = EINVAL;
848 if (nv->nv_error == 0)
849 nv->nv_error = EINVAL;
850 return (NULL);

--- 71 unchanged lines hidden (view full) ---

922 *(uint32_t *)(void *)p =
923 le32toh(*(uint32_t *)(void *)p);
924 break;
925 case 8:
926 *(uint64_t *)(void *)p =
927 le64toh(*(uint64_t *)(void *)p);
928 break;
929 default:
930 assert(!"invalid condition");
931 }
932 } else {
933 switch (vsize) {
934 case 2:
935 *(uint16_t *)(void *)p =
936 htole16(*(uint16_t *)(void *)p);
937 break;
938 case 4:
939 *(uint32_t *)(void *)p =
940 htole32(*(uint32_t *)(void *)p);
941 break;
942 case 8:
943 *(uint64_t *)(void *)p =
944 htole64(*(uint64_t *)(void *)p);
945 break;
946 default:
947 assert(!"invalid condition");
948 }
949 }
950 }
951 break;
952 case NV_TYPE_STRING:
953 break;
954 default:
955 assert(!"unrecognized type");
956 }
957}