]> git.saurik.com Git - apple/configd.git/blob - scutil.tproj/tests.c
configd-84.1.tar.gz
[apple/configd.git] / scutil.tproj / tests.c
1 /*
2 * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25
26 /*
27 * Modification History
28 *
29 * July 9, 2001 Allan Nathanson <ajn@apple.com>
30 * - added "-r" option for checking network reachability
31 * - added "-w" option to check/wait for the presence of a
32 * dynamic store key.
33 *
34 * June 1, 2001 Allan Nathanson <ajn@apple.com>
35 * - public API conversion
36 *
37 * November 9, 2000 Allan Nathanson <ajn@apple.com>
38 * - initial revision
39 */
40
41 #include "scutil.h"
42 #include "tests.h"
43
44 #include <sys/time.h>
45 #include <net/if.h>
46 #include <netinet/in.h>
47 #include <arpa/inet.h>
48
49
50 void
51 do_checkReachability(int argc, char **argv)
52 {
53 SCNetworkConnectionFlags flags = 0;
54 SCNetworkReachabilityRef target = NULL;
55
56 if (argc == 1) {
57 struct sockaddr_in sin;
58 struct sockaddr_in6 sin6;
59
60 bzero(&sin, sizeof(sin));
61 sin.sin_len = sizeof(sin);
62 sin.sin_family = AF_INET;
63
64 bzero(&sin6, sizeof(sin6));
65 sin6.sin6_len = sizeof(sin6);
66 sin6.sin6_family = AF_INET6;
67
68 if (inet_aton(argv[0], &sin.sin_addr) == 1) {
69 target = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&sin);
70 } else if (inet_pton(AF_INET6, argv[0], &sin6.sin6_addr) == 1) {
71 char *p;
72
73 p = strchr(argv[0], '%');
74 if (p != NULL) {
75 sin6.sin6_scope_id = if_nametoindex(p+1);
76 }
77
78 target = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&sin6);
79 } else {
80 target = SCNetworkReachabilityCreateWithName(NULL, argv[0]);
81 }
82 } else /* if (argc == 2) */ {
83 struct sockaddr_in l_sin;
84 struct sockaddr_in r_sin;
85
86 bzero(&l_sin, sizeof(l_sin));
87 l_sin.sin_len = sizeof(l_sin);
88 l_sin.sin_family = AF_INET;
89 if (inet_aton(argv[0], &l_sin.sin_addr) == 0) {
90 SCPrint(TRUE, stderr, CFSTR("Could not interpret address \"%s\"\n"), argv[0]);
91 exit(1);
92 }
93
94 bzero(&r_sin, sizeof(r_sin));
95 r_sin.sin_len = sizeof(r_sin);
96 r_sin.sin_family = AF_INET;
97 if (inet_aton(argv[1], &r_sin.sin_addr) == 0) {
98 SCPrint(TRUE, stderr, CFSTR("Could not interpret address \"%s\"\n"), argv[1]);
99 exit(1);
100 }
101
102 target = SCNetworkReachabilityCreateWithAddressPair(NULL,
103 (struct sockaddr *)&l_sin,
104 (struct sockaddr *)&r_sin);
105 }
106
107 if (!target) {
108 SCPrint(TRUE, stderr, CFSTR(" Could not determine status: %s\n"), SCErrorString(SCError()));
109 exit(1);
110 }
111
112 if (!SCNetworkReachabilityGetFlags(target, &flags)) {
113 SCPrint(TRUE, stderr, CFSTR(" Could not determine status: %s\n"), SCErrorString(SCError()));
114 exit(1);
115 }
116
117 SCPrint(_sc_debug, stdout, CFSTR("flags = 0x%x"), flags);
118 if (flags != 0) {
119 SCPrint(_sc_debug, stdout, CFSTR(" ("));
120 if (flags & kSCNetworkFlagsReachable) {
121 SCPrint(TRUE, stdout, CFSTR("Reachable"));
122 flags &= ~kSCNetworkFlagsReachable;
123 SCPrint(flags != 0, stdout, CFSTR(","));
124 }
125 if (flags & kSCNetworkFlagsTransientConnection) {
126 SCPrint(TRUE, stdout, CFSTR("Transient Connection"));
127 flags &= ~kSCNetworkFlagsTransientConnection;
128 SCPrint(flags != 0, stdout, CFSTR(","));
129 }
130 if (flags & kSCNetworkFlagsConnectionRequired) {
131 SCPrint(TRUE, stdout, CFSTR("Connection Required"));
132 flags &= ~kSCNetworkFlagsConnectionRequired;
133 SCPrint(flags != 0, stdout, CFSTR(","));
134 }
135 if (flags & kSCNetworkFlagsConnectionAutomatic) {
136 SCPrint(TRUE, stdout, CFSTR("Connection Automatic"));
137 flags &= ~kSCNetworkFlagsConnectionAutomatic;
138 SCPrint(flags != 0, stdout, CFSTR(","));
139 }
140 if (flags & kSCNetworkFlagsInterventionRequired) {
141 SCPrint(TRUE, stdout, CFSTR("Intervention Required"));
142 flags &= ~kSCNetworkFlagsInterventionRequired;
143 SCPrint(flags != 0, stdout, CFSTR(","));
144 }
145 if (flags & kSCNetworkFlagsIsLocalAddress) {
146 SCPrint(TRUE, stdout, CFSTR("Local Address"));
147 flags &= ~kSCNetworkFlagsIsLocalAddress;
148 SCPrint(flags != 0, stdout, CFSTR(","));
149 }
150 if (flags & kSCNetworkFlagsIsDirect) {
151 SCPrint(TRUE, stdout, CFSTR("Directly Reachable Address"));
152 flags &= ~kSCNetworkFlagsIsDirect;
153 SCPrint(flags != 0, stdout, CFSTR(","));
154 }
155 SCPrint(_sc_debug, stdout, CFSTR(")"));
156 } else {
157 SCPrint(_sc_debug, stdout, CFSTR(" ("));
158 SCPrint(TRUE, stdout, CFSTR("Not Reachable"));
159 SCPrint(_sc_debug, stdout, CFSTR(")"));
160 }
161 SCPrint(TRUE, stdout, CFSTR("\n"));
162 exit(0);
163 }
164
165
166 void
167 do_snapshot(int argc, char **argv)
168 {
169 if (!SCDynamicStoreSnapshot(store)) {
170 SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError()));
171 }
172 return;
173 }
174
175
176 static void
177 waitKeyFound()
178 {
179 exit(0);
180 }
181
182
183 static void
184 waitTimeout(int sigraised)
185 {
186 exit(1);
187 }
188
189
190 void
191 do_wait(char *waitKey, int timeout)
192 {
193 struct itimerval itv;
194 CFStringRef key;
195 CFMutableArrayRef keys;
196
197 store = SCDynamicStoreCreate(NULL, CFSTR("scutil (wait)"), waitKeyFound, NULL);
198 if (!store) {
199 SCPrint(TRUE, stderr,
200 CFSTR("SCDynamicStoreCreate() failed: %s\n"), SCErrorString(SCError()));
201 exit(1);
202 }
203
204 keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
205 key = CFStringCreateWithCString(NULL, waitKey, kCFStringEncodingMacRoman);
206 CFArrayAppendValue(keys, key);
207
208 if (!SCDynamicStoreSetNotificationKeys(store, keys, NULL)) {
209 SCPrint(TRUE, stderr,
210 CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s\n"), SCErrorString(SCError()));
211 exit(1);
212 }
213
214 notifyRls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
215 if (!notifyRls) {
216 SCPrint(TRUE, stderr,
217 CFSTR("SCDynamicStoreCreateRunLoopSource() failed: %s\n"), SCErrorString(SCError()));
218 exit(1);
219 }
220
221 CFRunLoopAddSource(CFRunLoopGetCurrent(), notifyRls, kCFRunLoopDefaultMode);
222
223 value = SCDynamicStoreCopyValue(store, key);
224 if (value) {
225 /* if the key is already present */
226 exit(0);
227 }
228 CFRelease(key);
229
230 if (waitTimeout > 0) {
231 signal(SIGALRM, waitTimeout);
232 bzero(&itv, sizeof(itv));
233 itv.it_value.tv_sec = timeout;
234 if (setitimer(ITIMER_REAL, &itv, NULL) < 0) {
235 SCPrint(TRUE, stderr,
236 CFSTR("setitimer() failed: %s\n"), strerror(errno));
237 exit(1);
238 }
239 }
240
241 CFRunLoopRun();
242 }