示例#1
0
struct MacGSocketData* _GSocket_Get_Mac_Socket(GSocket *socket)
{
  /* If socket is already created, returns a pointer to the data */
  /* Otherwise, creates socket and returns the pointer */
  CFSocketContext cont;
  struct MacGSocketData* data = (struct MacGSocketData*)socket->m_gui_dependent;

  if (data && data->source) return data;

  /* CFSocket has not been created, create it: */
  if (socket->m_fd < 0 || !data) return NULL;
  cont.version = 0; cont.retain = NULL;
  cont.release = NULL; cont.copyDescription = NULL;
  cont.info = socket;

  CFSocketRef cf = CFSocketCreateWithNative(NULL, socket->m_fd,
  			ALL_CALLBACK_TYPES, Mac_Socket_Callback, &cont);
  CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(NULL, cf, 0);
  assert(source);
  socket->m_gui_dependent = (char*)data;

  /* Keep the source and the socket around. */
  data->source = source;
  data->socket = cf;

  return data;
}
示例#2
0
static int _cf_runloop_clear_write( void * info, int fd ) {
  struct CFMIDIRunloop * runloop = info;
  CFSocketRef socket;
  MIDIAssert( runloop != NULL );

  socket = CFSocketCreateWithNative( NULL, fd, kCFSocketWriteCallBack, &_cf_socket_callback, &(runloop->socket_context) );
  CFSocketDisableCallBacks( socket, kCFSocketWriteCallBack );
  CFRelease( socket );
  return 0;
}
示例#3
0
int
browse(void)
{
	DNSServiceErrorType err;
	CFSocketContext ctx = { 0, NULL, NULL, NULL, NULL };

	err = DNSServiceBrowse(&nfsinfo.sdref, 0, 0, "_nfs._tcp", NULL, browser_callback, NULL);
	if (err != kDNSServiceErr_NoError)
		return (1);
	ctx.info = (void*)&nfsinfo;
	nfsinfo.sockref = CFSocketCreateWithNative(kCFAllocatorDefault, DNSServiceRefSockFD(nfsinfo.sdref),
			kCFSocketReadCallBack, socket_callback, &ctx);
	if (!nfsinfo.sockref)
		return (1);
	nfsinfo.rls = CFSocketCreateRunLoopSource(kCFAllocatorDefault, nfsinfo.sockref, 1);
	CFRunLoopAddSource(CFRunLoopGetCurrent(), nfsinfo.rls, kCFRunLoopDefaultMode);

	/* For backwards compatibility, browse for "mountd" services too */
	err = DNSServiceBrowse(&mountdinfo.sdref, 0, 0, "_mountd._tcp", NULL, browser_callback, NULL);
	if (err != kDNSServiceErr_NoError)
		return (1);
	ctx.info = (void*)&mountdinfo;
	mountdinfo.sockref = CFSocketCreateWithNative(kCFAllocatorDefault, DNSServiceRefSockFD(mountdinfo.sdref),
			kCFSocketReadCallBack, socket_callback, &ctx);
	if (!mountdinfo.sockref)
		return (1);
	mountdinfo.rls = CFSocketCreateRunLoopSource(kCFAllocatorDefault, mountdinfo.sockref, 1);
	CFRunLoopAddSource(CFRunLoopGetCurrent(), mountdinfo.rls, kCFRunLoopDefaultMode);

	CFRunLoopRun();

	CFRelease(nfsinfo.rls);
	CFSocketInvalidate(nfsinfo.sockref);
	CFRelease(nfsinfo.sockref);
	DNSServiceRefDeallocate(nfsinfo.sdref);
	CFRelease(mountdinfo.rls);
	CFSocketInvalidate(mountdinfo.sockref);
	CFRelease(mountdinfo.sockref);
	DNSServiceRefDeallocate(mountdinfo.sdref);
	return (0);
}
示例#4
0
struct CFMIDIRunLoopSource * CFMIDIRunLoopSourceCreate( struct MIDIRunloopSource * source ) {
  int i, create;
  CFRunLoopTimerContext timer_context;
  CFSocketContext       socket_context;
  CFOptionFlags         socket_cb_types;
  CFSocketRef           socket;
  struct CFMIDIRunLoopSource * cf = malloc( sizeof(struct CFMIDIRunLoopSource)
                                          + sizeof(CFRunLoopSourceRef)*(source->nfds-1) );
  MIDIPrecondReturn( cf != NULL, ENOMEM, NULL );
  
  timer_context.version = 0;
  timer_context.info = source;
  timer_context.release = NULL;
  timer_context.retain  = NULL;
  timer_context.copyDescription = NULL;

  socket_context.version = 0;
  socket_context.info = source;
  socket_context.release = NULL;
  socket_context.retain  = NULL;
  socket_context.copyDescription = NULL;
  
  cf->length = source->nfds;

  if( source->timeout.tv_sec > 0 || source->timeout.tv_nsec > 0 ) {
    cf->cfrlt = CFRunLoopTimerCreate( NULL, CFAbsoluteTimeGetCurrent(),
      (double) source->timeout.tv_sec + 0.000000001 * (double) source->timeout.tv_nsec,
      0, 1, &_cf_timer_callback, &timer_context );
  } else {
    cf->cfrlt = NULL;
  }

  for( i=0; i<cf->length; i++ ) {
    create = 0;
    socket_cb_types = kCFSocketNoCallBack;
    if( FD_ISSET(i, &(source->readfds)) ) {
      socket_cb_types |= kCFSocketReadCallBack;
      create = 1;
    }
    if( FD_ISSET(i, &(source->writefds)) ) {
      socket_cb_types |= kCFSocketWriteCallBack;
      create = 1;
    }
    if( create ) {
      socket       = CFSocketCreateWithNative( NULL, i, socket_cb_types, &_cf_socket_callback, &socket_context );
      cf->cfrls[i] = CFSocketCreateRunLoopSource( NULL, socket, 1 );
      CFRelease( socket );
    } else {
      cf->cfrls[i] = NULL;
    }
  }
  return cf;
}
示例#5
0
/*
 * Handle newly-discovered services
 */
