+
+ return;
+}
+
+
+__private_extern__
+void
+do_checkReachability(int argc, char **argv)
+{
+ SCNetworkReachabilityRef target;
+
+ target = _setupReachability(argc, argv, NULL);
+ if (target == NULL) {
+ SCPrint(TRUE, stderr, CFSTR(" Could not determine status: %s\n"), SCErrorString(SCError()));
+ exit(1);
+ }
+
+ _printReachability(target);
+ CFRelease(target);
+ exit(0);
+}
+
+
+static void
+callout(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void *info)
+{
+ static int n = 3;
+ struct tm tm_now;
+ struct timeval tv_now;
+
+ (void)gettimeofday(&tv_now, NULL);
+ (void)localtime_r(&tv_now.tv_sec, &tm_now);
+
+ SCPrint(TRUE, stdout, CFSTR("\n*** %2d:%02d:%02d.%03d\n\n"),
+ tm_now.tm_hour,
+ tm_now.tm_min,
+ tm_now.tm_sec,
+ tv_now.tv_usec / 1000);
+ SCPrint(TRUE, stdout, CFSTR("%2d: callback w/flags=0x%08x (info=\"%s\")\n"), n++, flags, (char *)info);
+ SCPrint(TRUE, stdout, CFSTR(" %@\n"), target);
+ _printReachability(target);
+ SCPrint(TRUE, stdout, CFSTR("\n"));
+ return;
+}
+
+
+__private_extern__
+void
+do_watchReachability(int argc, char **argv)
+{
+ SCNetworkReachabilityContext context = { 0, NULL, NULL, NULL, NULL };
+ SCNetworkReachabilityRef target;
+ SCNetworkReachabilityRef target_async;
+
+ target = _setupReachability(argc, argv, NULL);
+ if (target == NULL) {
+ SCPrint(TRUE, stderr, CFSTR(" Could not determine status: %s\n"), SCErrorString(SCError()));
+ exit(1);
+ }
+
+ target_async = _setupReachability(argc, argv, &context);
+ if (target_async == NULL) {
+ SCPrint(TRUE, stderr, CFSTR(" Could not determine status: %s\n"), SCErrorString(SCError()));
+ exit(1);
+ }
+
+ // Normally, we don't want to make any calls to SCNetworkReachabilityGetFlags()
+ // until after the "target" has been scheduled on a run loop. Otherwise, we'll
+ // end up making a synchronous DNS request and that's not what we want.
+ //
+ // But, to test the case were an application call SCNetworkReachabilityGetFlags()
+ // we provide the "CHECK_REACHABILITY_BEFORE_SCHEDULING" environment variable.
+ if (getenv("CHECK_REACHABILITY_BEFORE_SCHEDULING") != NULL) {
+ CFRelease(target_async);
+ target_async = CFRetain(target);
+ }
+
+ // Direct check of reachability
+ SCPrint(TRUE, stdout, CFSTR(" 0: direct\n"));
+ SCPrint(TRUE, stdout, CFSTR(" %@\n"), target);
+ _printReachability(target);
+ CFRelease(target);
+ SCPrint(TRUE, stdout, CFSTR("\n"));
+
+ // schedule the target
+ SCPrint(TRUE, stdout, CFSTR(" 1: start\n"));
+ SCPrint(TRUE, stdout, CFSTR(" %@\n"), target_async);
+ //_printReachability(target_async);
+ SCPrint(TRUE, stdout, CFSTR("\n"));
+
+ if (!SCNetworkReachabilitySetCallback(target_async, callout, &context)) {
+ printf("SCNetworkReachabilitySetCallback() failed: %s\n", SCErrorString(SCError()));
+ exit(1);
+ }
+
+#if !TARGET_OS_IPHONE
+ if (doDispatch) {
+ if (!SCNetworkReachabilitySetDispatchQueue(target_async, dispatch_get_current_queue())) {
+ printf("SCNetworkReachabilitySetDispatchQueue() failed: %s\n", SCErrorString(SCError()));
+ exit(1);
+ }
+ } else
+#endif // !TARGET_OS_IPHONE
+ {
+ if (!SCNetworkReachabilityScheduleWithRunLoop(target_async, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)) {
+ printf("SCNetworkReachabilityScheduleWithRunLoop() failed: %s\n", SCErrorString(SCError()));
+ exit(1);
+ }
+ }
+
+ // Note: now that we are scheduled on a run loop we can call SCNetworkReachabilityGetFlags()
+ // to get the current status. For "names", a DNS lookup has already been initiated.
+ SCPrint(TRUE, stdout, CFSTR(" 2: on %s\n"), doDispatch ? "dispatch queue" : "runloop");
+ SCPrint(TRUE, stdout, CFSTR(" %@\n"), target_async);
+ _printReachability(target_async);
+ SCPrint(TRUE, stdout, CFSTR("\n"));
+
+ CFRunLoopRun();