1/*
2 * Copyright (c) 2008-2012 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24/*
25 * type_to_data.c
26 * - convert from ip address, uint{8,16,32}, and string to xml data
27 */
28
29/*
30 * Modification History:
31 *
32 * March 17, 2008	Dieter Siegmund (dieter@apple.com)
33 * - initial revision
34 */
35#include <stdio.h>
36#include <stdlib.h>
37#include <stdint.h>
38#include <string.h>
39#include <sys/types.h>
40#include <sys/socket.h>
41#include <netinet/in.h>
42#include <arpa/inet.h>
43#include <CoreFoundation/CFData.h>
44#include <CoreFoundation/CFPropertyList.h>
45
46static void
47usage(const char * prog)
48{
49    fprintf(stderr,
50	    "usage: %s <type> <value1> [ <value2> ... [ <valueN> ] ... ]\n"
51	    "\t where <type> is one of ip, uint8, uint16, uint32, or string\n",
52	    prog);
53    exit(1);
54    return;
55}
56
57static void *
58data_from_ip(int argc, char * argv[], int * len)
59{
60    int			i;
61    struct in_addr *	ip_list;
62
63    *len = argc * sizeof(*ip_list);
64    ip_list = (struct in_addr *)malloc(*len);
65    for (i = 0; i < argc; i++) {
66	if (inet_aton(argv[i], ip_list + i) == 0) {
67	    fprintf(stderr, "invalid IP address '%s'\n",
68		    argv[i]);
69	    goto failed;
70	}
71    }
72    return (ip_list);
73 failed:
74    free(ip_list);
75    return (NULL);
76}
77
78static void *
79data_from_uint8(int argc, char * argv[], int * len)
80{
81    int		i;
82    uint8_t * 	list;
83
84    *len = argc * sizeof(*list);
85    list = (uint8_t *)malloc(*len);
86    for (i = 0; i < argc; i++) {
87	list[i] = (uint8_t)strtoul(argv[i], NULL, 0);
88    }
89    return (list);
90}
91
92static void *
93data_from_uint16(int argc, char * argv[], int * len)
94{
95    int		i;
96    uint16_t * 	list;
97
98    *len = argc * sizeof(*list);
99    list = (uint16_t *)malloc(*len);
100    for (i = 0; i < argc; i++) {
101	list[i] = htons((uint16_t)strtoul(argv[i], NULL, 0));
102    }
103    return (list);
104}
105
106static void *
107data_from_uint32(int argc, char * argv[], int * len)
108{
109    int		i;
110    uint32_t * 	list;
111
112    *len = argc * sizeof(*list);
113    list = (uint32_t *)malloc(*len);
114    for (i = 0; i < argc; i++) {
115	list[i] = htonl((uint32_t)strtoul(argv[i], NULL, 0));
116    }
117    return (list);
118}
119
120int
121main(int argc, char * argv[])
122{
123    const void *	data;
124    int			data_len;
125    CFDataRef		cfdata;
126    const char *	type;
127    CFDataRef		xml_data;
128
129    if (argc < 3) {
130	usage(argv[0]);
131    }
132    type = argv[1];
133    argv += 2;
134    argc -= 2;
135    if (strcmp(type, "ip") == 0) {
136	data = data_from_ip(argc, argv, &data_len);
137    }
138    else if (strcmp(type, "uint8") == 0) {
139	data = data_from_uint8(argc, argv, &data_len);
140    }
141    else if (strcmp(type, "uint16") == 0) {
142	data = data_from_uint16(argc, argv, &data_len);
143    }
144    else if (strcmp(type, "uint32") == 0) {
145	data = data_from_uint32(argc, argv, &data_len);
146    }
147    else if (strcmp(type, "string") == 0) {
148	data = argv[0];
149	data_len = strlen(data);
150    }
151    else {
152	fprintf(stderr, "unrecognized type '%s'\n", type);
153	exit(2);
154    }
155    if (data == NULL) {
156	exit(2);
157    }
158    cfdata = CFDataCreateWithBytesNoCopy(NULL, data, data_len,
159					 kCFAllocatorNull);
160    xml_data = CFPropertyListCreateXMLData(NULL, cfdata);
161    CFRelease(cfdata);
162    fwrite(CFDataGetBytePtr(xml_data), CFDataGetLength(xml_data), 1,
163	   stdout);
164    CFRelease(xml_data);
165    exit(0);
166    return (0);
167}
168