File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libpdel / structs / test / main.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 23:25:53 2012 UTC (13 years, 10 months ago) by misho
Branches: libpdel, MAIN
CVS tags: v0_5_3, HEAD
libpdel

    1: 
    2: /*
    3:  * Copyright (c) 2001-2002 Packet Design, LLC.
    4:  * All rights reserved.
    5:  * 
    6:  * Subject to the following obligations and disclaimer of warranty,
    7:  * use and redistribution of this software, in source or object code
    8:  * forms, with or without modifications are expressly permitted by
    9:  * Packet Design; provided, however, that:
   10:  * 
   11:  *    (i)  Any and all reproductions of the source or object code
   12:  *         must include the copyright notice above and the following
   13:  *         disclaimer of warranties; and
   14:  *    (ii) No rights are granted, in any manner or form, to use
   15:  *         Packet Design trademarks, including the mark "PACKET DESIGN"
   16:  *         on advertising, endorsements, or otherwise except as such
   17:  *         appears in the above copyright notice or in the software.
   18:  * 
   19:  * THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
   20:  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
   21:  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
   22:  * THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
   23:  * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
   24:  * OR NON-INFRINGEMENT.  PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
   25:  * OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
   26:  * OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
   27:  * RELIABILITY OR OTHERWISE.  IN NO EVENT SHALL PACKET DESIGN BE
   28:  * LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
   29:  * OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
   30:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
   31:  * DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
   32:  * USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
   33:  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   34:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
   35:  * THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
   36:  * THE POSSIBILITY OF SUCH DAMAGE.
   37:  *
   38:  * Author: Archie Cobbs <archie@freebsd.org>
   39:  */
   40: 
   41: #include <sys/types.h>
   42: #include <sys/time.h>
   43: #include <netinet/in.h>
   44: #include <arpa/inet.h>
   45: #ifndef NO_BPF
   46: #include <net/bpf.h>
   47: #endif
   48: 
   49: #include <stdio.h>
   50: #include <stdlib.h>
   51: #include <stdarg.h>
   52: #include <stddef.h>
   53: #include <string.h>
   54: #include <unistd.h>
   55: #include <errno.h>
   56: #ifndef NO_BPF
   57: #include <pcap.h>
   58: #endif
   59: #include <err.h>
   60: 
   61: #include <pdel/structs/structs.h>
   62: #include <pdel/structs/xml.h>
   63: #include <pdel/structs/types.h>
   64: #include <pdel/structs/xmlrpc.h>
   65: #include <pdel/structs/type/ip6.h>
   66: #include <pdel/sys/alog.h>
   67: #include <pdel/util/typed_mem.h>
   68: 
   69: #define ELEM_TAG		"structs_test"
   70: #define XMLRPC_TAG		"value"
   71: #define ATTR_MEM_TYPE		"attr_mem_type"
   72: 
   73: /* Our structures, etc */
   74: struct array_elem {
   75: 	u_int16_t		elem_value;
   76: 	char			*elem_string;
   77: 	u_char			elem_ether[6];
   78: 	u_int32_t		elem_color;
   79: 	struct in_addr		elem_ip;
   80: 	float			elem_float;
   81: 	double			elem_double;
   82: 	u_char			elem_bytes[13];
   83: 	char			elem_bstring[13];
   84: 	struct structs_dnsname	elem_dnsname;
   85: };
   86: 
   87: union ip_address {
   88: 	struct in_addr	ip4;
   89: 	struct in6_addr	ip6;
   90: };
   91: 
   92: /* fields for union ip_address */
   93: static const struct structs_ufield ip_address_fields[] = {
   94: 	STRUCTS_UNION_FIELD(ip4, &structs_type_ip4),
   95: 	STRUCTS_UNION_FIELD(ip6, &structs_type_ip6),
   96: 	STRUCTS_UNION_FIELD_END
   97: };
   98: 
   99: /* structs type for union ip_address */
  100: static const struct structs_type ip_address_type
  101: 	= STRUCTS_UNION_TYPE(ip_address, &ip_address_fields);
  102: 
  103: /* c type for union ip_address */
  104: DEFINE_STRUCTS_UNION(ip_address_struct, ip_address);
  105: 
  106: struct prefix_ip {
  107: 	struct ip_address_struct ip_addr;
  108: 	u_int masklen;
  109: };
  110: 
  111: static struct structs_field prefix_ip_fields[] = {
  112: 	STRUCTS_STRUCT_FIELD(prefix_ip, ip_addr, &ip_address_type),
  113: 	STRUCTS_STRUCT_FIELD(prefix_ip, masklen, &structs_type_uint),
  114: 	STRUCTS_STRUCT_FIELD_END
  115: };
  116: 
  117: static const struct structs_type prefix_ip_type
  118: 	= STRUCTS_STRUCT_TYPE(prefix_ip, prefix_ip_fields);
  119: 
  120: union my_union {
  121: 	char 		*u_string;
  122: 	int64_t		u_int64;
  123: 	u_char		u_bool;
  124: };
  125: 
  126: DEFINE_STRUCTS_UNION(ustruct, my_union);
  127: 
  128: #define INNER_STRARY_LEN	4
  129: 
  130: struct inner_struct {
  131: 	char			*inner_string;
  132: 	struct structs_data	inner_data;
  133: 	struct structs_data	inner_data2;
  134: 	struct structs_array	inner_array;
  135: 	struct array_elem	inner_struct;
  136: 	struct structs_array	inner_struct_ptr_array;
  137: 	u_char			*inner_ether;
  138: 	struct alog_config	inner_alog;
  139: #ifndef NO_BPF
  140: 	struct structs_bpf	*inner_bpf;
  141: #endif
  142: 	time_t			inner_time_gmt;
  143: 	time_t			inner_time_local;
  144: 	time_t			inner_time_iso8601;
  145: 	time_t			inner_time_rel;
  146: 	struct ustruct		inner_union;
  147: 	struct ustruct		inner_union2;
  148: 	struct ip_address_struct	ip6_mapped_from_ip4;
  149: 	struct ip_address_struct	ip6;
  150: 	struct ip_address_struct	ip4;
  151: 	struct prefix_ip	pfx_ip6;
  152: 	struct prefix_ip	pfx_ip4;
  153: 	struct structs_regex	inner_regex;
  154: 	char			*inner_strary[INNER_STRARY_LEN];
  155: };
  156: 
  157: /* Type for field 'elem_color' */
  158: static const struct structs_id color_list[] = {
  159: 	{ "Red", 1 }, { "Green", 2 }, { "Blue", 3 }, { NULL, 0 }
  160: };
  161: static const struct structs_type color_type
  162: 	= STRUCTS_ID_TYPE(color_list, sizeof(u_int32_t));
  163: 
  164: /* Type for field 'elem_bytes' */
  165: static const struct structs_type elem_bytes_type
  166: 	= STRUCTS_FIXEDDATA_TYPE(sizeof(((struct array_elem *)0)->elem_bytes));
  167: 
  168: /* Type for field 'elem_bstring' */
  169: static const struct structs_type elem_bstring_type
  170: 	= STRUCTS_FIXEDSTRING_TYPE(
  171: 	  sizeof(((struct array_elem *)0)->elem_bstring));
  172: 
  173: /* Type for struct array_elem */
  174: static const struct structs_field array_elem_fields[] = {
  175: 	STRUCTS_STRUCT_FIELD(array_elem, elem_value, &structs_type_uint16),
  176: 	STRUCTS_STRUCT_FIELD(array_elem, elem_string, &structs_type_string),
  177: 	STRUCTS_STRUCT_FIELD(array_elem, elem_ether, &structs_type_ether),
  178: 	STRUCTS_STRUCT_FIELD(array_elem, elem_bstring, &elem_bstring_type),
  179: 	STRUCTS_STRUCT_FIELD(array_elem, elem_dnsname, &structs_type_dnsname),
  180: 	STRUCTS_STRUCT_FIELD(array_elem, elem_color, &color_type),
  181: 	STRUCTS_STRUCT_FIELD(array_elem, elem_ip, &structs_type_ip4),
  182: 	STRUCTS_STRUCT_FIELD(array_elem, elem_float, &structs_type_float),
  183: 	STRUCTS_STRUCT_FIELD(array_elem, elem_double, &structs_type_double),
  184: 	STRUCTS_STRUCT_FIELD(array_elem, elem_bytes, &elem_bytes_type),
  185: 	STRUCTS_STRUCT_FIELD_END
  186: };
  187: static const struct structs_type array_elem_type
  188: 	= STRUCTS_STRUCT_TYPE(array_elem, &array_elem_fields);
  189: static const struct structs_type array_elem_ptr_type
  190: 	= STRUCTS_POINTER_TYPE(&array_elem_type, "array_elem_ptr");
  191: /* Type for array of pointers to array_elems type */
  192: static const struct structs_type array_elem_ptr_array_type
  193: 	= STRUCTS_ARRAY_TYPE(&array_elem_ptr_type,
  194: 	    "inner_struct_ptr", "inner_struct_ptr");
  195: 
  196: /* Type for array of array_elems type */
  197: static const struct structs_type inner_array_type
  198: 	= STRUCTS_ARRAY_TYPE(&array_elem_type, "array_elem", "array_elem");
  199: 
  200: /* Type for pointer to Ethernet address */
  201: static const struct structs_type ether_ptr_type
  202: 	= STRUCTS_POINTER_TYPE(&structs_type_ether_nocolon, "ether_ptr");
  203: 
  204: /* Type for union my_union */
  205: static const struct structs_ufield my_union_fields[] = {
  206: 	STRUCTS_UNION_FIELD(u_string, &structs_type_string),
  207: 	STRUCTS_UNION_FIELD(u_int64, &structs_type_int64),
  208: 	STRUCTS_UNION_FIELD(u_bool, &structs_type_boolean_char),
  209: 	STRUCTS_UNION_FIELD_END
  210: };
  211: static const struct structs_type my_union_type
  212: 	= STRUCTS_UNION_TYPE(my_union, &my_union_fields);
  213: 
  214: /* Type for field "inner_strary" in struct inner_struct */
  215: static const struct structs_type structs_type_strary
  216: 	= STRUCTS_FIXEDARRAY_TYPE(&structs_type_string,
  217: 	    sizeof(char *), INNER_STRARY_LEN, "strary_elem");
  218: 
  219: #ifndef NO_BPF
  220: /* Type for field "inner_bpf" in struct inner_struct */
  221: static structs_bpf_compile_t	bpf_compiler;
  222: 
  223: static const struct structs_type inner_bpf_type
  224: 	= BPF_STRUCTS_TYPE(DLT_EN10MB, bpf_compiler);
  225: #endif
  226: 
  227: /* Type for struct inner_struct */
  228: static const struct structs_field inner_struct_fields[] = {
  229: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_string, &structs_type_string),
  230: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_data, &structs_type_data),
  231: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_data2, &structs_type_hexdata),
  232: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_array, &inner_array_type),
  233: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_struct, &array_elem_type),
  234: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_struct_ptr_array,
  235: 		&array_elem_ptr_array_type),
  236: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_ether, &ether_ptr_type),
  237: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_alog, &alog_config_type),
  238: #ifndef NO_BPF
  239: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_bpf, &inner_bpf_type),
  240: #endif
  241: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_time_gmt,
  242: 		&structs_type_time_gmt),
  243: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_time_local,
  244: 		&structs_type_time_local),
  245: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_time_iso8601,
  246: 		&structs_type_time_iso8601),
  247: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_time_rel,
  248: 		&structs_type_time_rel),
  249: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_union, &my_union_type),
  250: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_union2, &my_union_type),
  251: 	STRUCTS_STRUCT_FIELD(inner_struct, ip6_mapped_from_ip4, &ip_address_type),
  252: 	STRUCTS_STRUCT_FIELD(inner_struct, ip6, &ip_address_type),
  253: 	STRUCTS_STRUCT_FIELD(inner_struct, ip4, &ip_address_type),
  254: 	STRUCTS_STRUCT_FIELD(inner_struct, pfx_ip6, &prefix_ip_type),
  255: 	STRUCTS_STRUCT_FIELD(inner_struct, pfx_ip4, &prefix_ip_type),
  256: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_regex, &structs_type_regex),
  257: 	STRUCTS_STRUCT_FIELD(inner_struct, inner_strary, &structs_type_strary),
  258: 	STRUCTS_STRUCT_FIELD_END
  259: };
  260: static const struct structs_type inner_struct_type
  261: 	= STRUCTS_STRUCT_TYPE(inner_struct, &inner_struct_fields);
  262: 
  263: static int	structs_encode(const char *fname);
  264: static int	structs_decode(const char *fname);
  265: 
  266: static struct	in_addr random_ip = { 0x04030201 };
  267: 
  268: static int	flags;
  269: 
  270: int
  271: main(int argc, char *argv[])
  272: {
  273: 	const struct structs_type *type = &inner_struct_type;
  274: 	struct inner_struct s, scopy;
  275: 	const char *name = "inner_array.1.elem_string";
  276: 	const char *value = "new value";
  277: 	const char *fname = NULL;
  278: 	char ebuf[128] = { '\0' };
  279: 	int xml2xmlrpc = 0;
  280: 	int normalize = 0;
  281: 	int nostats = 0;
  282: 	int coding = 0;
  283: 	void *xmlrpc;
  284: 	char *attrs;
  285: 	char *t;
  286: 	int ch;
  287: 
  288: 	/* Parse command line arguments */
  289: 	while ((ch = getopt(argc, argv, "cdef:nxlTt")) != -1) {
  290: 		switch (ch) {
  291: 		case 'c':
  292: 			flags |= STRUCTS_XML_COMB_TAGS;
  293: 			break;
  294: 		case 'd':
  295: 			coding = -1;
  296: 			break;
  297: 		case 'e':
  298: 			coding = 1;
  299: 			break;
  300: 		case 'f':
  301: 			fname = optarg;
  302: 			break;
  303: 		case 'l':
  304: 			flags |= STRUCTS_XML_LOOSE;
  305: 			break;
  306: 		case 'n':
  307: 			normalize = 1;
  308: 			break;
  309: 		case 'x':
  310: 			nostats = 1;
  311: 			break;
  312: 		case 't':
  313: 			xml2xmlrpc = 1;
  314: 			break;
  315: 		case 'T':
  316: 			xml2xmlrpc = -1;
  317: 			break;
  318: 		default:
  319: usage:			errx(1, "usage:\n"
  320: 		"\tstructs_test [-xlc] < test.xml\n"
  321: 		"\tstructs_test -n [-xlc] < test.xml > test.xml\n"
  322: 		"\tstructs_test -t [-xlc] < test.xml > test.xmlrpc\n"
  323: 		"\tstructs_test -T [-x] < test.xmlrpc > test.xml\n"
  324: 		"\tstructs_test -e [-f field] [-xlc] < test.xml > test.bin\n"
  325: 		"\tstructs_test -d [-f field] [-xlc] < test.bin > test.xml");
  326: 		}
  327: 	}
  328: 	argc -= optind;
  329: 	argv += optind;
  330: 	switch (argc) {
  331: 	case 0:
  332: 		break;
  333: 	default:
  334: 		goto usage;
  335: 	}
  336: 
  337: 	if (typed_mem_enable() == -1)
  338: 		err(1, "typed_mem_enable");
  339: 
  340: 	if (coding && normalize)
  341: 		goto usage;
  342: 
  343: 	/* Binary encoding/decoding? */
  344: 	if (coding == 1) {
  345: 		structs_encode(fname);
  346: 		goto done;
  347: 	}
  348: 	if (coding == -1) {
  349: 		structs_decode(fname);
  350: 		goto done;
  351: 	}
  352: 
  353: 	/* Convert between XML and XML-RPC? */
  354: 	if (xml2xmlrpc == 1) {
  355: 		const struct structs_type *const xtype
  356: 		    = &structs_type_xmlrpc_value;
  357: 		struct xmlrpc_value_union xvalue;
  358: 
  359: 		if (structs_xml_input(type, ELEM_TAG, NULL,
  360: 		    NULL, stdin, &s, STRUCTS_XML_UNINIT | flags,
  361: 		    STRUCTS_LOGGER_STDERR) == -1)
  362: 			err(1, "structs_xml_input");
  363: 		if (structs_init(xtype, NULL, &xvalue) == -1)
  364: 			err(1, "structs_init");
  365: 		if (structs_struct2xmlrpc(type, &s, NULL,
  366: 		    xtype, &xvalue, NULL) == -1)
  367: 			err(1, "structs_struct2xmlrpc");
  368: 		structs_free(type, NULL, &s);
  369: 		if (structs_xml_output(xtype, XMLRPC_TAG, NULL,
  370: 		    &xvalue, stdout, NULL, 0) == -1)
  371: 			err(1, "structs_xml_output");
  372: 		structs_free(xtype, NULL, &xvalue);
  373: 		goto done;
  374: 	} else if (xml2xmlrpc == -1) {
  375: 		const struct structs_type *const xtype
  376: 		    = &structs_type_xmlrpc_value;
  377: 		struct xmlrpc_value_union xvalue;
  378: 
  379: 		if (structs_xml_input(xtype, XMLRPC_TAG, NULL,
  380: 		    NULL, stdin, &xvalue, STRUCTS_XML_UNINIT,
  381: 		    STRUCTS_LOGGER_STDERR) == -1)
  382: 			err(1, "structs_xml_input");
  383: 		if (structs_init(type, NULL, &s) == -1)
  384: 			err(1, "structs_init");
  385: 		if (structs_xmlrpc2struct(xtype, &xvalue, NULL,
  386: 		    type, &s, NULL, ebuf, sizeof(ebuf)) == -1)
  387: 			errx(1, "structs_struct2xmlrpc: %s", ebuf);
  388: 		structs_free(xtype, NULL, &xvalue);
  389: 		if (structs_xml_output(type, ELEM_TAG, NULL,
  390: 		    &s, stdout, NULL, 0) == -1)
  391: 			err(1, "structs_xml_output");
  392: 		structs_free(type, NULL, &s);
  393: 		goto done;
  394: 	}
  395: 
  396: 	/* Normalize XML? */
  397: 	if (normalize) {
  398: 		if (structs_xml_input(type, ELEM_TAG, NULL,
  399: 		    NULL, stdin, &s, STRUCTS_XML_UNINIT | flags,
  400: 		    STRUCTS_LOGGER_STDERR) == -1)
  401: 			err(1, "structs_xml_input");
  402: 		if (structs_xml_output(type, ELEM_TAG, NULL,
  403: 		    &s, stdout, NULL, 0) == -1)
  404: 			err(1, "structs_xml_output");
  405: 		structs_free(type, NULL, &s);
  406: 		goto done;
  407: 	}
  408: 
  409: 	printf(">>>>>>>> TEST: Initializing struct...\n");
  410: 	if (structs_init(type, NULL, &s) == -1) {
  411: 		warn("structs_init");
  412: 		goto done;
  413: 	}
  414: 
  415: 	printf(">>>>>>>> TEST: Dumping initialized struct...\n");
  416: 	if (structs_xml_output(type,
  417: 	    ELEM_TAG, NULL, &s, stdout, NULL, 0) == -1) {
  418: 		warn("structs_xml_output");
  419: 		structs_free(type, NULL, &s);
  420: 		goto done;
  421: 	}
  422: 
  423: 	printf(">>>>>>>> TEST: Free'ing struct...\n");
  424: 	structs_free(type, NULL, &s);
  425: 
  426: 	printf(">>>>>>>> TEST: Initializing struct...\n");
  427: 	if (structs_init(type, NULL, &s) == -1) {
  428: 		warn("structs_init");
  429: 		goto done;
  430: 	}
  431: 
  432: 	printf(">>>>>>>> TEST: Setting %s to \"%s\"...\n",
  433: 	    "inner_union.u_int64", "0");
  434: 	if (structs_set_string(type, "inner_union.u_int64",
  435: 	    "0", &s, ebuf, sizeof(ebuf)) == -1) {
  436: 		warnx("structs_set_string: %s", ebuf);
  437: 		structs_free(type, NULL, &s);
  438: 		goto done;
  439: 	}
  440: 
  441: 	printf(">>>>>>>> TEST: Dumping struct, should show the union...\n");
  442: 	if (structs_xml_output(type,
  443: 	    ELEM_TAG, NULL, &s, stdout, NULL, 0) == -1) {
  444: 		warn("structs_xml_output");
  445: 		structs_free(type, NULL, &s);
  446: 		goto done;
  447: 	}
  448: 
  449:     {
  450: 	const char *elems[] = { "inner_union", NULL };
  451: 
  452: 	printf(">>>>>>>> TEST: Dumping only \"%s\", but full...\n", elems[0]);
  453: 	if (structs_xml_output(type,
  454: 	    ELEM_TAG, NULL, &s, stdout, elems, STRUCTS_XML_FULL) == -1) {
  455: 		warn("structs_xml_output");
  456: 		FREE(ATTR_MEM_TYPE, attrs);
  457: 		structs_free(type, NULL, &s);
  458: 		goto done;
  459: 	}
  460:     }
  461: 
  462: 	printf(">>>>>>>> TEST: Copying struct...\n");
  463: 	if (structs_get(type, NULL, &s, &scopy) == -1) {
  464: 		warn("structs_get");
  465: 		structs_free(type, NULL, &s);
  466: 		goto done;
  467: 	}
  468: 
  469: 	printf(">>>>>>>> TEST: Free'ing both structs...\n");
  470: 	structs_free(type, NULL, &s);
  471: 	structs_free(type, NULL, &scopy);
  472: 
  473: 	printf(">>>>>>>> TEST: Reading input...\n");
  474: 	if (structs_xml_input(type, ELEM_TAG, &attrs,
  475: 	    ATTR_MEM_TYPE, stdin, &s, STRUCTS_XML_UNINIT | flags,
  476: 	    STRUCTS_LOGGER_STDERR) == -1) {
  477: 		warn("structs_xml_input");
  478: 		goto done;
  479: 	}
  480: 
  481: 	printf(">>>>>>>> TEST: Displaying attributes...\n");
  482: 	for (t = attrs; *t != '\0'; ) {
  483: 		printf("%30s =", t);
  484: 		t += strlen(t) + 1;
  485: 		printf(" %s\n", t);
  486: 		t += strlen(t) + 1;
  487: 	}
  488: 
  489: 	printf(">>>>>>>> TEST: Dumping output...\n");
  490: 	if (structs_xml_output(type,
  491: 	    ELEM_TAG, attrs, &s, stdout, NULL, 0) == -1) {
  492: 		warn("structs_xml_output");
  493: 		FREE(ATTR_MEM_TYPE, attrs);
  494: 		structs_free(type, NULL, &s);
  495: 		goto done;
  496: 	}
  497: 
  498:     {
  499: 	const char *elems[] = { "inner_struct", NULL };
  500: 
  501: 	printf(">>>>>>>> TEST: Dumping only \"%s\" ...\n", elems[0]);
  502: 	if (structs_xml_output(type,
  503: 	    ELEM_TAG, attrs, &s, stdout, elems, 0) == -1) {
  504: 		warn("structs_xml_output");
  505: 		FREE(ATTR_MEM_TYPE, attrs);
  506: 		structs_free(type, NULL, &s);
  507: 		goto done;
  508: 	}
  509:     }
  510: 
  511:     {
  512: 	const char *elems[] = {
  513: 	    "inner_struct_ptr_array.2.elem_bytes", NULL };
  514: 
  515: 	printf(">>>>>>>> TEST: Dumping only \"%s\", but full...\n", elems[0]);
  516: 	if (structs_xml_output(type,
  517: 	    ELEM_TAG, NULL, &s, stdout, elems, STRUCTS_XML_FULL) == -1) {
  518: 		warn("structs_xml_output");
  519: 		FREE(ATTR_MEM_TYPE, attrs);
  520: 		structs_free(type, NULL, &s);
  521: 		goto done;
  522: 	}
  523:     }
  524: 
  525: 	printf(">>>>>>>> TEST: Copying struct...\n");
  526: 	if (structs_get(type, NULL, &s, &scopy) == -1) {
  527: 		warn("structs_get");
  528: 		FREE(ATTR_MEM_TYPE, attrs);
  529: 		structs_free(type, NULL, &s);
  530: 		goto done;
  531: 	}
  532: 
  533: 	printf(">>>>>>>> TEST: Dumping copy...\n");
  534: 	if (structs_xml_output(type,
  535: 	    ELEM_TAG, attrs, &scopy, stdout, NULL, 0) == -1) {
  536: 		warn("structs_xml_output");
  537: 		FREE(ATTR_MEM_TYPE, attrs);
  538: 		structs_free(type, NULL, &scopy);
  539: 		structs_free(type, NULL, &s);
  540: 		goto done;
  541: 	}
  542: 	FREE(ATTR_MEM_TYPE, attrs);
  543: 
  544: 	printf(">>>>>>>> TEST: Comparing original and copy...\n");
  545: 	printf("equal = %s\n",
  546: 	    structs_equal(type, NULL, &s, &scopy) ? "TRUE" : "FALSE");
  547: 
  548: 	printf(">>>>>>>> TEST: Setting copy's %s to \"%s\"...\n", name, value);
  549: 	if (structs_set_string(type, name, value,
  550: 	    &scopy, ebuf, sizeof(ebuf)) == -1) {
  551: 		warnx("structs_set_string: %s", ebuf);
  552: 		structs_free(type, NULL, &scopy);
  553: 		structs_free(type, NULL, &s);
  554: 		goto done;
  555: 	}
  556: 
  557: 	printf(">>>>>>>> TEST: Setting copy's %s to \"%s\"...\n",
  558: 	    "inner_union.u_int64", "1234567890");
  559: 	if (structs_set_string(type, "inner_union.u_int64",
  560: 	    "1234567890", &scopy, ebuf, sizeof(ebuf)) == -1) {
  561: 		warnx("structs_set_string: %s", ebuf);
  562: 		structs_free(type, NULL, &scopy);
  563: 		structs_free(type, NULL, &s);
  564: 		goto done;
  565: 	}
  566: 
  567: 	printf(">>>>>>>> TEST: Setting copy's %s to \"%s\"...\n",
  568: 	    "inner_struct.elem_ip", inet_ntoa(random_ip));
  569: 	if (structs_set(type, &random_ip,
  570: 	    "inner_struct.elem_ip", &scopy) == -1) {
  571: 		warn("structs_set");
  572: 		structs_free(type, NULL, &scopy);
  573: 		structs_free(type, NULL, &s);
  574: 		goto done;
  575: 	}
  576: 
  577: 	printf(">>>>>>>> TEST: Comparing original and copy...\n");
  578: 	printf("equal = %s\n",
  579: 	    structs_equal(type, NULL, &s, &scopy) ? "TRUE" : "FALSE");
  580: 
  581: 	printf(">>>>>>>> TEST: Dumping copy...\n");
  582: 	if (structs_xml_output(type,
  583: 	    ELEM_TAG, NULL, &scopy, stdout, NULL, 0) == -1) {
  584: 		warn("structs_xml_output");
  585: 		structs_free(type, NULL, &scopy);
  586: 		structs_free(type, NULL, &s);
  587: 		goto done;
  588: 	}
  589: 
  590: 	printf(">>>>>>>> TEST: Dumping copy in an XML-RPC request...\n");
  591:     {
  592: 	const struct structs_type *types[1] = { type };
  593: 	const void *datas[1] = { &scopy };
  594: 
  595: 	if ((xmlrpc = structs_xmlrpc_build_request(TYPED_MEM_TEMP,
  596: 	    "someMethodName", 1, types, datas)) == NULL) {
  597: 		warn("structs_xmlrpc_build_request");
  598: 		structs_free(type, NULL, &scopy);
  599: 		structs_free(type, NULL, &s);
  600: 		goto done;
  601: 	}
  602: 	if (structs_xml_output(&structs_type_xmlrpc_request,
  603: 	    "methodCall", NULL, xmlrpc, stdout, NULL, 0) == -1) {
  604: 		warn("structs_xml_output");
  605: 		structs_free(&structs_type_xmlrpc_request, NULL, xmlrpc);
  606: 		FREE(TYPED_MEM_TEMP, xmlrpc);
  607: 		structs_free(type, NULL, &scopy);
  608: 		structs_free(type, NULL, &s);
  609: 		goto done;
  610: 	}
  611: 	structs_free(&structs_type_xmlrpc_request, NULL, xmlrpc);
  612: 	FREE(TYPED_MEM_TEMP, xmlrpc);
  613:     }
  614: 
  615: 	printf(">>>>>>>> TEST: dumping copy's element list...\n");
  616:     {
  617: 	char **list;
  618: 	int len;
  619: 	int i;
  620: 
  621: 	if ((len = structs_traverse(type, &scopy, &list, TYPED_MEM_TEMP)) == -1)
  622: 		err(1, "structs_traverse");
  623: 	for (i = 0; i < len; i++) {
  624: 		char *val;
  625: 
  626: 		if ((val = structs_get_string(type,
  627: 		    list[i], &scopy, TYPED_MEM_TEMP)) == NULL)
  628: 			err(1, "structs_get_string");
  629: 		printf("\t%s=%s\n", list[i], val);
  630: 		FREE(TYPED_MEM_TEMP, val);
  631: 	}
  632: 	while (len > 0)
  633: 		FREE(TYPED_MEM_TEMP, list[--len]);
  634: 	FREE(TYPED_MEM_TEMP, list);
  635:     }
  636: 
  637: 	printf(">>>>>>>> TEST: Free'ing original and copy...\n");
  638: 	structs_free(type, NULL, &s);
  639: 	structs_free(type, NULL, &scopy);
  640: 
  641: done:
  642: 	if (!nostats) {
  643: 		FILE *const fp = coding ? stderr : stdout;
  644: 
  645: 		fprintf(fp, ">>>>>>>> TEST: Displaying unfree'd memory...\n");
  646: 		typed_mem_dump(fp);
  647: 	}
  648: 
  649: 	/* Done */
  650: 	return (0);
  651: }
  652: 
  653: static int
  654: structs_encode(const char *fname)
  655: {
  656: 	const struct structs_type *type = &inner_struct_type;
  657: 	struct structs_data code;
  658: 	struct inner_struct s;
  659: 
  660: 	if (structs_xml_input(type, ELEM_TAG, NULL, NULL, stdin,
  661: 	    &s, STRUCTS_XML_UNINIT | flags, STRUCTS_LOGGER_STDERR) == -1) {
  662: 		warn("structs_xml_input");
  663: 		return (-1);
  664: 	}
  665: 	if (structs_get_binary(type, fname, &s, TYPED_MEM_TEMP, &code) == -1) {
  666: 		warn("structs_get_binary");
  667: 		structs_free(type, NULL, &s);
  668: 		return (-1);
  669: 	}
  670: 	if (fwrite(code.data, 1, code.length, stdout) != code.length) {
  671: 		warn("fwrite");
  672: 		FREE(TYPED_MEM_TEMP, code.data);
  673: 		structs_free(type, NULL, &s);
  674: 		return (-1);
  675: 	}
  676: 	FREE(TYPED_MEM_TEMP, code.data);
  677: 	structs_free(type, NULL, &s);
  678: 	return (0);
  679: }
  680: 
  681: static int
  682: structs_decode(const char *fname)
  683: {
  684: 	const struct structs_type *type = &inner_struct_type;
  685: 	struct structs_data code;
  686: 	struct inner_struct s;
  687: 	u_char buf[0x10000];
  688: 	char ebuf[128];
  689: 	int blen;
  690: 	int clen;
  691: 
  692: 	if (structs_init(type, NULL, &s) == -1) {
  693: 		warn("initializing inner_struct");
  694: 		return (-1);
  695: 	}
  696: 	if ((blen = fread(buf, 1, sizeof(buf), stdin)) == 0) {
  697: 		warn("reading input");
  698: 		structs_free(type, NULL, &s);
  699: 		return (-1);
  700: 	}
  701: 	code.data = buf;
  702: 	code.length = blen;
  703: 	if ((clen = structs_set_binary(type,
  704: 	    fname, &code, &s, ebuf, sizeof(ebuf))) == -1) {
  705: 		warnx("structs_set_binary: %s", ebuf);
  706: 		structs_free(type, NULL, &s);
  707: 		return (-1);
  708: 	}
  709: 	if (clen < blen) {
  710: 		fprintf(stderr, "WARNING: ignoring %d extra bytes\n",
  711: 		    blen - clen);
  712: 	}
  713: 	if (structs_xml_output(type,
  714: 	    ELEM_TAG, NULL, &s, stdout, NULL, 0) == -1) {
  715: 		warn("structs_xml_output");
  716: 		structs_free(type, NULL, &s);
  717: 		return (-1);
  718: 	}
  719: 	structs_free(type, NULL, &s);
  720: 	return (0);
  721: }
  722: 
  723: #ifndef NO_BPF
  724: static int
  725: bpf_compiler(const char *string, struct bpf_program *bpf,
  726: 	int linktype, char *ebuf, size_t emax)
  727: {
  728: 	pcap_t *pcap;
  729: 
  730: 	memset(bpf, 0, sizeof(*bpf));
  731: 	if ((pcap = pcap_open_dead(linktype, 2048)) == NULL)
  732: 		return (-1);
  733: 	if (pcap_compile(pcap, bpf, (char *)string, 1, ~0) != 0) {
  734: 		strlcpy(ebuf, pcap_geterr(pcap), emax);
  735: 		pcap_close(pcap);
  736: 		errno = EINVAL;
  737: 		return (-1);
  738: 	}
  739: 	pcap_close(pcap);
  740: 	return (0);
  741: }
  742: #endif
  743: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>