static void
browser_callback(
	__unused DNSServiceRef sdRef,
	DNSServiceFlags servFlags,
	uint32_t interfaceIndex,
	DNSServiceErrorType errorCode,
	const char *serviceName,
	const char *regType,
	const char *replyDomain,
	__unused void *context)
{
	DNSServiceErrorType err;
	CFSocketContext ctx = { 0, NULL, NULL, NULL, NULL };
	struct cbinfo *info;

        if (errorCode != kDNSServiceErr_NoError) {
		printf("DNS service discovery error: %d\n", errorCode);
		return;
	}
#ifdef DEBUG
	printf("browse: %s: %s, %s, %s\n",
		(servFlags & kDNSServiceFlagsAdd) ? "new" : "gone",
		serviceName, regType, replyDomain);
#endif
	if (!(servFlags & kDNSServiceFlagsAdd))
		return;

	info = malloc(sizeof(*info));
	if (!info) {
		printf("browse: out of memeory\n");
		return;
	}

	err = DNSServiceResolve(&info->sdref, servFlags, interfaceIndex, serviceName, regType, replyDomain, resolve_callback, info);
	if (err != kDNSServiceErr_NoError) {
		printf("DNSServiceResolve failed: %d\n", err);
		free(info);
		return;
	}
	ctx.info = (void*)info;
	info->sockref = CFSocketCreateWithNative(kCFAllocatorDefault, DNSServiceRefSockFD(info->sdref),
				kCFSocketReadCallBack, socket_callback, &ctx);
	if (!info->sockref) {
		printf("CFSocketCreateWithNative failed\n");
		DNSServiceRefDeallocate(info->sdref);
		free(info);
		return;
	}
	info->rls = CFSocketCreateRunLoopSource(kCFAllocatorDefault, info->sockref, 1);
	CFRunLoopAddSource(CFRunLoopGetCurrent(), info->rls, kCFRunLoopDefaultMode);
}
示例#6
0
static void OnAccept(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *value, void *info) {
    switch (type) {
        case kCFSocketAcceptCallBack:
            Client *client(new Client());

            client->message_ = NULL;

            CFSocketContext context;
            context.version = 0;
            context.info = client;
            context.retain = NULL;
            context.release = NULL;
            context.copyDescription = NULL;

            client->socket_ = CFSocketCreateWithNative(kCFAllocatorDefault, *reinterpret_cast<const CFSocketNativeHandle *>(value), kCFSocketDataCallBack, &OnData, &context);

            CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(kCFAllocatorDefault, client->socket_, 0), kCFRunLoopDefaultMode);
        break;
    }
}
/*!
    Implements the GUI-specific AddProcessCallback() for both wxMac and
    wxCocoa using the CFSocket/CFRunLoop API which is available to both.
    Takes advantage of the fact that sockets on UNIX are just regular
    file descriptors and thus even a non-socket file descriptor can
    apparently be used with CFSocket so long as you only tell CFSocket
    to do things with it that would be valid for a non-socket fd.
 */
