1/*
2 * Copyright (c) 2000 Apple Computer, 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#include <stdio.h>
26#include <ctype.h>
27#include <stdlib.h>
28#include <string.h>
29#include <unistd.h>
30#include <signal.h>
31#include <errno.h>
32#include <fcntl.h>
33#include <syslog.h>
34#include <netdb.h>
35#include <paths.h>
36#include <sys/queue.h>
37
38#include <sys/param.h>
39#include <sys/types.h>
40#include <sys/wait.h>
41#include <sys/time.h>
42#include <sys/resource.h>
43#include <sys/stat.h>
44#include <sys/socket.h>
45#include <netinet/in.h>
46#include <arpa/inet.h>
47
48#include <CoreFoundation/CoreFoundation.h>
49
50#include "cf_utils.h"
51
52
53// ----------------------------------------------------------------------------
54// ----------------------------------------------------------------------------
55Boolean isDictionary (CFTypeRef obj)
56{
57    return (obj && CFGetTypeID(obj) == CFDictionaryGetTypeID());
58}
59
60Boolean isArray (CFTypeRef obj)
61{
62    return (obj && CFGetTypeID(obj) == CFArrayGetTypeID());
63}
64
65Boolean isString (CFTypeRef obj)
66{
67    return (obj && CFGetTypeID(obj) == CFStringGetTypeID());
68}
69
70Boolean isNumber (CFTypeRef obj)
71{
72    return (obj && CFGetTypeID(obj) == CFNumberGetTypeID());
73}
74
75Boolean isData (CFTypeRef obj)
76{
77    return (obj && CFGetTypeID(obj) == CFDataGetTypeID());
78}
79
80
81#define OPT_STR_LEN 256
82
83// ----------------------------------------------------------------------------
84//	get_array_option
85// ----------------------------------------------------------------------------
86int get_array_option(CFPropertyListRef options, CFStringRef entity, CFStringRef property, CFIndex index,
87            u_char *opt, u_int32_t optsiz, u_int32_t *outlen, u_char *defaultval)
88{
89    CFDictionaryRef	dict;
90    CFArrayRef		array;
91    CFIndex		count;
92    CFStringRef		string;
93
94    dict = CFDictionaryGetValue(options, entity);
95    if (isDictionary(dict)) {
96
97        array = CFDictionaryGetValue(dict, property);
98        if (isArray(array)
99            && (count = CFArrayGetCount(array)) > index) {
100            string = CFArrayGetValueAtIndex(array, index);
101            if (isString(string)) {
102                opt[0] = 0;
103                CFStringGetCString(string, (char*)opt, optsiz, kCFStringEncodingMacRoman);
104                *outlen = strlen((char*)opt);
105            }
106            return (count > (index + 1));
107        }
108    }
109
110    strlcpy((char*)opt, (char*)defaultval, optsiz);
111    *outlen = strlen((char*)opt);
112    return 0;
113}
114
115// ----------------------------------------------------------------------------
116//	get_str_option
117// ----------------------------------------------------------------------------
118void get_str_option (CFPropertyListRef options, CFStringRef entity, CFStringRef property,
119                        u_char *opt, u_int32_t optsiz, u_int32_t *outlen, u_char *defaultval)
120{
121    CFDictionaryRef	dict;
122    CFStringRef		ref;
123
124    dict = CFDictionaryGetValue(options, entity);
125    if (isDictionary(dict)) {
126        opt[0] = 0;
127        ref  = CFDictionaryGetValue(dict, property);
128        if (isString(ref)) {
129            CFStringGetCString(ref, (char*)opt, optsiz, kCFStringEncodingUTF8);
130            *outlen = strlen((char*)opt);
131            return;
132        }
133    }
134
135    strlcpy((char*)opt, (char*)defaultval, optsiz);
136    *outlen = strlen((char*)opt);
137}
138
139// ----------------------------------------------------------------------------
140//	get_cfstr_option
141// ----------------------------------------------------------------------------
142CFStringRef get_cfstr_option (CFPropertyListRef options, CFStringRef entity, CFStringRef property)
143{
144    CFDictionaryRef	dict;
145    CFStringRef		ref;
146
147    dict = CFDictionaryGetValue(options, entity);
148    if (isDictionary(dict)) {
149        ref  = CFDictionaryGetValue(dict, property);
150        if (isString(ref))
151            return ref;
152    }
153
154    return NULL;
155}
156
157// ----------------------------------------------------------------------------
158//	get_int_option
159// ----------------------------------------------------------------------------
160void get_int_option (CFPropertyListRef options, CFStringRef entity, CFStringRef property,
161        u_int32_t *opt, u_int32_t defaultval)
162{
163    CFDictionaryRef	dict;
164    CFNumberRef		ref;
165
166    dict = CFDictionaryGetValue(options, entity);
167    if (isDictionary(dict)) {
168        ref  = CFDictionaryGetValue(dict, property);
169        if (isNumber(ref)) {
170            CFNumberGetValue(ref, kCFNumberSInt32Type, opt);
171            return;
172        }
173    }
174
175    *opt = defaultval;
176}
177
178// ----------------------------------------------------------------------------
179//	GetIntFromDict
180// ----------------------------------------------------------------------------
181Boolean GetIntFromDict (CFDictionaryRef dict, CFStringRef property, u_int32_t *outval, u_int32_t defaultval)
182{
183    CFNumberRef		ref;
184
185	ref  = CFDictionaryGetValue(dict, property);
186	if (isNumber(ref)
187		&&  CFNumberGetValue(ref, kCFNumberSInt32Type, outval))
188		return TRUE;
189
190	*outval = defaultval;
191	return FALSE;
192}
193
194// ----------------------------------------------------------------------------
195//	GetStrFromDict
196// ----------------------------------------------------------------------------
197int GetStrFromDict (CFDictionaryRef dict, CFStringRef property, char *outstr, int maxlen, char *defaultval)
198{
199    CFStringRef		ref;
200
201	ref  = CFDictionaryGetValue(dict, property);
202	if (!isString(ref)
203		|| !CFStringGetCString(ref, outstr, maxlen, kCFStringEncodingUTF8))
204		strncpy(outstr, defaultval, maxlen);
205
206	return strlen(outstr);
207}
208
209// ----------------------------------------------------------------------------
210//	GetStrAddrFromDict
211// ----------------------------------------------------------------------------
212Boolean GetStrAddrFromDict (CFDictionaryRef dict, CFStringRef property, char *outstr, int maxlen)
213{
214    CFStringRef		ref;
215	in_addr_t               addr;
216
217	ref  = CFDictionaryGetValue(dict, property);
218	if (isString(ref)
219			&& CFStringGetCString(ref, outstr, maxlen, kCFStringEncodingUTF8)) {
220					addr = inet_addr(outstr);
221					return addr != INADDR_NONE;
222	}
223
224	return FALSE;
225}
226
227// ----------------------------------------------------------------------------
228//	GetStrNetFromDict
229// ----------------------------------------------------------------------------
230Boolean GetStrNetFromDict (CFDictionaryRef dict, CFStringRef property, char *outstr, int maxlen)
231{
232    CFStringRef		ref;
233	in_addr_t               net;
234
235	ref  = CFDictionaryGetValue(dict, property);
236	if (isString(ref)
237			&& CFStringGetCString(ref, outstr, maxlen, kCFStringEncodingUTF8)) {
238			net = inet_network(outstr);
239			return net != INADDR_NONE && net != 0;
240	}
241
242	return FALSE;
243}
244