launch_data_t launch_msg(launch_data_t d)
{
	launch_data_t resp = NULL;

	pthread_once(&_lc_once, launch_client_init);

	if (!_lc) {
		errno = ENOTCONN;
		return NULL;
	}

	pthread_mutex_lock(&_lc->mtx);

	if (d) {
		if (launchd_msg_send(_lc->l, d) == -1)
			goto out;
	} else if (launch_data_array_get_count(_lc->async_resp) > 0) {
		resp = launch_data_array_pop_first(_lc->async_resp);
		goto out;
	}

	while (resp == NULL) {
		if (launchd_msg_recv(_lc->l, launch_msg_getmsgs, &resp) == -1 && errno != EAGAIN)
			goto out;
	}

out:
	pthread_mutex_unlock(&_lc->mtx);

	return resp;
}
/*
    returns -1 for error, else file descriptor for listener
*/
int get_listener_fd() {
    launch_data_t checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN);
    if (!checkin_request) {
        syslog(LOG_NOTICE, "Unable to create checkin string!");
        return -1;
    }
    launch_data_t checkin_response = launch_msg(checkin_request);
    if (!checkin_response) {
        syslog(LOG_NOTICE, "Unable to do checkin!");
        return -1;
    }
    if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) {
        errno = launch_data_get_errno(checkin_response);
        syslog(LOG_NOTICE, "Error %d getting type of checkin response!", errno);
        return -1;
    }
    launch_data_t the_label = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_LABEL);
    if (!the_label) {
        syslog(LOG_NOTICE, "No Label for job!");
        return -1;
    }    
    launch_data_t sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS);
    if (!sockets_dict) {
        syslog(LOG_NOTICE, "No socket found to answer requests on!");
        return -1;
    }
    size_t count = launch_data_dict_get_count(sockets_dict);
    if (count < 1) {
        syslog(LOG_NOTICE, "No socket found to answer requests on!");
        return -1;
    }
    if (1 < count) {
        syslog(LOG_NOTICE, "Some socket(s) will be ignored!");
    }
    launch_data_t listening_fd_array = launch_data_dict_lookup(sockets_dict, "MasterSocket");
    if (!listening_fd_array) {
        syslog(LOG_NOTICE, "MasterSocket not found!");
        return -1;
    }
    count = launch_data_array_get_count(listening_fd_array);
    if (count < 1) {
        syslog(LOG_NOTICE, "No socket found to answer requests on!");
        return -1;
    }
    if (1 < count) {
        syslog(LOG_NOTICE, "Some socket(s) will be ignored!");
    }
    launch_data_t this_listening_fd = launch_data_array_get_index(listening_fd_array, 0);
    int listener_fd = launch_data_get_fd(this_listening_fd);
    if ( listener_fd == -1 ) {
        syslog(LOG_NOTICE, "launch_data_get_fd() failed!");
        return -1;
    }
    if (listen(listener_fd, 5)) {
        syslog(LOG_NOTICE, "listen() failed with %i", errno);
        return -1;
    }
    return listener_fd;
}
static void launch_msg_getmsgs(launch_data_t m, void *context)
{
	launch_data_t async_resp, *sync_resp = context;
	
	if ((LAUNCH_DATA_DICTIONARY == launch_data_get_type(m)) && (async_resp = launch_data_dict_lookup(m, "_AsyncMessage"))) {
		launch_data_array_set_index(_lc->async_resp, launch_data_copy(async_resp), launch_data_array_get_count(_lc->async_resp));
	} else {
		*sync_resp = launch_data_copy(m);
	}
}
/*
 * Register listening sockets with our run loop
 */