int wxGUIAppTraits::AddProcessCallback(wxEndProcessData *proc_data, int fd)
{
    static int s_last_tag = 0;
    CFSocketContext context =
    {   0
    ,   static_cast<void*>(proc_data)
    ,   NULL
    ,   NULL
    ,   NULL
    };
    CFSocketRef cfSocket = CFSocketCreateWithNative(kCFAllocatorDefault,fd,kCFSocketReadCallBack,&WXCF_EndProcessDetector,&context);
    if(cfSocket == NULL)
    {
        wxLogError(wxT("Failed to create socket for end process detection"));
        return 0;
    }
    CFRunLoopSourceRef runLoopSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, cfSocket, /*highest priority:*/0);
    if(runLoopSource == NULL)
    {
        wxLogError(wxT("Failed to create CFRunLoopSource from CFSocket for end process detection"));
        // closes the fd.. we can't really stop it, nor do we necessarily want to.
        CFSocketInvalidate(cfSocket);
        CFRelease(cfSocket);
        return 0;
    }
    // Now that the run loop source has the socket retained and we no longer
    // need to refer to it within this method, we can release it.
    CFRelease(cfSocket);

    CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
    // Now that the run loop has the source retained we can release it.
    CFRelease(runLoopSource);

    /*
        Feed wx some bullshit.. we don't use it since CFSocket helpfully passes
        itself into our callback and that's enough to be able to
        CFSocketInvalidate it which is all we need to do to get everything we
        just created to be deallocated.
     */
    return ++s_last_tag;
}
示例#8
0
unsigned int
xmmsc_mainloop_cf_init (xmmsc_connection_t *c, CFRunLoopSourceRef *source)
{

	CFRunLoopRef runLoopRef = CFRunLoopGetCurrent ();
	CFRunLoopSourceRef runLoopSourceRef;
	CFSocketContext context;
	CFSocketRef sockRef;
	CFOptionFlags flags;

	context.version = 0;
	context.info = c;
	context.retain = NULL;
	context.release = NULL;
	context.copyDescription = NULL;

	flags = kCFSocketReadCallBack;
	if (xmmsc_io_want_out (c))
		flags |= kCFSocketWriteCallBack;

	sockRef = CFSocketCreateWithNative (kCFAllocatorDefault,
	                                    xmmsc_io_fd_get (c),
	                                    flags,
	                                    &xmmsc_io_cf_event_callback,
	                                    &context);

	if (!sockRef)
		return 0;


	runLoopSourceRef = CFSocketCreateRunLoopSource (kCFAllocatorDefault,
	                                                sockRef, XMMSC_CF_SOURCE_PRIORITY);

	CFRunLoopAddSource (runLoopRef, runLoopSourceRef, kCFRunLoopDefaultMode);


	xmmsc_io_need_out_callback_set (c, xmmsc_io_cf_toggle_socket_flags, sockRef);
	*source = runLoopSourceRef;

	return 1;
}
示例#9
0
FskErr KprZeroconfPlatformServiceNew(KprZeroconfPlatformService* it, KprZeroconfPlatformService owner, DNSServiceRef serviceRef, const char* name, UInt32 port)
{
	FskErr err = kFskErrNone;
	KprZeroconfPlatformService self = NULL;
	SInt32 fd = DNSServiceRefSockFD(serviceRef);
	bailIfError(FskMemPtrNewClear(sizeof(KprZeroconfPlatformServiceRecord), &self));
	FskInstrumentedItemNew(self, NULL, &KprZeroconfPlatformServiceInstrumentation);
	self->owner = owner;
	self->serviceRef = serviceRef;
	if (name) {
		self->name = FskStrDoCopy(name);
		bailIfNULL(self->name);
	}
	self->port = port;
#if KPR_ZEROCONF_EMBEDDED
	if (!gEmbeddedServiceCount) {
		FskTimeCallbackNew(&gEmbeddedServiceTimer);
		FskTimeCallbackScheduleFuture(gEmbeddedServiceTimer, 0, 0, KprZeroconfEmbeddedCallback, NULL);
	}
	gEmbeddedServiceCount++;
#elif TARGET_OS_MAC
	CFSocketContext context;
	FskMemSet(&context, 0, sizeof(context));
	context.info = (void*)serviceRef;
	self->socket = CFSocketCreateWithNative(kCFAllocatorDefault, fd, kCFSocketReadCallBack, KprZeroconfPlatformCallBack, &context);
	self->source = CFSocketCreateRunLoopSource(NULL, self->socket, 0);
	CFRunLoopAddSource(CFRunLoopGetCurrent(), self->source, kCFRunLoopCommonModes);
#else
	self->source = FskThreadCreateDataSource(fd);
	FskSocketActivate(self->source, true);
	FskThreadAddDataHandler(&self->handler, self->source, KprZeroconfPlatformCallBack, true, false, serviceRef);
#endif
	*it = self;
	return err;
bail:
	if (err) {
		KprZeroconfPlatformServiceDispose(self);
	}
	return err;
}
示例#10
0
static int _cf_source_schedule( struct MIDIRunloopSource * source, int event ) {
  int i, created;
  struct CFMIDIRunLoopSource * cf = source->scheduler;
  CFSocketContext socket_context;
  CFOptionFlags   socket_cb_types = kCFSocketNoCallBack;
  CFSocketRef     socket;

  if( event & MIDI_RUNLOOP_READ )  socket_cb_types |= kCFSocketReadCallBack;
  if( event & MIDI_RUNLOOP_WRITE ) socket_cb_types |= kCFSocketWriteCallBack;

  socket_context.version = 0;
  socket_context.info = source;
  socket_context.release = NULL;
  socket_context.retain  = NULL;
  socket_context.copyDescription = NULL;

  for( i=0; i<source->nfds; i++ ) {
    created = 0;
    if( FD_ISSET(i, &(source->readfds)) ) {
      created = 1;
    }
    if( FD_ISSET(i, &(source->writefds)) ) {
      created = 1;
    }
    if( created ) {
      socket = CFSocketCreateWithNative( NULL, i, socket_cb_types, &_cf_socket_callback, &socket_context );
      if( event & MIDI_RUNLOOP_INVALIDATE ) {
        CFSocketInvalidate( socket );
      } else if( socket_cb_types != kCFSocketNoCallBack ) {
        CFSocketEnableCallBacks( socket, socket_cb_types );
      }
      CFRelease( socket );
    }
  }
  return 0;
}
static void
MyDNSServiceAddToRunLoop(MyDNSServiceState *ref)
{
    CFSocketNativeHandle    sock;
    CFOptionFlags           sockFlags;
    CFRunLoopSourceRef      source;
    CFSocketContext         context = { 0, ref, NULL, NULL, NULL };  // Use MyDNSServiceState as context data.

    assert(ref);

    // Access the underlying Unix domain socket to communicate with the mDNSResponder daemon.
    sock = DNSServiceRefSockFD(ref->service);
    assert(sock >= 0);

    // Create a CFSocket using the Unix domain socket.
    ref->socket = CFSocketCreateWithNative(NULL, sock, kCFSocketReadCallBack, MyDNSServiceSocketCallBack, &context);
    assert(ref->socket);

    // Prevent CFSocketInvalidate from closing DNSServiceRef's socket.
    sockFlags = CFSocketGetSocketFlags(ref->socket);
    CFSocketSetSocketFlags(ref->socket, sockFlags & (~kCFSocketCloseOnInvalidate));

    // Create a CFRunLoopSource from the CFSocket.
    source = CFSocketCreateRunLoopSource(NULL, ref->socket, 0);
    assert(source);

    // Add the CFRunLoopSource to the current runloop.
    CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes);
    
    // We no longer need our reference to source.  The runloop continues to 
    // hold a reference to it, but we don't care about that.  When we invalidate 
    // the socket, the runloop will drop its reference and the source will get 
    // destroyed.
    
    CFRelease(source);
}
int tnet_transport_wrap(tnet_transport_t *transport, int index) {
    transport_context_t *context = transport->context;
    transport_socket_t *sock = context->sockets[index];
    
    // If the socket is already wrapped in a CFSocket then return.
    if (sock->cf_socket || sock->cf_read_stream) {
        return 1;
    }
    
    // Put a reference to the transport context 
    const CFSocketContext socket_context = { 0, transport, NULL, NULL, NULL };
    
    if (TNET_SOCKET_TYPE_IS_DGRAM(sock->type)) {
        
        // Create a CFSocket from the native socket and register for Read events
        sock->cf_socket = CFSocketCreateWithNative(kCFAllocatorDefault, 
                                                   sock->fd,
                                                   kCFSocketReadCallBack, 
                                                   &__CFSocketCallBack, 
                                                   &socket_context);
        
        // Don't close the socket if the CFSocket is invalidated
        CFOptionFlags flags = CFSocketGetSocketFlags(sock->cf_socket);
        flags = flags & ~kCFSocketCloseOnInvalidate;
        CFSocketSetSocketFlags(sock->cf_socket, flags);
		
        
        // Create a new RunLoopSource and register it with the main thread RunLoop
        sock->cf_run_loop_source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, sock->cf_socket, 0);
        CFRunLoopAddSource(context->cf_run_loop, sock->cf_run_loop_source, kCFRunLoopDefaultMode);
        CFRelease(sock->cf_run_loop_source);
        
    } else if (TNET_SOCKET_TYPE_IS_STREAM(sock->type)) {
        
        // Create a pair of streams (read/write) from the socket
        CFStreamCreatePairWithSocket(kCFAllocatorDefault, sock->fd, &sock->cf_read_stream, &sock->cf_write_stream);
        
        // Don't close underlying socket
        CFReadStreamSetProperty(sock->cf_read_stream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanFalse);
        CFWriteStreamSetProperty(sock->cf_write_stream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanFalse);
        
        if (TNET_SOCKET_TYPE_IS_SECURE(sock->type)) {
            CFMutableDictionaryRef settings = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
            CFDictionaryAddValue(settings, kCFStreamSSLAllowsExpiredCertificates, kCFBooleanTrue);
            CFDictionaryAddValue(settings, kCFStreamSSLAllowsAnyRoot, kCFBooleanTrue);
            CFDictionaryAddValue(settings, kCFStreamSSLValidatesCertificateChain, kCFBooleanFalse);
            CFDictionaryAddValue(settings, kCFStreamSSLPeerName, kCFNull);
            
            // Set the SSL settings
            CFReadStreamSetProperty(sock->cf_read_stream, kCFStreamPropertySocketSecurityLevel, kCFStreamSocketSecurityLevelNegotiatedSSL);
            CFReadStreamSetProperty(sock->cf_read_stream, kCFStreamPropertySSLSettings, settings);
            CFWriteStreamSetProperty(sock->cf_write_stream, kCFStreamPropertySocketSecurityLevel, kCFStreamSocketSecurityLevelNegotiatedSSL);
            CFWriteStreamSetProperty(sock->cf_write_stream, kCFStreamPropertySSLSettings, settings);
            
            CFRelease(settings);
        }
        
#if __IPHONE_4_0
        // Mark the stream for VoIP usage
        CFReadStreamSetProperty(sock->cf_read_stream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
        CFWriteStreamSetProperty(sock->cf_write_stream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
#endif
        
        // Setup a context for the streams
        CFStreamClientContext streamContext = { 0, transport, NULL, NULL, NULL };
        
        // Set the client callback for the stream
        CFReadStreamSetClient(sock->cf_read_stream, 
                              kCFStreamEventOpenCompleted | kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered,
                              &__CFReadStreamClientCallBack, 
                              &streamContext);
        CFWriteStreamSetClient(sock->cf_write_stream, 
                               kCFStreamEventOpenCompleted | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, 
                               &__CFWriteStreamClientCallBack, 
                               &streamContext);
        
        // Enroll streams in the run-loop
        CFReadStreamScheduleWithRunLoop(sock->cf_read_stream, context->cf_run_loop, kCFRunLoopDefaultMode);
        CFWriteStreamScheduleWithRunLoop(sock->cf_write_stream, context->cf_run_loop, kCFRunLoopDefaultMode);
        
        // Release references
        CFRelease(sock->cf_read_stream);
        CFRelease(sock->cf_write_stream);
        
        CFReadStreamOpen(sock->cf_read_stream);
        CFWriteStreamOpen(sock->cf_write_stream);
    }
    
    return 0;
}
示例#13
0
/*------------------------------------ udpPortSetPort ---*/
bool
udpPortSetPort(UdpObjectData * xx,
               const bool      bangOnError)
{
    bool okSoFar = true;

    if (xx)
    {
        if (xx->fSocket)
        {
            CFSocketInvalidate(xx->fSocket);
            CFRelease(xx->fSocket);
            xx->fSocket = NULL;
        }
        int err;
        int sock = socket(AF_INET, SOCK_DGRAM, 0);

        if (0 > sock)
        {
            err = errno;
            okSoFar = false;
        }
        else
        {
            err = 0;
        }
        if (okSoFar)
        {
            sockaddr_in addr;

            memset(&addr, 0, sizeof(addr));
            addr.sin_len = sizeof(addr);
            addr.sin_family = AF_INET;
            addr.sin_port = htons(xx->fSelfPort);
            addr.sin_addr.s_addr = INADDR_ANY;
            err = bind(sock, reinterpret_cast<sockaddr *>(&addr), sizeof(addr));
            if (0 > err)
            {
                err = errno;
                okSoFar = false;
            }
        }
        if (okSoFar)
        {
            int flags = fcntl(sock, F_GETFL);

            err = fcntl(sock, F_SETFL, flags | O_NONBLOCK);
            if (0 > err)
            {
                err = errno;
                okSoFar = false;
            }
        }
        if (okSoFar)
        {
            const CFSocketContext context = { 0, xx, NULL, NULL, NULL };

            xx->fSocket = CFSocketCreateWithNative(kCFAllocatorDefault, sock, kCFSocketReadCallBack,
                                                   socketReadCallback, &context);
            sock = -1;
            CFRunLoopSourceRef rls = CFSocketCreateRunLoopSource(kCFAllocatorDefault, xx->fSocket,
                                                                 0);

            CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
            CFRelease(rls);
            setObjectState(xx, kUdpStateBound);
        }
        if (! okSoFar)
        {
            close(sock);
            LOG_ERROR_2(xx, OUTPUT_PREFIX "set port failed (%ld)", static_cast<long>(err))
            if (bangOnError)
            {
                signalError(xx);
            }
        }
    }
示例#14
0
static void DeviceNotificationCallback(am_device_notification_callback_info *info, void *unknown)
{
    struct am_device *device = info->dev;
    switch (info->msg) {
        case ADNCI_MSG_CONNECTED: {
            if (debug) {
                CFStringRef deviceId = AMDeviceCopyDeviceIdentifier(device);
                CFStringRef str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("deviceconsole connected: %@"), deviceId);
                CFRelease(deviceId);
                CFShow(str);
                CFRelease(str);
            }
            if (requiredDeviceId) {
                CFStringRef deviceId = AMDeviceCopyDeviceIdentifier(device);
                Boolean isRequiredDevice = CFEqual(deviceId, requiredDeviceId);
                CFRelease(deviceId);
                if (!isRequiredDevice)
                    break;
            }
            if (AMDeviceConnect(device) == MDERR_OK) {
                if (AMDeviceIsPaired(device) && (AMDeviceValidatePairing(device) == MDERR_OK)) {
                    if (AMDeviceStartSession(device) == MDERR_OK) {
                        service_conn_t connection;
                        if (AMDeviceStartService(device, AMSVC_SYSLOG_RELAY, &connection, NULL) == MDERR_OK) {
                            CFSocketRef socket = CFSocketCreateWithNative(kCFAllocatorDefault, connection, kCFSocketDataCallBack, SocketCallback, NULL);
                            if (socket) {
                                CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0);
                                if (source) {
                                    CFRunLoopAddSource(CFRunLoopGetMain(), source, kCFRunLoopCommonModes);
                                    AMDeviceRetain(device);
                                    DeviceConsoleConnection *data = malloc(sizeof *data);
                                    data->connection = connection;
                                    data->socket = socket;
                                    data->source = source;
                                    CFDictionarySetValue(liveConnections, device, data);
                                    return;
                                }
                                CFRelease(source);
                            }
                        }
                        AMDeviceStopSession(device);
                    }
                }
            }
            AMDeviceDisconnect(device);
            break;
        }
        case ADNCI_MSG_DISCONNECTED: {
            if (debug) {
                CFStringRef deviceId = AMDeviceCopyDeviceIdentifier(device);
                CFStringRef str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("deviceconsole disconnected: %@"), deviceId);
                CFRelease(deviceId);
                CFShow(str);
                CFRelease(str);
            }
            DeviceConsoleConnection *data = (DeviceConsoleConnection *)CFDictionaryGetValue(liveConnections, device);
            if (data) {
                CFDictionaryRemoveValue(liveConnections, device);
                AMDeviceRelease(device);
                CFRunLoopRemoveSource(CFRunLoopGetMain(), data->source, kCFRunLoopCommonModes);
                CFRelease(data->source);
                CFRelease(data->socket);
                free(data);
                AMDeviceStopSession(device);
                AMDeviceDisconnect(device);
            }
            break;
        }
        default:
            break;
    }
}
示例#15
0
/*! iSCSI daemon entry point. */
int main(void)
{
    // Connect to the preferences .plist file associated with "iscsid" and
    // read configuration parameters for the initiator
    iSCSIPLSynchronize();

    CFStringRef initiatorIQN = iSCSIPLCopyInitiatorIQN();

    if(initiatorIQN) {
        iSCSISetInitiatiorName(initiatorIQN);
        CFRelease(initiatorIQN);
    }

    CFStringRef initiatorAlias = iSCSIPLCopyInitiatorAlias();

    if(initiatorAlias) {
        iSCSISetInitiatiorName(initiatorAlias);
        CFRelease(initiatorAlias);
    }

    // Register with launchd so it can manage this daemon
    launch_data_t reg_request = launch_data_new_string(LAUNCH_KEY_CHECKIN);

    // Quit if we are unable to checkin...
    if(!reg_request) {
        fprintf(stderr,"Failed to checkin with launchd.\n");
        goto ERROR_LAUNCH_DATA;
    }

    launch_data_t reg_response = launch_msg(reg_request);

    // Ensure registration was successful
    if((launch_data_get_type(reg_response) == LAUNCH_DATA_ERRNO)) {
        fprintf(stderr,"Failed to checkin with launchd.\n");
        goto ERROR_NO_SOCKETS;
    }

    // Grab label and socket dictionary from daemon's property list
    launch_data_t label = launch_data_dict_lookup(reg_response,LAUNCH_JOBKEY_LABEL);
    launch_data_t sockets = launch_data_dict_lookup(reg_response,LAUNCH_JOBKEY_SOCKETS);

    if(!label || !sockets) {
        fprintf(stderr,"Could not find socket ");
        goto ERROR_NO_SOCKETS;
    }

    launch_data_t listen_socket_array = launch_data_dict_lookup(sockets,"iscsid");

    if(!listen_socket_array || launch_data_array_get_count(listen_socket_array) == 0)
        goto ERROR_NO_SOCKETS;

    // Grab handle to socket we want to listen on...
    launch_data_t listen_socket = launch_data_array_get_index(listen_socket_array,0);

    if(!iSCSIDRegisterForPowerEvents())
        goto ERROR_PWR_MGMT_FAIL;

    // Create a socket that will
    CFSocketRef socket = CFSocketCreateWithNative(kCFAllocatorDefault,
                         launch_data_get_fd(listen_socket),
                         kCFSocketReadCallBack,
                         iSCSIDProcessIncomingRequest,0);

    // Runloop sources associated with socket events of connected clients
    CFRunLoopSourceRef clientSockSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault,socket,0);
    CFRunLoopAddSource(CFRunLoopGetMain(),clientSockSource,kCFRunLoopDefaultMode);

    CFRunLoopRun();

    // Deregister for power
    iSCSIDDeregisterForPowerEvents();

    launch_data_free(reg_response);
    return 0;

    // TODO: verify that launch data is freed under all possible execution paths

