int getSocketFromLaunchd() { // check-in launch_data_t checkinRequest = launch_data_new_string(LAUNCH_KEY_CHECKIN); launch_data_t checkinResponse = launch_msg(checkinRequest); if (!checkinResponse) { fprintf(stderr, "launch_msg(checkin_request) failed.\n"); return -1; } // test if check-in was successful launch_data_type_t responseType = launch_data_get_type(checkinResponse); if (responseType == LAUNCH_DATA_ERRNO) { errno = launch_data_get_errno(checkinResponse); fprintf(stderr, "Check-in with launchd failed, error %i.\n", errno); return -1; } else if (responseType != LAUNCH_DATA_DICTIONARY) { fprintf(stderr, "Unknown error, aborting."); return -1; } // get socket launch_data_t sockets = launch_data_dict_lookup(checkinResponse, LAUNCH_JOBKEY_SOCKETS); launch_data_t ipcSocket = launch_data_dict_lookup(sockets, "IPC"); launch_data_t socket = launch_data_array_get_index(ipcSocket, 0); int fd = launch_data_get_fd(socket); // we're done with launchd, free all resources launch_data_free(checkinRequest); launch_data_free(checkinResponse); return fd; }
/* 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; }
/* * 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); } }
static PyObject* launch2python(launch_data_t data) { launch_data_type_t tp; tp = launch_data_get_type(data); switch (tp) { case LAUNCH_DATA_DICTIONARY: return launchdict2python(data); case LAUNCH_DATA_ARRAY: return launcharray2python(data); case LAUNCH_DATA_FD: return PyObject_CallFunction(file_descriptor_type, "i", launch_data_get_fd(data)); return NULL; case LAUNCH_DATA_INTEGER: return PyLong_FromLongLong(launch_data_get_integer(data)); case LAUNCH_DATA_REAL: return PyFloat_FromDouble(launch_data_get_real(data)); case LAUNCH_DATA_BOOL: return PyBool_FromLong(launch_data_get_bool(data)); case LAUNCH_DATA_STRING: return PyString_FromString(launch_data_get_string(data)); case LAUNCH_DATA_OPAQUE: return PyBuffer_FromMemory( launch_data_get_opaque(data), launch_data_get_opaque_size(data)); case LAUNCH_DATA_ERRNO: return PyObject_CallFunction(errno_type, "i", launch_data_get_errno(data)); default: PyErr_Format(PyExc_ValueError, "Unhandled launch data type (tag: %d)", (int)tp); return NULL; } }
static int get_listener_socket_from_launchd(void) { launch_data_t req, resp, socks; req = launch_data_new_string(LAUNCH_KEY_CHECKIN); if (req == NULL) { w_log(W_LOG_ERR, "unable to create LAUNCH_KEY_CHECKIN\n"); return -1; } resp = launch_msg(req); launch_data_free(req); if (resp == NULL) { w_log(W_LOG_ERR, "launchd checkin failed %s\n", strerror(errno)); return -1; } if (launch_data_get_type(resp) == LAUNCH_DATA_ERRNO) { w_log(W_LOG_ERR, "launchd checkin failed: %s\n", strerror(launch_data_get_errno(resp))); launch_data_free(resp); return -1; } socks = launch_data_dict_lookup(resp, LAUNCH_JOBKEY_SOCKETS); if (socks == NULL) { w_log(W_LOG_ERR, "launchd didn't provide any sockets\n"); launch_data_free(resp); return -1; } // the "sock" name here is coupled with the plist in main.c socks = launch_data_dict_lookup(socks, "sock"); if (socks == NULL) { w_log(W_LOG_ERR, "launchd: \"sock\" wasn't present in Sockets\n"); launch_data_free(resp); return -1; } return launch_data_get_fd(launch_data_array_get_index(socks, 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; }
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); }
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 }
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; }
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; }
/*! 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; }