void socket_connection_launchd_register_fd_array(launch_data_t listening_fd_array){
	int i;
    for (i = 0; i < launch_data_array_get_count(listening_fd_array); i++) {
        // get fd
        launch_data_t tempi = launch_data_array_get_index (listening_fd_array, i);
        int listening_fd = launch_data_get_fd(tempi);
        launch_data_free (tempi);
		log_info("file descriptor = %u\n", listening_fd);
        
        // create data_source_t for fd
        data_source_t *ds = malloc( sizeof(data_source_t));
        if (ds == NULL) return;
        ds->process = socket_connection_accept;
        ds->fd = listening_fd;
        run_loop_add_data_source(ds);
	}
}
Exemple #5
0
static PyObject* 
launcharray2python(launch_data_t data)
{
	size_t count = launch_data_array_get_count(data);
	size_t i;
	PyObject* result = PyList_New(count);

	for (i = 0; i < 0; i ++) {
		launch_data_t v = launch_data_array_get_index(data, i);
		PyList_SET_ITEM(result, i, launch2python(data));
	}
	if (PyErr_Occurred()) {
		Py_DECREF(result);
		return NULL;
	}
	return result;
}
Exemple #6
0
int listen_to_launchd_sockets() {
    //check-in with launchd
    launch_data_t checkin_message = launch_data_new_string(LAUNCH_KEY_CHECKIN);
    if (checkin_message == NULL) {
        exit_error("couldn't create launchd checkin message", errno);
    }
    launch_data_t checkin_result = launch_msg(checkin_message);
    if (checkin_result == NULL) {
        exit_error("couldn't check in with launchd", errno);
    }
    if (launch_data_get_type(checkin_result) == LAUNCH_DATA_ERRNO) {
        exit_error("error on launchd checkin",launch_data_get_errno(checkin_result));
        return EX_OSERR;
    }
    launch_data_t socket_info = launch_data_dict_lookup(checkin_result, LAUNCH_JOBKEY_SOCKETS);
    if (socket_info == NULL) {
        exit_error("couldn't find socket information", 0);
    }
    launch_data_t listening_sockets = launch_data_dict_lookup(socket_info, "Listener");
    if (listening_sockets == NULL) {
        exit_error("couldn't find my socket", 0);
    }
    //set up a kevent for our socket
    int kernel_queue = kqueue();
    if (kernel_queue == -1) {
        exit_error("couldn't create kernel queue", errno);
    }
    for (int i = 0; i < launch_data_array_get_count(listening_sockets); i++) {
        launch_data_t this_socket = launch_data_array_get_index(listening_sockets, i);
        struct kevent kev_init;
        EV_SET(&kev_init, launch_data_get_fd(this_socket), EVFILT_READ, EV_ADD, 0, 0, NULL);
        if (kevent(kernel_queue, &kev_init, 1, NULL, 0, NULL) == -1) {
            exit_error("couldn't create kernel event", errno);
        }
    }
    launch_data_free(checkin_result);
    return kernel_queue;
}
Exemple #7
0
static void
launchd_checkin(void)
{
  size_t		i,		/* Looping var */
			count;		/* Number of listeners */
  launch_data_t		ld_msg,		/* Launch data message */
			ld_resp,	/* Launch data response */
			ld_array,	/* Launch data array */
			ld_sockets,	/* Launch data sockets dictionary */
			tmp;		/* Launch data */
  cupsd_listener_t	*lis;		/* Listeners array */
  http_addr_t		addr;		/* Address variable */
  socklen_t		addrlen;	/* Length of address */
  int			fd;		/* File descriptor */
  char			s[256];		/* String addresss */


  cupsdLogMessage(CUPSD_LOG_DEBUG, "launchd_checkin: pid=%d", (int)getpid());

 /*
  * Check-in with launchd...
  */

  ld_msg = launch_data_new_string(LAUNCH_KEY_CHECKIN);
  if ((ld_resp = launch_msg(ld_msg)) == NULL)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
		    "launchd_checkin: launch_msg(\"" LAUNCH_KEY_CHECKIN
		    "\") IPC failure");
    exit(EXIT_FAILURE);
    return; /* anti-compiler-warning */
  }

  if (launch_data_get_type(ld_resp) == LAUNCH_DATA_ERRNO)
  {
    errno = launch_data_get_errno(ld_resp);
    cupsdLogMessage(CUPSD_LOG_ERROR, "launchd_checkin: Check-in failed: %s",
                    strerror(errno));
    exit(EXIT_FAILURE);
    return; /* anti-compiler-warning */
  }

 /*
  * Get the sockets dictionary...
  */

  if ((ld_sockets = launch_data_dict_lookup(ld_resp, LAUNCH_JOBKEY_SOCKETS))
          == NULL)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "launchd_checkin: No sockets found to answer requests on!");
    exit(EXIT_FAILURE);
    return; /* anti-compiler-warning */
  }

 /*
  * Get the array of listener sockets...
  */

  if ((ld_array = launch_data_dict_lookup(ld_sockets, "Listeners")) == NULL)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "launchd_checkin: No sockets found to answer requests on!");
    exit(EXIT_FAILURE);
    return; /* anti-compiler-warning */
  }

 /*
  * Add listening fd(s) to the Listener array...
  */

  if (launch_data_get_type(ld_array) == LAUNCH_DATA_ARRAY)
  {
    count = launch_data_array_get_count(ld_array);

    for (i = 0; i < count; i ++)
    {
     /*
      * Get the launchd file descriptor and address...
      */

      if ((tmp = launch_data_array_get_index(ld_array, i)) != NULL)
      {
	fd      = launch_data_get_fd(tmp);
	addrlen = sizeof(addr);

	if (getsockname(fd, (struct sockaddr *)&addr, &addrlen))
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "launchd_checkin: Unable to get local address - %s",
			  strerror(errno));
	  continue;
	}

       /*
	* Try to match the launchd socket address to one of the listeners...
	*/

	for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
	     lis;
	     lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
	  if (httpAddrEqual(&lis->address, &addr))
	    break;

       /*
	* Add a new listener If there's no match...
	*/

	if (lis)
	{
	  cupsdLogMessage(CUPSD_LOG_DEBUG,
		  "launchd_checkin: Matched existing listener %s with fd %d...",
		  httpAddrString(&(lis->address), s, sizeof(s)), fd);
	}
	else
	{
	  cupsdLogMessage(CUPSD_LOG_DEBUG,
		  "launchd_checkin: Adding new listener %s with fd %d...",
		  httpAddrString(&addr, s, sizeof(s)), fd);

	  if ((lis = calloc(1, sizeof(cupsd_listener_t))) == NULL)
	  {
	    cupsdLogMessage(CUPSD_LOG_ERROR,
			    "launchd_checkin: Unable to allocate listener - "
			    "%s.", strerror(errno));
	    exit(EXIT_FAILURE);
	  }

	  cupsArrayAdd(Listeners, lis);

	  memcpy(&lis->address, &addr, sizeof(lis->address));
	}

	lis->fd = fd;

#  ifdef HAVE_SSL
	if (_httpAddrPort(&(lis->address)) == 443)
	  lis->encryption = HTTP_ENCRYPT_ALWAYS;
#  endif /* HAVE_SSL */
      }
    }
  }

  launch_data_free(ld_msg);
  launch_data_free(ld_resp);
}
Exemple #8
0
int main(int argc, char *argv[]) {
    auto request(launch_data_new_string(LAUNCH_KEY_GETJOBS));
    auto response(launch_msg(request));
    launch_data_free(request);

    _assert(response != NULL);
    _assert(launch_data_get_type(response) == LAUNCH_DATA_DICTIONARY);

    auto parent(getppid());

    auto cydia(false);

    launch_data_dict_iterate(response, [=, &cydia](const char *name, launch_data_t value) {
        if (launch_data_get_type(response) != LAUNCH_DATA_DICTIONARY)
            return;

        auto integer(launch_data_dict_lookup(value, LAUNCH_JOBKEY_PID));
        if (integer == NULL || launch_data_get_type(integer) != LAUNCH_DATA_INTEGER)
            return;

        auto pid(launch_data_get_integer(integer));
        if (pid != parent)
            return;

        auto variables(launch_data_dict_lookup(value, LAUNCH_JOBKEY_ENVIRONMENTVARIABLES));
        if (variables != NULL && launch_data_get_type(variables) == LAUNCH_DATA_DICTIONARY) {
            auto dyld(false);

            launch_data_dict_iterate(variables, [&dyld](const char *name, launch_data_t value) {
                if (strncmp(name, "DYLD_", 5) == 0)
                    dyld = true;
            });

            if (dyld)
                return;
        }

        auto string(launch_data_dict_lookup(value, LAUNCH_JOBKEY_PROGRAM));
        if (string == NULL || launch_data_get_type(string) != LAUNCH_DATA_STRING) {
            auto array(launch_data_dict_lookup(value, LAUNCH_JOBKEY_PROGRAMARGUMENTS));
            if (array == NULL || launch_data_get_type(array) != LAUNCH_DATA_ARRAY)
                return;
            if (launch_data_array_get_count(array) == 0)
                return;

            string = launch_data_array_get_index(array, 0);
            if (string == NULL || launch_data_get_type(string) != LAUNCH_DATA_STRING)
                return;
        }

        auto program(launch_data_get_string(string));
        if (program == NULL)
            return;

        if (strcmp(program, "/Applications/Cydia.app/Cydia") == 0)
            cydia = true;
    });

    if (!cydia) {
        fprintf(stderr, "thou shalt not pass\n");
        return EX_NOPERM;
    }

    setuid(0);
    setgid(0);

    if (argc < 2 || argv[1][0] != '/')
        argv[0] = "/usr/bin/dpkg";
    else {
        --argc;
        ++argv;
    }

    execv(argv[0], argv);
    return EX_UNAVAILABLE;
}
DBusServer *
_dbus_server_new_for_launchd (const char *launchd_env_var, DBusError * error)
  {
#ifdef DBUS_ENABLE_LAUNCHD
    DBusServer *server;
    DBusString address;
    int launchd_fd;
    launch_data_t sockets_dict, checkin_response;
    launch_data_t checkin_request;
    launch_data_t listening_fd_array, listening_fd;
    launch_data_t environment_dict, environment_param;
    const char *launchd_socket_path, *display;

    launchd_socket_path = _dbus_getenv (launchd_env_var);
    display = _dbus_getenv ("DISPLAY");

    _DBUS_ASSERT_ERROR_IS_CLEAR (error);

    if (launchd_socket_path == NULL || *launchd_socket_path == '\0')
      {
        dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
                        "launchd's environment variable %s is empty, but should contain a socket path.\n", launchd_env_var);
        return NULL;
      }

    if (!_dbus_string_init (&address))
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        return NULL;
      }
    if (!_dbus_string_append (&address, "unix:path="))
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto l_failed_0;
      }
    if (!_dbus_string_append (&address, launchd_socket_path))
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
        goto l_failed_0;
      }

    if ((checkin_request = launch_data_new_string (LAUNCH_KEY_CHECKIN)) == NULL)
      {
        dbus_set_error (error, DBUS_ERROR_NO_MEMORY,
                        "launch_data_new_string(\"%s\") Unable to create string.\n",
                        LAUNCH_KEY_CHECKIN);
        goto l_failed_0;
      }

    if ((checkin_response = launch_msg (checkin_request)) == NULL)
      {
        dbus_set_error (error, DBUS_ERROR_IO_ERROR,
                        "launch_msg(\"%s\") IPC failure: %s\n",
                        LAUNCH_KEY_CHECKIN, strerror (errno));
        goto l_failed_0;
      }

    if (LAUNCH_DATA_ERRNO == launch_data_get_type (checkin_response))
      {
        dbus_set_error (error, DBUS_ERROR_FAILED, "Check-in failed: %s\n",
                        strerror (launch_data_get_errno (checkin_response)));
        goto l_failed_0;
      }

    sockets_dict =
      launch_data_dict_lookup (checkin_response, LAUNCH_JOBKEY_SOCKETS);
    if (NULL == sockets_dict)
      {
        dbus_set_error (error, DBUS_ERROR_IO_ERROR,
                        "No sockets found to answer requests on!\n");
        goto l_failed_0;
      }

    listening_fd_array =
      launch_data_dict_lookup (sockets_dict, "unix_domain_listener");
    if (NULL == listening_fd_array)
      {
        dbus_set_error (error, DBUS_ERROR_IO_ERROR,
                        "No known sockets found to answer requests on!\n");
        goto l_failed_0;
      }

    if (launch_data_array_get_count (listening_fd_array) != 1)
      {
        dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
                        "Expected 1 socket from launchd, got %d.\n",
                        launch_data_array_get_count (listening_fd_array));
        goto l_failed_0;
      }

    listening_fd = launch_data_array_get_index (listening_fd_array, 0);
    launchd_fd = launch_data_get_fd (listening_fd);

    _dbus_fd_set_close_on_exec (launchd_fd);

    if (launchd_fd < 0)
      {
        _DBUS_ASSERT_ERROR_IS_SET (error);
        goto l_failed_0;
  if (display == NULL || *display == '\0')
    {
      environment_dict = launch_data_dict_lookup (checkin_response, LAUNCH_JOBKEY_USERENVIRONMENTVARIABLES);
      if (NULL == environment_dict)
        {
          _dbus_warn ("Unable to retrieve user environment from launchd.");
        }
      else
        {
          environment_param = launch_data_dict_lookup (environment_dict, "DISPLAY");
          if (NULL == environment_param)
            {
              _dbus_warn ("Unable to retrieve DISPLAY from launchd.");
            }
          else
            {
              display = launch_data_get_string(environment_param);
              dbus_setenv ("DISPLAY", display);
            }
        }
    }

      }

    server = _dbus_server_new_for_socket (&launchd_fd, 1, &address, 0);
    if (server == NULL)
      {
        dbus_set_error (error, DBUS_ERROR_NO_SERVER,
                        "Unable to listen on launchd fd %d.", launchd_fd);
        goto l_failed_0;
      }

    _dbus_string_free (&address);

    return server;

  l_failed_0:
    _dbus_string_free (&address);

    return NULL;