ERROR_PWR_MGMT_FAIL:
ERROR_NO_SOCKETS:
    launch_data_free(reg_response);

ERROR_LAUNCH_DATA:

    return ENOTSUP;
}
示例#16
0
/* CF_EXPORT */ Boolean
CFNetServiceBrowserSearchForServices(CFNetServiceBrowserRef b, CFStringRef domain, CFStringRef type, CFStreamError* error) {

	__CFNetServiceBrowser* browser = (__CFNetServiceBrowser*)b;

	CFStreamError extra;
	Boolean result = FALSE;

	if (!error)
		error = &extra;

	memset(error, 0, sizeof(error[0]));

	// Retain so it doesn't go away underneath in the case of a callout.  This is really
	// no worry for async, but makes the memmove for the error more difficult to place
	// for synchronous without it being here.
	CFRetain(browser);

	// Lock down the browser to start search
	__CFSpinLock(&(browser->_lock));

	do {

		int i;
        char properties[2][1024];
        CFStringRef argProperties[] = {type, domain};
		CFSocketContext ctxt = {0, browser, CFRetain, CFRelease, NULL};

		if (!browser->_callback) {
			browser->_error.error = kCFNetServicesErrorInvalid;
			browser->_error.domain = kCFStreamErrorDomainNetServices;
			break;
		}

		// Check to see if there is an ongoing search already
		if (browser->_trigger) {

			// If it's a mdns search, don't allow another.
			if (CFGetTypeID(browser->_trigger) == CFSocketGetTypeID()) {
				browser->_error.error = kCFNetServicesErrorInProgress;
				browser->_error.domain = kCFStreamErrorDomainNetServices;
				break;
			}

			// It's just the cancel that hasn't fired yet, so cancel it.
			else {

				// Remove the trigger from run loops and modes
				_CFTypeUnscheduleFromMultipleRunLoops(browser->_trigger, browser->_schedules);

				// Invalidate the run loop source
				CFRunLoopSourceInvalidate((CFRunLoopSourceRef)(browser->_trigger));

				// Release the trigger now.
				CFRelease(browser->_trigger);
				browser->_trigger = NULL;
			}
		}

		// Convert the type and domain to c strings to pass down
        for (i = 0; i < (sizeof(properties) / sizeof(properties[0])); i++) {

            if (!argProperties[i])
                properties[i][0] = '\0';
            else {
                CFIndex bytesUsed;

                CFStringGetBytes(argProperties[i],
                                CFRangeMake(0, CFStringGetLength(argProperties[i])),
                                kCFStringEncodingUTF8,
                                0,
                                FALSE,
                                (UInt8*)properties[i],
                                sizeof(properties[i]) - 1,
                                &bytesUsed);
                properties[i][bytesUsed] = '\0';
            }
        }

		browser->_domainSearch = FALSE;

		// Create the service search at the service discovery level
		browser->_error.error = DNSServiceBrowse(&browser->_browse,
												 0,
												 0,
												 properties[0],
												 properties[1],
												 _BrowseReply,
												 browser);

		// Fail if it did.
		if (browser->_error.error) {
			browser->_error.error = _DNSServiceErrorToCFNetServiceError(browser->_error.error);
			browser->_error.domain = kCFStreamErrorDomainNetServices;
			break;
		}

		// Create the trigger for the browse
		browser->_trigger = CFSocketCreateWithNative(CFGetAllocator(browser),
													 DNSServiceRefSockFD(browser->_browse),
													 kCFSocketReadCallBack,
													 _SocketCallBack,
													 &ctxt);

		// Make sure the CFSocket wrapper succeeded
		if (!browser->_trigger) {

			// Try to use errno for the error
			browser->_error.error = errno;

			// If it has no error in it, assume no memory
			if (!browser->_error.error)
				browser->_error.error = ENOMEM;

			// Correct domain and bail.
			browser->_error.domain = kCFStreamErrorDomainPOSIX;

			DNSServiceRefDeallocate(browser->_browse);
			browser->_browse = NULL;

			break;
		}

		// Tell CFSocket not to close the native socket on invalidation.
		CFSocketSetSocketFlags((CFSocketRef)browser->_trigger,
							   CFSocketGetSocketFlags((CFSocketRef)browser->_trigger) & ~kCFSocketCloseOnInvalidate);

		// Async mode is complete at this point
		if (CFArrayGetCount(browser->_schedules)) {

			// Schedule the trigger on the run loops and modes.
			_CFTypeScheduleOnMultipleRunLoops(browser->_trigger, browser->_schedules);

			// It's now succeeded.
			result = TRUE;
		}

		// If there is no callback, go into synchronous mode.
		else {

			// Unlock the browser
			__CFSpinUnlock(&(browser->_lock));

			// Wait for synchronous return
			result = _BrowserBlockUntilComplete(browser);

			// Lock down the browser
			__CFSpinLock(&(browser->_lock));
		}

	} while (0);

	// Copy the error.
	memmove(error, &browser->_error, sizeof(error[0]));

	// Unlock the browser
	__CFSpinUnlock(&(browser->_lock));

	// Release the earlier retain.
	CFRelease(browser);

	return result;
}
示例#17
0
static int ConnectionRegisterListener(
    ConnectionRef               conn, 
    CFRunLoopRef                runLoop,
    CFStringRef                 runLoopMode, 
    ConnectionCallbackProcPtr   callback, 
    void *                      refCon
)
    // Register a listener to be called when packets arrive.  Once you've done 
    // this, you can no longer use conn for RPCs.
    //
    // conn must be a valid connection
    //
    // runLoop and runLoopMode specify the context in which the callback will 
    // be called; in most cases you specify CFRunLoopGetCurrent() and 
    // kCFRunLoopDefaultMode
    //
    // callback is the function you want to be called when packets arrive; it 
    // must not be NULL
    //
    // refCon is passed to callback
    //
    // Returns an errno-style error code
    // On success, the connection has been converted to a listener and your 
    // callback will be called from the context of the specific runloop when 
    // a packet arrives; on error, the connection is no longer useful (conn is 
    // still valid, but you can't use it to transmit any more data)
{
    int             err;

    assert(conn != NULL);
    assert(runLoop != NULL);
    assert(runLoopMode != NULL);
    assert(callback != NULL);

    assert(conn->fSockFD != -1);            // connection must not be shut down
    assert(conn->fSockCF == NULL);          // can't register twice
    
    // Create the packet buffer.
    
    err = 0;
    conn->fBufferedPackets = CFDataCreateMutable(NULL, 0);
    if (conn->fBufferedPackets == NULL) {
        err = ENOMEM;
    }
    
    // Add the source to the runloop.
    
    if (err == 0) {
        CFSocketContext context;

        memset(&context, 0, sizeof(context));
        context.info = conn;

        conn->fSockCF = CFSocketCreateWithNative(
            NULL, 
            (CFSocketNativeHandle) conn->fSockFD, 
            kCFSocketDataCallBack, 
            ConnectionGotData, 
            &context
        );
        if (conn->fSockCF == NULL) {
            err = EINVAL;
        }
    }
    if (err == 0) {
        conn->fRunLoopSource = CFSocketCreateRunLoopSource(NULL, conn->fSockCF, 0);
        if (conn->fRunLoopSource == NULL) {
            err = EINVAL;
        }
    }
    if (err == 0) {
        conn->fCallback = callback;
        conn->fCallbackRefCon = refCon;
        
        CFRunLoopAddSource( runLoop, conn->fRunLoopSource, runLoopMode);
    }

    // Any failure means the entire connection is dead; again, this is the 
    // draconian approach to error handling.  But hey, connections are 
    // (relatively) cheap.
    
    if (err != 0) {
        ConnectionShutdown(conn);
    }
    
    return err;
}
void
load(CFBundleRef bundle, Boolean bundleVerbose)
{
	int			so;
	int			status;
	struct kev_request	kev_req;
	CFSocketRef		es;
	CFSocketContext		context = { 0, NULL, NULL, NULL, NULL };
	CFRunLoopSourceRef	rls;

	if (bundleVerbose) {
		_verbose = TRUE;
	}

	SCLog(_verbose, LOG_DEBUG, CFSTR("load() called"));
	SCLog(_verbose, LOG_DEBUG, CFSTR("  bundle ID = %@"), CFBundleGetIdentifier(bundle));

	/* open a "configd" session to allow cache updates */
	store = SCDynamicStoreCreate(NULL,
				     CFSTR("Kernel Event Monitor plug-in"),
				     NULL,
				     NULL);
	if (!store) {
		SCLog(TRUE, LOG_ERR, CFSTR("SCDnamicStoreCreate() failed: %s"), SCErrorString(SCError()));
		SCLog(TRUE, LOG_ERR, CFSTR("kernel event monitor disabled."));
		return;
	}

	/* Open an event socket */
	so = socket(PF_SYSTEM, SOCK_RAW, SYSPROTO_EVENT);
	if (so != -1) {
		/* establish filter to return all events */
		kev_req.vendor_code  = 0;
		kev_req.kev_class    = 0;	/* Not used if vendor_code is 0 */
		kev_req.kev_subclass = 0;	/* Not used if either kev_class OR vendor_code are 0 */
		status = ioctl(so, SIOCSKEVFILT, &kev_req);
		if (status) {
			SCLog(TRUE, LOG_ERR, CFSTR("could not establish event filter, ioctl() failed: %s"), strerror(errno));
			(void) close(so);
			so = -1;
		}
	} else {
		SCLog(TRUE, LOG_ERR, CFSTR("could not open event socket, socket() failed: %s"), strerror(errno));
	}

	if (so != -1) {
		int	yes = 1;

		status = ioctl(so, FIONBIO, &yes);
		if (status) {
			SCLog(TRUE, LOG_ERR, CFSTR("could not set non-blocking io, ioctl() failed: %s"), strerror(errno));
			(void) close(so);
			so = -1;
		}
	}

	if (so == -1) {
		SCLog(TRUE, LOG_ERR, CFSTR("kernel event monitor disabled."));
		CFRelease(store);
		return;
	}

	/* Create a CFSocketRef for the PF_SYSTEM kernel event socket */
	es  = CFSocketCreateWithNative(NULL,
				       so,
				       kCFSocketReadCallBack,
				       eventCallback,
				       &context);

	/* Create and add a run loop source for the event socket */
	rls = CFSocketCreateRunLoopSource(NULL, es, 0);
	CFRunLoopAddSource(CFRunLoopGetCurrent(), rls, kCFRunLoopDefaultMode);
	CFRelease(rls);
	CFRelease(es);

	return;
}
示例#19
0
/*
    Register a QSocketNotifier with the mac event system by creating a CFSocket with
    with a read/write callback.

    Qt has separate socket notifiers for reading and writing, but on the mac there is
    a limitation of one CFSocket object for each native socket.
*/
void QEventDispatcherMac::registerSocketNotifier(QSocketNotifier *notifier)
{
    Q_ASSERT(notifier);
    int nativeSocket = notifier->socket();
    int type = notifier->type();
#ifndef QT_NO_DEBUG
    if (nativeSocket < 0 || nativeSocket > FD_SETSIZE) {
        qWarning("QSocketNotifier: Internal error");
        return;
    } else if (notifier->thread() != thread()
               || thread() != QThread::currentThread()) {
        qWarning("QSocketNotifier: socket notifiers cannot be enabled from another thread");
        return;
    }
#endif

    Q_D(QEventDispatcherMac);
    QEventDispatcherUNIX::registerSocketNotifier(notifier);

    if (type == QSocketNotifier::Exception) {
        qWarning("QSocketNotifier::Exception is not supported on Mac OS X");
        return;
    }

    // Check if we have a CFSocket for the native socket, create one if not.
    MacSocketInfo *socketInfo = d->macSockets.value(nativeSocket);
    if (!socketInfo) {
        socketInfo = new MacSocketInfo();

        // Create CFSocket, specify that we want both read and write callbacks (the callbacks
        // are enabled/disabled later on).
        const int callbackTypes = kCFSocketReadCallBack | kCFSocketWriteCallBack;
        CFSocketContext context = {0, this, NULL, NULL, NULL};
        socketInfo->socket = CFSocketCreateWithNative(kCFAllocatorDefault, nativeSocket, callbackTypes, qt_mac_socket_callback, &context);
        if (CFSocketIsValid(socketInfo->socket) == false) {
            qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to create CFSocket");
            return;
        }

        CFOptionFlags flags = CFSocketGetSocketFlags(socketInfo->socket);
        flags |= kCFSocketAutomaticallyReenableWriteCallBack; //QSocketNotifier stays enabled after a write
        flags &= ~kCFSocketCloseOnInvalidate; //QSocketNotifier doesn't close the socket upon destruction/invalidation
        CFSocketSetSocketFlags(socketInfo->socket, flags);

        // Add CFSocket to runloop.
        if(!(socketInfo->runloop = qt_mac_add_socket_to_runloop(socketInfo->socket))) {
            qWarning("QEventDispatcherMac::registerSocketNotifier: Failed to add CFSocket to runloop");
            CFSocketInvalidate(socketInfo->socket);
            CFRelease(socketInfo->socket);
            return;
        }

        // Disable both callback types by default. This must be done after
        // we add the CFSocket to the runloop, or else these calls will have
        // no effect.
        CFSocketDisableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
        CFSocketDisableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);

        d->macSockets.insert(nativeSocket, socketInfo);
    }

    // Increment read/write counters and select enable callbacks if necessary.
    if (type == QSocketNotifier::Read) {
        if (++socketInfo->read == 1)
             CFSocketEnableCallBacks(socketInfo->socket, kCFSocketReadCallBack);
    } else if (type == QSocketNotifier::Write) {
        if (++socketInfo->write == 1)
             CFSocketEnableCallBacks(socketInfo->socket, kCFSocketWriteCallBack);
    }
}
bool wxServiceDiscoveryTaskBase::Start( void )
{
	wxASSERT( m_rServiceRef == NULL );

	bool output = DoStart();
	
	if ( output )
	{
		wxASSERT( m_rServiceRef != NULL );
		
		if ( m_rServiceRef != NULL )
		{
			if ( m_bUseThreads )
			{
				wxASSERT( m_pThread == NULL );
				
				if ( m_pThread != NULL )
				{
					m_pThread->Delete();
					delete m_pThread;
					m_pThread = NULL;
				}
				
				m_pThread = new wxServiceDiscoveryServiceHelperThread( m_rServiceRef );
				
				if ( m_pThread != NULL )
				{
					m_pThread->Create();
					m_pThread->Run();
				}
			}
			else
			{
				dns_sd_fd = DNSServiceRefSockFD( m_rServiceRef );

				#ifdef __DARWIN__
				
					CFSocketContext context = { 0, this, NULL, NULL, NULL }; 
				
					cfsocket = CFSocketCreateWithNative(NULL, 
														dns_sd_fd, 
														kCFSocketReadCallBack, 
														wxServiceDiscoveryTaskBase::Mac_Socket_Callback, 
														&context);
					
					// Prevent CFSocketInvalidate from closing DNSServiceRef's socket. 
					CFOptionFlags f = CFSocketGetSocketFlags( cfsocket ); 
					CFSocketSetSocketFlags( cfsocket, f & ~kCFSocketCloseOnInvalidate); 
					
					source = CFSocketCreateRunLoopSource( NULL, cfsocket, 0 ); 
					CFRunLoopAddSource( CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes );
					
				#elif defined( _WIN32 )
					
				    // Create the window. This window won't actually be shown, 
					// but it demonstrates how to use DNS-SD with Windows GUI 
					// applications by having DNS-SD events processed as messages 
					// to a Window. 
					wind = CreateWindow(GetWndClass().lpszClassName, 
										GetWndClass().lpszClassName,
										0, 
										CW_USEDEFAULT,
										0,
										CW_USEDEFAULT,
										0,
										HWND_MESSAGE, // requires 2000/XP http://msdn2.microsoft.com/en-us/library/ms632599.aspx#message_only
										NULL,
										instance,
										NULL ); 

					BOOL status = SetProp( wind, PROPNAME, this );
					wxASSERT( status != 0 );
					
					// Associate the DNS-SD browser with our window 
					// using the WSAAsyncSelect mechanism. Whenever something 
					// related to the DNS-SD browser occurs, our private Windows message 
					// will be sent to our window so we can give DNS-SD a 
					// chance to process it. This allows DNS-SD to avoid using a 
					// secondary thread (and all the issues with synchronization that 
					// would introduce), but still process everything asynchronously. 
					
					// This also simplifies app code because DNS-SD will only run when we 
					// explicitly call it. 
					
					err = WSAAsyncSelect( dns_sd_fd, 
										  wind, 
										  DNSSD_EVENT, 
										  FD_READ | FD_CLOSE); 
					
					assert(err == kDNSServiceErr_NoError); 

				#else
					
					nfds = dns_sd_fd + 1;
					
					FD_ZERO(&readfds);
					FD_SET(dns_sd_fd,&readfds);
					
				#endif
			}
		}
	}
	
	return output;	
}