Exemplo n.º 1
0
static launch_data_t
to_launchd_sockets(json_t *json)
{
	launch_data_t result, arr;
	const char *key;
	size_t idx;
	json_t *val, *val2;

	result = launch_data_alloc(LAUNCH_DATA_DICTIONARY);

	json_object_foreach(json, key, val) {
		arr = launch_data_alloc(LAUNCH_DATA_ARRAY);

		switch (json_typeof(val)) {
			case JSON_OBJECT:
				launch_data_array_set_index(arr,
				    create_socket(val), 0);
				break;

			case JSON_ARRAY:
				json_array_foreach(val, idx, val2) {
					launch_data_array_set_index(arr,
					    create_socket(val2), idx);
				}
				break;

			default:
				errx(EX_OSERR, "Invalid jlist specification");
		}
launch_data_t launch_data_copy(launch_data_t o)
{
	launch_data_t r = launch_data_alloc(o->type);
	size_t i;

	memcpy(r, o, sizeof(struct _launch_data));

	switch (o->type) {
	case LAUNCH_DATA_DICTIONARY:
	case LAUNCH_DATA_ARRAY:
		r->_array = calloc(1, o->_array_cnt * sizeof(launch_data_t));
		for (i = 0; i < o->_array_cnt; i++) {
			if (o->_array[i])
				r->_array[i] = launch_data_copy(o->_array[i]);
		}
		break;
	case LAUNCH_DATA_STRING:
		r->string = strdup(o->string);
		break;
	case LAUNCH_DATA_OPAQUE:
		r->opaque = malloc(o->opaque_size);
		memcpy(r->opaque, o->opaque, o->opaque_size);
		break;
	default:
		break;
	}

	return r;
}
static launch_data_t GTMPerformOnLabel(const char *verb,
                                       CFStringRef jobLabel,
                                       CFErrorRef *error) {
  launch_data_t resp = NULL;
  launch_data_t label = GTMLaunchDataCreateFromCFType(jobLabel, error);
  if (*error == NULL) {
    launch_data_t msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
    launch_data_dict_insert(msg, label, verb);
    resp = launch_msg(msg);
    launch_data_free(msg);
    if (!resp) {
      *error = GTMCFLaunchCreateUnlocalizedError(errno, CFSTR(""));
    }
  }
  return resp;
}
Exemplo n.º 4
0
bool
launchd_job_status(const char * job, LaunchJobStatus& info)
{
	launch_data_t resp;
	launch_data_t msg;

	msg = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
	if (msg == NULL) {
	    throw std::runtime_error("out of memory");
	}

	launch_data_dict_insert(msg, launch_data_new_string(job),
				LAUNCH_KEY_GETJOB);

	resp = launch_msg(msg);
	launch_data_free(msg);

	if (resp == NULL) {
	    LAUNCHD_MSG_ERR(job, LAUNCH_KEY_GETJOB);
	    return false;
	}

	switch (launch_data_get_type(resp)) {
	case LAUNCH_DATA_DICTIONARY:
	    fill_job_info(resp, NULL, &info);
	    launch_data_free(resp);
	    return true;

	case LAUNCH_DATA_ERRNO:
	    errno = launch_data_get_errno(resp);
	    launch_data_free(resp);
	    if (errno != 0) {
		LAUNCHD_MSG_ERR(job, LAUNCH_KEY_GETJOB);
		return false;
	    }

	    return true;

	default:
	    LAUNCHD_MSG_ERRMSG(job, LAUNCH_KEY_GETJOB,
		    "unexpected respose type %d",
		    launch_data_get_type(resp));
	    launch_data_free(resp);
	    return false;
	}

}
static void launch_client_init(void)
{
	struct sockaddr_un sun;
	char *where = getenv(LAUNCHD_SOCKET_ENV);
	char *_launchd_fd = getenv("__LAUNCHD_FD");
	int lfd;
	
	_lc = calloc(1, sizeof(struct _launch_client));

	if (!_lc)
		return;

	pthread_mutex_init(&_lc->mtx, NULL);

	if (_launchd_fd) {
		lfd = strtol(_launchd_fd, NULL, 10);
	} else {
		if (!where)
			where = "/var/run/launchd.socket";

		memset(&sun, 0, sizeof(sun));
		sun.sun_family = AF_UNIX;

		strncpy(sun.sun_path, where, sizeof(sun.sun_path));

		if ((lfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
			goto out_bad;
		if (connect(lfd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
			close(lfd);
			goto out_bad;
		}
	}
	if (!(_lc->l = launchd_fdopen(lfd))) {
		close(lfd);
		goto out_bad;
	}
	if (!(_lc->async_resp = launch_data_alloc(LAUNCH_DATA_ARRAY)))
		goto out_bad;

	return;
out_bad:
	if (_lc->l)
		launchd_close(_lc->l);
	if (_lc)
		free(_lc);
	_lc = NULL;
}
bool launch_data_dict_insert(launch_data_t dict, launch_data_t what, const char *key)
{
	size_t i;
	launch_data_t thekey = launch_data_alloc(LAUNCH_DATA_STRING);

	launch_data_set_string(thekey, key);

	for (i = 0; i < dict->_array_cnt; i += 2) {
		if (!strcmp(key, dict->_array[i]->string)) {
			launch_data_array_set_index(dict, thekey, i);
			launch_data_array_set_index(dict, what, i + 1);
			return true;
		}
	}
	launch_data_array_set_index(dict, thekey, i);
	launch_data_array_set_index(dict, what, i + 1);
	return true;
}
Exemplo n.º 7
0
static launch_data_t
python2launch(PyObject* object)
{
	launch_data_t result;

	if (PyDict_Check(object)) {
		/* PyMapping_Check doesn't work because a lot of sequence types
		 * are mappings as wel to support extended slices a[i:j:k]
		 */
		return pythondict2launch(object);
	} else if (PySequence_Check(object)) {
		return pythonarray2launch(object);
	} else if (PyInt_Check(object)) {
		long value = PyInt_AsLong(object);
		
		result = launch_data_alloc(LAUNCH_DATA_INTEGER);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_integer(result, value)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}
	} else if (PyLong_Check(object)) {
		long long value = PyLong_AsLongLong(object);

		result = launch_data_alloc(LAUNCH_DATA_INTEGER);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_integer(result, value)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}

	} else if (PyString_Check(object)) {
		char* value = PyString_AsString(object);

		result = launch_data_alloc(LAUNCH_DATA_STRING);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_string(result, value)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}

	} else if ((PyObject*)(object->ob_type) == file_descriptor_type) {
		long value = PyInt_AsLong(object);
		
		result = launch_data_alloc(LAUNCH_DATA_FD);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_fd(result, value)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}

	} else if ((PyObject*)(object->ob_type) == errno_type) {
		long value = PyInt_AsLong(object);
		
		result = launch_data_alloc(LAUNCH_DATA_ERRNO);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_errno(result, value)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}

	} else if (object->ob_type->tp_as_buffer != NULL) {
		PyBufferProcs* bp = object->ob_type->tp_as_buffer;
		void* ptr;
		size_t size;

		size = bp->bf_getreadbuffer(object, 0, &ptr);
		if (size == (size_t)-1) {
			return NULL;
		}

		result = launch_data_alloc(LAUNCH_DATA_OPAQUE);
		if (result == NULL) {
			PyErr_SetString(PyExc_TypeError,
				"allocating launch_data_t failed");
			return NULL;
		}
		if (!launch_data_set_opaque(result, ptr, size)) {
			PyErr_SetString(PyExc_TypeError,
				"setting launch_data_t failed");
			launch_data_free(result);
			return NULL;
		}

	} else {
		PyErr_Format(PyExc_TypeError,
			"Don't know how to convert object of type %s to launch",
			object->ob_type->tp_name);
		return NULL;
	}
}
Exemplo n.º 8
0
void
launch_client_init(void)
{
	struct sockaddr_un sun;
	char *where = getenv(LAUNCHD_SOCKET_ENV);
	char *_launchd_fd = getenv(LAUNCHD_TRUSTED_FD_ENV);
	int dfd, lfd = -1, cifd = -1;
	kern_return_t kr;
	name_t spath;

	if (_launchd_fd) {
		cifd = strtol(_launchd_fd, NULL, 10);
		if ((dfd = dup(cifd)) >= 0) {
			close(dfd);
			_fd(cifd);
		} else {
			cifd = -1;
		}
		unsetenv(LAUNCHD_TRUSTED_FD_ENV);
	}

	memset(&sun, 0, sizeof(sun));
	sun.sun_family = AF_UNIX;

	/* The rules are as follows. 
	 * - All users (including root) talk to their per-user launchd's by default.
	 * - If we have been invoked under sudo, talk to the system launchd.
	 * - If we're the root user and the __USE_SYSTEM_LAUNCHD environment variable is set, then
	 *   talk to the system launchd.
	 */
	if (where && where[0] != '\0') {
		strncpy(sun.sun_path, where, sizeof(sun.sun_path));
	} else {
		kr = _vprocmgr_getsocket(spath);
		if (kr == 0) {
			if ((getenv("SUDO_COMMAND") || getenv("__USE_SYSTEM_LAUNCHD")) && geteuid() == 0) {
				/* Talk to the system launchd. */
				strncpy(sun.sun_path, LAUNCHD_SOCK_PREFIX "/sock", sizeof(sun.sun_path));
			} else {
				/* Talk to our per-user launchd. */
				size_t min_len;

				min_len = sizeof(sun.sun_path) < sizeof(spath) ? sizeof(sun.sun_path) : sizeof(spath);

				strncpy(sun.sun_path, spath, min_len);
			}
		} else
			fprintf(stderr, "_vprocmgr_getsocket(): 0x%x\n", kr);
	}

	launch_globals_t globals = _launch_globals();
	if ((lfd = _fd(socket(AF_UNIX, SOCK_STREAM, 0))) == -1) {
		goto out_bad;
	}

#if TARGET_OS_EMBEDDED
	(void)vproc_swap_integer(NULL, VPROC_GSK_EMBEDDEDROOTEQUIVALENT, NULL, &globals->s_am_embedded_god);
#endif
	if (-1 == connect(lfd, (struct sockaddr *)&sun, sizeof(sun))) {
		if (cifd != -1 || globals->s_am_embedded_god) {
			/* There is NO security enforced by this check. This is just a hint to our
			 * library that we shouldn't error out due to failing to open this socket. If
			 * we inherited a trusted file descriptor, we shouldn't fail. This should be
			 * adequate for clients' expectations.
			 */
			close(lfd);
			lfd = -1;
		} else {
			goto out_bad;
		}
	}
	
	if (!(globals->l = launchd_fdopen(lfd, cifd))) {
		goto out_bad;
	}

	if (!(globals->async_resp = launch_data_alloc(LAUNCH_DATA_ARRAY))) {
		goto out_bad;
	}

	return;
out_bad:
	if (globals->l) {
		launchd_close(globals->l, close);
		globals->l = NULL;
	} else if (lfd != -1) {
		close(lfd);
	}
	if (cifd != -1) {
		close(cifd);
	}
}
launch_data_t GTMLaunchDataCreateFromCFType(CFTypeRef cf_type_ref,
                                            CFErrorRef *error) {
  launch_data_t result = NULL;
  CFErrorRef local_error = NULL;
  if (cf_type_ref == NULL) {
    local_error = GTMCFLaunchCreateUnlocalizedError(EINVAL,
                                                    CFSTR("NULL CFType"));
    goto exit;
  }

  CFTypeID cf_type = CFGetTypeID(cf_type_ref);
  if (cf_type == CFStringGetTypeID()) {
    CFIndex length = CFStringGetLength(cf_type_ref);
    CFIndex max_length
      = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
    char *buffer = calloc(max_length, sizeof(char));
    size_t buffer_size = max_length * sizeof(char);
    if (buffer) {
      if (CFStringGetCString(cf_type_ref,
                             buffer,
                             buffer_size,
                             kCFStringEncodingUTF8)) {
        result = launch_data_alloc(LAUNCH_DATA_STRING);
        launch_data_set_string(result, buffer);
      } else {
        local_error
          = GTMCFLaunchCreateUnlocalizedError(EINVAL,
                                              CFSTR("CFStringGetCString failed %@"),
                                              cf_type_ref);
      }
      free(buffer);
    } else {
      local_error = GTMCFLaunchCreateUnlocalizedError(ENOMEM,
                                                      CFSTR("calloc of %zu failed"),
                                                      buffer_size);
    }
  } else if (cf_type == CFBooleanGetTypeID()) {
    result = launch_data_alloc(LAUNCH_DATA_BOOL);
    launch_data_set_bool(result, CFBooleanGetValue(cf_type_ref));
  } else if (cf_type == CFArrayGetTypeID()) {
    CFIndex count = CFArrayGetCount(cf_type_ref);
    result = launch_data_alloc(LAUNCH_DATA_ARRAY);
    for (CFIndex i = 0; i < count; i++) {
      CFTypeRef array_value = CFArrayGetValueAtIndex(cf_type_ref, i);
      if (array_value) {
        launch_data_t launch_value
          = GTMLaunchDataCreateFromCFType(array_value, &local_error);
        if (local_error) break;
        launch_data_array_set_index(result, launch_value, i);
      }
    }
  } else if (cf_type == CFDictionaryGetTypeID()) {
    result = launch_data_alloc(LAUNCH_DATA_DICTIONARY);
    GTMCFToLDictContext context = { result, &local_error };
    CFDictionaryApplyFunction(cf_type_ref,
                              GTMConvertCFDictEntryToLaunchDataDictEntry,
                              &context);
  } else if (cf_type == CFDataGetTypeID()) {
    result = launch_data_alloc(LAUNCH_DATA_OPAQUE);
    launch_data_set_opaque(result,
                           CFDataGetBytePtr(cf_type_ref),
                           CFDataGetLength(cf_type_ref));
  } else if (cf_type == CFNumberGetTypeID()) {
    CFNumberType cf_number_type = CFNumberGetType(cf_type_ref);
    switch (cf_number_type) {
      case kCFNumberSInt8Type:
      case kCFNumberSInt16Type:
      case kCFNumberSInt32Type:
      case kCFNumberSInt64Type:
      case kCFNumberCharType:
      case kCFNumberShortType:
      case kCFNumberIntType:
      case kCFNumberLongType:
      case kCFNumberLongLongType:
      case kCFNumberCFIndexType:
      case kCFNumberNSIntegerType:{
        long long value;
        if (CFNumberGetValue(cf_type_ref, kCFNumberLongLongType, &value)) {
          result = launch_data_alloc(LAUNCH_DATA_INTEGER);
          launch_data_set_integer(result, value);
        } else {
          local_error
            = GTMCFLaunchCreateUnlocalizedError(EINVAL,
                                                CFSTR("Unknown to convert: %@"),
                                                cf_type_ref);
        }
        break;
      }

      case kCFNumberFloat32Type:
      case kCFNumberFloat64Type:
      case kCFNumberFloatType:
      case kCFNumberDoubleType:
      case kCFNumberCGFloatType: {
        double value;
        if (CFNumberGetValue(cf_type_ref, kCFNumberDoubleType, &value)) {
          result = launch_data_alloc(LAUNCH_DATA_REAL);
          launch_data_set_real(result, value);
        } else {
          local_error
            = GTMCFLaunchCreateUnlocalizedError(EINVAL,
                                                CFSTR("Unknown to convert: %@"),
                                                cf_type_ref);
        }
        break;
      }

      default:
        local_error
          = GTMCFLaunchCreateUnlocalizedError(EINVAL,
                                              CFSTR("Unknown CFNumberType %lld"),
                                              (long long)cf_number_type);
        break;
    }
  } else {
    local_error
      = GTMCFLaunchCreateUnlocalizedError(EINVAL,
                                          CFSTR("Unknown CFTypeID %lu"),
                                          cf_type);
  }

exit:
  if (error) {
    *error = local_error;
  } else if (local_error) {
#ifdef DEBUG
    CFShow(local_error);
#endif //  DEBUG
    CFRelease(local_error);
  }
  return result;
}