#else /* DBUS_ENABLE_LAUNCHD */
    dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
                    "address type 'launchd' requested, but launchd support not compiled in");
    return NULL;
#endif
  }
Exemple #10
0
int                     
checklaunchd()                  
{               
	launch_data_t checkin_response = NULL; 
#ifdef LION_TEST
    launch_data_t checkin_request = NULL;
#endif
	launch_data_t sockets_dict, listening_fd_array;
	launch_data_t listening_fd;
	struct sockaddr_storage fdsockaddr;
	socklen_t fdsockaddrlen = sizeof(fdsockaddr);
	int socketct;
	int i;
	int listenerct;
	int returnval = 0;
	int fd;
	
	/* check in with launchd */
#ifdef LION_TEST
    if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == NULL) {
#else
	if ((checkin_response = launch_socket_service_check_in()) == NULL) {
#endif
		plog(ASL_LEVEL_ERR, 
			 "failed to launch_socket_service_check_in.\n");
		goto done;
	}
#ifdef LION_TEST
    if ((checkin_response = launch_msg(checkin_request)) == NULL) {
        plog(ASL_LEVEL_ERR, "failed to launch_msg.\n");
        goto done;
    }
#endif
	if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) {
		plog(ASL_LEVEL_ERR, 
			 "launch_data_get_type error %d\n",
			 launch_data_get_errno(checkin_response));
		goto done;
	}
	if ( (sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS)) == NULL){
		plog(ASL_LEVEL_ERR, 
			 "failed to launch_data_dict_lookup.\n");
		goto done;
	}
	if ( !(socketct = launch_data_dict_get_count(sockets_dict))){
		plog(ASL_LEVEL_ERR, 
			 "launch_data_dict_get_count returns no socket defined.\n");
		goto done;
	}
	
	if ( (listening_fd_array = launch_data_dict_lookup(sockets_dict, "Listeners")) == NULL ){
		plog(ASL_LEVEL_ERR, 
			 "failed to launch_data_dict_lookup.\n");
		goto done;
	}
	listenerct = launch_data_array_get_count(listening_fd_array);
	for (i = 0; i < listenerct; i++) {
		listening_fd = launch_data_array_get_index(listening_fd_array, i);
		fd = launch_data_get_fd( listening_fd );
		if ( getsockname( fd , (struct sockaddr *)&fdsockaddr, &fdsockaddrlen)){
			continue;
		}
		
		/* Is this the VPN control socket? */ 
		if ( fdsockaddr.ss_family == AF_UNIX && 
				(!(strcmp(vpncontrolsock_path, ((struct sockaddr_un *)&fdsockaddr)->sun_path))))
		{       
			plog(ASL_LEVEL_INFO, 
				 "found launchd socket.\n");
			returnval = fd;
			break;
		}
	}
	// TODO: check if we have any leaked fd
	if ( listenerct == i){
		plog(ASL_LEVEL_ERR, 
			 "failed to find launchd socket\n");               
		returnval = 0;
	}
	
