]>
Commit | Line | Data |
---|---|---|
5958d7c0 A |
1 | /* |
2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * The contents of this file constitute Original Code as defined in and | |
7 | * are subject to the Apple Public Source License Version 1.1 (the | |
8 | * "License"). You may not use this file except in compliance with the | |
9 | * License. Please obtain a copy of the License at | |
10 | * http://www.apple.com/publicsource and read it before using this file. | |
11 | * | |
12 | * This Original Code and all software distributed under the License are | |
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | |
17 | * License for the specific language governing rights and limitations | |
18 | * under the License. | |
19 | * | |
20 | * @APPLE_LICENSE_HEADER_END@ | |
21 | */ | |
22 | ||
0fae82ee A |
23 | /* |
24 | * Modification History | |
25 | * | |
26 | * July 9, 2001 Allan Nathanson <ajn@apple.com> | |
27 | * - added "-r" option for checking network reachability | |
28 | * - added "-w" option to check/wait for the presence of a | |
29 | * dynamic store key. | |
30 | * | |
31 | * June 1, 2001 Allan Nathanson <ajn@apple.com> | |
32 | * - public API conversion | |
33 | * | |
34 | * November 9, 2000 Allan Nathanson <ajn@apple.com> | |
35 | * - initial revision | |
36 | */ | |
37 | ||
5958d7c0 | 38 | #include "scutil.h" |
0fae82ee A |
39 | |
40 | #include <SystemConfiguration/SCPrivate.h> | |
41 | #include <sys/time.h> | |
42 | #include <netinet/in.h> | |
43 | #include <arpa/inet.h> | |
44 | ||
5958d7c0 A |
45 | |
46 | void | |
0fae82ee | 47 | do_checkReachability(char *node) |
5958d7c0 | 48 | { |
0fae82ee A |
49 | SCNetworkConnectionFlags flags = 0; |
50 | Boolean ok = FALSE; | |
51 | ||
52 | if (isdigit(node[0])) { | |
53 | struct sockaddr_in sin; | |
54 | ||
55 | bzero(&sin, sizeof(sin)); | |
56 | sin.sin_len = sizeof(sin); | |
57 | sin.sin_family = AF_INET; | |
58 | sin.sin_addr.s_addr = inet_addr(node); | |
59 | if (inet_aton(node, &sin.sin_addr) == 0) { | |
60 | SCPrint(TRUE, stderr, CFSTR("Could not interpret address \"%s\"\n"), node); | |
61 | exit(1); | |
62 | } | |
63 | ok = SCNetworkCheckReachabilityByAddress((struct sockaddr *)&sin, | |
64 | sizeof(sin), | |
65 | &flags); | |
66 | ||
67 | } else { | |
68 | ok = SCNetworkCheckReachabilityByName(node, | |
69 | &flags); | |
70 | } | |
71 | ||
72 | if (!ok) { | |
73 | SCPrint(TRUE, stderr, CFSTR(" Could not determine status: %s\n"), SCErrorString(SCError())); | |
74 | exit(1); | |
75 | } | |
76 | ||
77 | SCPrint(_sc_debug, stdout, CFSTR("flags = 0x%x"), flags); | |
78 | if (flags != 0) { | |
79 | SCPrint(_sc_debug, stdout, CFSTR(" (")); | |
80 | if (flags & kSCNetworkFlagsReachable) { | |
81 | SCPrint(TRUE, stdout, CFSTR("Reachable")); | |
82 | flags &= ~kSCNetworkFlagsReachable; | |
83 | SCPrint(flags != 0, stdout, CFSTR(",")); | |
84 | } | |
85 | if (flags & kSCNetworkFlagsTransientConnection) { | |
86 | SCPrint(TRUE, stdout, CFSTR("Transient Connection")); | |
87 | flags &= ~kSCNetworkFlagsTransientConnection; | |
88 | SCPrint(flags != 0, stdout, CFSTR(",")); | |
89 | } | |
90 | if (flags & kSCNetworkFlagsConnectionRequired) { | |
91 | SCPrint(TRUE, stdout, CFSTR("Connection Required")); | |
92 | flags &= ~kSCNetworkFlagsConnectionRequired; | |
93 | SCPrint(flags != 0, stdout, CFSTR(",")); | |
94 | } | |
95 | if (flags & kSCNetworkFlagsConnectionAutomatic) { | |
96 | SCPrint(TRUE, stdout, CFSTR("Connection Automatic")); | |
97 | flags &= ~kSCNetworkFlagsConnectionAutomatic; | |
98 | SCPrint(flags != 0, stdout, CFSTR(",")); | |
99 | } | |
100 | if (flags & kSCNetworkFlagsInterventionRequired) { | |
101 | SCPrint(TRUE, stdout, CFSTR("Intervention Required")); | |
102 | flags &= ~kSCNetworkFlagsInterventionRequired; | |
103 | SCPrint(flags != 0, stdout, CFSTR(",")); | |
104 | } | |
105 | SCPrint(_sc_debug, stdout, CFSTR(")")); | |
106 | } else { | |
107 | SCPrint(_sc_debug, stdout, CFSTR(" (")); | |
108 | SCPrint(TRUE, stdout, CFSTR("Not Reachable")); | |
109 | SCPrint(_sc_debug, stdout, CFSTR(")")); | |
110 | } | |
111 | SCPrint(TRUE, stdout, CFSTR("\n")); | |
112 | exit(0); | |
113 | } | |
5958d7c0 | 114 | |
0fae82ee A |
115 | |
116 | void | |
117 | do_snapshot(int argc, char **argv) | |
118 | { | |
119 | if (!SCDynamicStoreSnapshot(store)) { | |
120 | SCPrint(TRUE, stdout, CFSTR(" %s\n"), SCErrorString(SCError())); | |
5958d7c0 A |
121 | } |
122 | return; | |
123 | } | |
124 | ||
125 | ||
0fae82ee A |
126 | static void |
127 | waitKeyFound() | |
128 | { | |
129 | exit(0); | |
130 | } | |
131 | ||
132 | ||
133 | static void | |
134 | waitTimeout(int sigraised) | |
135 | { | |
136 | exit(1); | |
137 | } | |
138 | ||
5958d7c0 A |
139 | |
140 | void | |
0fae82ee | 141 | do_wait(char *waitKey, int timeout) |
5958d7c0 | 142 | { |
0fae82ee A |
143 | struct itimerval itv; |
144 | CFStringRef key; | |
145 | CFMutableArrayRef keys; | |
5958d7c0 | 146 | |
0fae82ee A |
147 | store = SCDynamicStoreCreate(NULL, CFSTR("scutil (wait)"), waitKeyFound, NULL); |
148 | if (!store) { | |
149 | SCPrint(TRUE, stderr, | |
150 | CFSTR("SCDynamicStoreCreate() failed: %s\n"), SCErrorString(SCError())); | |
151 | exit(1); | |
5958d7c0 A |
152 | } |
153 | ||
0fae82ee A |
154 | keys = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); |
155 | key = CFStringCreateWithCString(NULL, waitKey, kCFStringEncodingMacRoman); | |
156 | CFArrayAppendValue(keys, key); | |
5958d7c0 | 157 | |
0fae82ee A |
158 | if (!SCDynamicStoreSetNotificationKeys(store, keys, NULL)) { |
159 | SCPrint(TRUE, stderr, | |
160 | CFSTR("SCDynamicStoreSetNotificationKeys() failed: %s\n"), SCErrorString(SCError())); | |
161 | exit(1); | |
162 | } | |
5958d7c0 | 163 | |
0fae82ee A |
164 | notifyRls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0); |
165 | if (!notifyRls) { | |
166 | SCPrint(TRUE, stderr, | |
167 | CFSTR("SCDynamicStoreCreateRunLoopSource() failed: %s\n"), SCErrorString(SCError())); | |
168 | exit(1); | |
5958d7c0 A |
169 | } |
170 | ||
0fae82ee A |
171 | CFRunLoopAddSource(CFRunLoopGetCurrent(), notifyRls, kCFRunLoopDefaultMode); |
172 | ||
173 | value = SCDynamicStoreCopyValue(store, key); | |
174 | if (value) { | |
175 | /* if the key is already present */ | |
176 | exit(0); | |
5958d7c0 | 177 | } |
0fae82ee A |
178 | CFRelease(key); |
179 | ||
180 | if (waitTimeout > 0) { | |
181 | signal(SIGALRM, waitTimeout); | |
182 | bzero(&itv, sizeof(itv)); | |
183 | itv.it_value.tv_sec = timeout; | |
184 | if (setitimer(ITIMER_REAL, &itv, NULL) < 0) { | |
185 | SCPrint(TRUE, stderr, | |
186 | CFSTR("setitimer() failed: %s\n"), strerror(errno)); | |
187 | exit(1); | |
5958d7c0 A |
188 | } |
189 | } | |
190 | ||
0fae82ee | 191 | CFRunLoopRun(); |
5958d7c0 | 192 | } |