done:   
	if (checkin_response)
		launch_data_free(checkin_response);
	return(returnval);
}

		
void
vpncontrol_handler(void *unused)
{
	struct sockaddr_storage from;
	socklen_t fromlen = sizeof(from);
    int sock;

	struct vpnctl_socket_elem *sock_elem;
	
    sock_elem = racoon_malloc(sizeof(struct vpnctl_socket_elem));
	if (sock_elem == NULL) {
		plog(ASL_LEVEL_ERR, 
			"memory error: %s\n", strerror(errno));
		return; //%%%%%% terminate
	}
	LIST_INIT(&sock_elem->bound_addresses);
    
	sock_elem->sock = accept(lcconf->sock_vpncontrol, (struct sockaddr *)&from, &fromlen);
	if (sock_elem->sock < 0) {
		plog(ASL_LEVEL_ERR, 
			"failed to accept vpn_control command: %s\n", strerror(errno));
		racoon_free(sock_elem);
		return; //%%%%% terminate
	}
	LIST_INSERT_HEAD(&lcconf->vpnctl_comm_socks, sock_elem, chain);
    
    sock_elem->source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, sock_elem->sock, 0, dispatch_get_main_queue());
    if (sock_elem->source == NULL) {
		plog(ASL_LEVEL_ERR, "could not create comm socket source.");
		racoon_free(sock_elem);
		return; //%%%%% terminate
    }
    dispatch_source_set_event_handler(sock_elem->source, 
                                        ^{
                                                vpncontrol_comm_handler(sock_elem);
                                        });
    sock = sock_elem->sock;
	
    dispatch_source_t the_source = sock_elem->source;
    dispatch_source_set_cancel_handler(sock_elem->source,
                                       ^{
                                           close(sock);
                                           dispatch_release(the_source); /* Release the source on cancel */
                                       });
CFTypeRef GTMCFTypeCreateFromLaunchData(launch_data_t ldata,
                                        bool convert_non_standard_objects,
                                        CFErrorRef *error) {
  CFTypeRef cf_type_ref = NULL;
  CFErrorRef local_error = NULL;
  if (ldata == NULL) {
    local_error = GTMCFLaunchCreateUnlocalizedError(EINVAL,
                                                    CFSTR("NULL ldata"));
    goto exit;
  }

  launch_data_type_t ldata_type = launch_data_get_type(ldata);
  switch (ldata_type) {
    case LAUNCH_DATA_STRING:
      cf_type_ref
        = CFStringCreateWithCString(kCFAllocatorDefault,
                                    launch_data_get_string(ldata),
                                    kCFStringEncodingUTF8);
      break;

    case LAUNCH_DATA_INTEGER: {
      long long value = launch_data_get_integer(ldata);
      cf_type_ref = CFNumberCreate(kCFAllocatorDefault,
                                   kCFNumberLongLongType,
                                   &value);
      break;
    }

    case LAUNCH_DATA_REAL: {
      double value = launch_data_get_real(ldata);
      cf_type_ref = CFNumberCreate(kCFAllocatorDefault,
                                   kCFNumberDoubleType,
                                   &value);
      break;
    }

    case LAUNCH_DATA_BOOL: {
      bool value = launch_data_get_bool(ldata);
      cf_type_ref = value ? kCFBooleanTrue : kCFBooleanFalse;
      CFRetain(cf_type_ref);
      break;
    }

    case LAUNCH_DATA_OPAQUE: {
      size_t size = launch_data_get_opaque_size(ldata);
      void *data = launch_data_get_opaque(ldata);
      cf_type_ref = CFDataCreate(kCFAllocatorDefault, data, size);
      break;
    }

    case LAUNCH_DATA_ARRAY: {
      size_t count = launch_data_array_get_count(ldata);
      cf_type_ref = CFArrayCreateMutable(kCFAllocatorDefault,
                                         count,
                                         &kCFTypeArrayCallBacks);
      if (cf_type_ref) {
        for (size_t i = 0; !local_error && i < count; i++) {
          launch_data_t l_sub_data = launch_data_array_get_index(ldata, i);
          CFTypeRef cf_sub_type
            = GTMCFTypeCreateFromLaunchData(l_sub_data,
                                            convert_non_standard_objects,
                                            &local_error);
          if (cf_sub_type) {
            CFArrayAppendValue((CFMutableArrayRef)cf_type_ref, cf_sub_type);
            CFRelease(cf_sub_type);
          }
        }
      }
      break;
    }

    case LAUNCH_DATA_DICTIONARY:
      cf_type_ref = CFDictionaryCreateMutable(kCFAllocatorDefault,
                                              0,
                                              &kCFTypeDictionaryKeyCallBacks,
                                              &kCFTypeDictionaryValueCallBacks);
      if (cf_type_ref) {
        GTMLToCFDictContext context = {
          (CFMutableDictionaryRef)cf_type_ref,
          convert_non_standard_objects,
          &local_error
        };
        launch_data_dict_iterate(ldata,
                                 GTMConvertLaunchDataDictEntryToCFDictEntry,
                                 &context);
      }
      break;

    case LAUNCH_DATA_FD:
      if (convert_non_standard_objects) {
        int file_descriptor = launch_data_get_fd(ldata);
        cf_type_ref = CFNumberCreate(kCFAllocatorDefault,
                                     kCFNumberIntType,
                                     &file_descriptor);
      }
      break;

    case LAUNCH_DATA_MACHPORT:
      if (convert_non_standard_objects) {
        mach_port_t port = launch_data_get_machport(ldata);
        cf_type_ref = CFNumberCreate(kCFAllocatorDefault,
                                     kCFNumberIntType,
                                     &port);
      }
      break;

    default:
      local_error =
        GTMCFLaunchCreateUnlocalizedError(EINVAL,
                                          CFSTR("Unknown launchd type %d"),
                                          ldata_type);
      break;
  }
exit:
  if (error) {
    *error = local_error;
  } else if (local_error) {
#ifdef DEBUG
    CFShow(local_error);
#endif //  DEBUG
    CFRelease(local_error);
  }
  return cf_type_ref;
}
Exemple #12
0
int
TRANS(MakeAllCOTSServerListeners) (char *port, int *partial, int *count_ret, 
				   XtransConnInfo **ciptrs_ret)

{
    char		buffer[256]; /* ??? What size ?? */
    XtransConnInfo	ciptr, temp_ciptrs[NUMTRANS];
    int			status, i, j;
#ifdef HAVE_LAUNCHD
    int                 launchd_fd;
    launch_data_t       sockets_dict, checkin_request, checkin_response;
    launch_data_t       listening_fd_array, listening_fd;
#endif

#if defined(IPv6) && defined(AF_INET6)
    int		ipv6_succ = 0;
#endif
    PRMSG (2,"MakeAllCOTSServerListeners(%s,%p)\n",
	   port ? port : "NULL", ciptrs_ret, 0);

    *count_ret = 0;

#ifdef HAVE_LAUNCHD
    /* Get launchd fd */
    if ((checkin_request = launch_data_new_string(LAUNCH_KEY_CHECKIN)) == NULL) {
      fprintf(stderr,"launch_data_new_string(\"" LAUNCH_KEY_CHECKIN "\") Unable to create string.\n");
	  goto not_launchd;
	  }

    if ((checkin_response = launch_msg(checkin_request)) == NULL) {
       fprintf(stderr,"launch_msg(\"" LAUNCH_KEY_CHECKIN "\") IPC failure: %s\n",strerror(errno));
	   goto not_launchd;
	}

    if (LAUNCH_DATA_ERRNO == launch_data_get_type(checkin_response)) {
      // ignore EACCES, which is common if we weren't started by launchd
      if (launch_data_get_errno(checkin_response) != EACCES)
       fprintf(stderr,"launchd check-in failed: %s\n",strerror(launch_data_get_errno(checkin_response)));
	   goto not_launchd;
	} 

	sockets_dict = launch_data_dict_lookup(checkin_response, LAUNCH_JOBKEY_SOCKETS);
    if (NULL == sockets_dict) {
       fprintf(stderr,"launchd check-in: no sockets found to answer requests on!\n");
	   goto not_launchd;
	}

    if (launch_data_dict_get_count(sockets_dict) > 1) {
       fprintf(stderr,"launchd check-in: some sockets will be ignored!\n");
	   goto not_launchd;
	}

    listening_fd_array = launch_data_dict_lookup(sockets_dict, ":0");
    if (NULL == listening_fd_array) {
       fprintf(stderr,"launchd check-in: No known sockets found to answer requests on!\n");
	   goto not_launchd;
	}

    if (launch_data_array_get_count(listening_fd_array)!=1) {
       fprintf(stderr,"launchd check-in: Expected 1 socket from launchd, got %d)\n",
                       launch_data_array_get_count(listening_fd_array));
	   goto not_launchd;
	}

    listening_fd=launch_data_array_get_index(listening_fd_array, 0);
    launchd_fd=launch_data_get_fd(listening_fd);
    fprintf(stderr,"Xquartz: run by launchd for fd %d\n",launchd_fd);
    if((ciptr = TRANS(ReopenCOTSServer(TRANS_SOCKET_LOCAL_INDEX,
                                       launchd_fd, getenv("DISPLAY"))))==NULL)
        fprintf(stderr,"Got NULL while trying to Reopen launchd port\n");
        else temp_ciptrs[(*count_ret)++] = ciptr;

not_launchd:
#endif

    for (i = 0; i < NUMTRANS; i++)
    {
	Xtransport *trans = Xtransports[i].transport;
	unsigned int flags = 0;

	if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN)
	    continue;

	snprintf(buffer, sizeof(buffer), "%s/:%s",
		 trans->TransName, port ? port : "");

	PRMSG (5,"MakeAllCOTSServerListeners: opening %s\n",
	       buffer, 0, 0);

	if ((ciptr = TRANS(OpenCOTSServer(buffer))) == NULL)
	{
	    if (trans->flags & TRANS_DISABLED)
		continue;

	    PRMSG (1,
	  "MakeAllCOTSServerListeners: failed to open listener for %s\n",
		  trans->TransName, 0, 0);
	    continue;
	}
#if defined(IPv6) && defined(AF_INET6)
		if ((Xtransports[i].transport_id == TRANS_SOCKET_INET_INDEX
		     && ipv6_succ))
		    flags |= ADDR_IN_USE_ALLOWED;
#endif

	if ((status = TRANS(CreateListener (ciptr, port, flags))) < 0)
	{
	    if (status == TRANS_ADDR_IN_USE)
	    {
		/*
		 * We failed to bind to the specified address because the
		 * address is in use.  It must be that a server is already
		 * running at this address, and this function should fail.
		 */

		PRMSG (1,
		"MakeAllCOTSServerListeners: server already running\n",
		  0, 0, 0);

		for (j = 0; j < *count_ret; j++)
		    TRANS(Close) (temp_ciptrs[j]);

		*count_ret = 0;
		*ciptrs_ret = NULL;
		*partial = 0;
		return -1;
	    }
	    else
	    {
		PRMSG (1,
	"MakeAllCOTSServerListeners: failed to create listener for %s\n",
		  trans->TransName, 0, 0);

		continue;
	    }
	}

#if defined(IPv6) && defined(AF_INET6)
	if (Xtransports[i].transport_id == TRANS_SOCKET_INET6_INDEX)
	    ipv6_succ = 1;
#endif
	
	PRMSG (5,
	      "MakeAllCOTSServerListeners: opened listener for %s, %d\n",
	      trans->TransName, ciptr->fd, 0);

	temp_ciptrs[*count_ret] = ciptr;
	(*count_ret)++;
    }

    *partial = (*count_ret < complete_network_count());

    PRMSG (5,
     "MakeAllCOTSServerListeners: partial=%d, actual=%d, complete=%d \n",
	*partial, *count_ret, complete_network_count());

    if (*count_ret > 0)
    {
	if ((*ciptrs_ret = (XtransConnInfo *) xalloc (
	    *count_ret * sizeof (XtransConnInfo))) == NULL)
	{
	    return -1;
	}

	for (i = 0; i < *count_ret; i++)
	{
	    (*ciptrs_ret)[i] = temp_ciptrs[i];
	}
    }
    else
	*ciptrs_ret = NULL;
 
    return 0;
}
Exemple #13
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;
}