static int
my_com_netsplit_Nih_Test_colour_set (NihDBusObject *  object,
                                     NihDBusMessage * message,
                                     DBusMessageIter *iter)
{
	DBusMessageIter variter;
	const char *    value_dbus;
	char *          value;

	nih_assert (object != NULL);
	nih_assert (message != NULL);
	nih_assert (iter != NULL);

	/* Recurse into the variant */
	if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_VARIANT) {
		nih_dbus_error_raise_printf (DBUS_ERROR_INVALID_ARGS,
		                             "Invalid arguments to colour property");
		return -1;
	}

	dbus_message_iter_recurse (iter, &variter);

	/* Demarshal a char * from the message */
	if (dbus_message_iter_get_arg_type (&variter) != DBUS_TYPE_STRING) {
		nih_dbus_error_raise_printf (DBUS_ERROR_INVALID_ARGS,
		                             "Invalid arguments to colour property");
		return -1;
	}

	dbus_message_iter_get_basic (&variter, &value_dbus);

	value = nih_strdup (message, value_dbus);
	if (! value) {
		nih_error_raise_no_memory ();
		return -1;
	}

	dbus_message_iter_next (&variter);

	dbus_message_iter_next (iter);

	if (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_INVALID) {
		nih_dbus_error_raise_printf (DBUS_ERROR_INVALID_ARGS,
		                             "Invalid arguments to colour property");
		return -1;
	}

	/* Call the handler function */
	if (my_test_set_colour (object->data, message, value) < 0)
		return -1;

	return 0;
}
Esempio n. 2
0
int get_pid_cgroup_abs_main (void *parent, char *controller,
		struct ucred p, struct ucred r, struct ucred v, char **output)
{
	DBusMessage *message;
	DBusMessageIter iter;
	int sv[2], ret = -1;
	char s[MAXPATHLEN] = { 0 };

	if (memcmp(&p, &r, sizeof(struct ucred)) != 0) {
		nih_error("%s: proxy != requestor", __func__);
		return -1;
	}

	if (!(message = start_dbus_request("GetPidCgroupAbsScm", sv))) {
		nih_error("%s: error starting dbus request", __func__);
		return -1;
	}

	dbus_message_iter_init_append(message, &iter);
	if (!dbus_message_iter_append_basic (&iter,
			DBUS_TYPE_STRING,
			&controller)) {
		dbus_message_unref(message);
		nih_error("%s: out of memory", __func__);
		goto out;
	}
	if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_UNIX_FD, &sv[1])) {
		dbus_message_unref(message);
		nih_error("%s: out of memory", __func__);
		goto out;
	}

	if (!complete_dbus_request(message, sv, &r, &v)) {
		nih_error("%s: error completing dbus request", __func__);
		goto out;
	}

	if (proxyrecv(sv[0], s, MAXPATHLEN-1) <= 0)
		nih_error("%s: Error reading result from cgmanager",
			__func__);
	else {
		*output = NIH_MUST( nih_strdup(parent, s) );
		ret = 0;
	}
out:
	close(sv[0]);
	close(sv[1]);
	return ret;
}
Esempio n. 3
0
static void get_active_controllers(void)
{
	int i;
	nih_local char **list = cgm_list_controllers();

	if (!list) {
		mysyslog(LOG_NOTICE, "unable to detect controllers");
		ctrl_list = NIH_MUST( nih_strdup(NULL, "all") );
		return;
	}
	for (i = 0; list[i]; i++) {
		if (strcmp(list[i], "name=systemd") == 0)
			continue;
		NIH_MUST( nih_strcat_sprintf(&ctrl_list, NULL, "%s%s",
			ctrl_list ? "," : "", list[i]) );
	}
}
Esempio n. 4
0
char *get_my_cgroup()
{
	char line[1024], *ret = NULL;
	FILE *f = fopen("/proc/self/cgroup", "r");

	while (fgets(line, 1024, f)) {
		char *p, *p2;
		if ((p = strchr(line, ':')) == NULL)
			continue;
		p++;
		if ((p2 = strchr(p, ':')) == NULL)
			continue;
		if (strncmp(p, "name=", 5) == 0)
			continue;
		ret = NIH_MUST( nih_strdup(NULL, p2+1) );
		break;
	}
	fclose(f);
	return ret;
}
Esempio n. 5
0
/**
 * nih_dbus_error_raise_printf:
 * @name: D-Bus name for error,
 * @format: format string for human-readable message.
 *
 * Raises an error which includes a D-Bus name so that it may be sent as
 * a reply to a method call, the error type is fixed to NIH_DBUS_ERROR.
 *
 * The human-readable message for the error is parsed according to @format,
 * and allocated as a child of the error object so that it is freed.
 *
 * You may use this in D-Bus handlers and return a negative number to
 * automatically have this error returned as the method reply.  It is also
 * useful when mixing D-Bus and libnih function calls in your own methods
 * to return consistent error forms, in which case pass the name and message
 * members of the DBusError structure before freeing it.
 **/
void
nih_dbus_error_raise_printf (const char *name,
			     const char *format,
			     ...)
{
	NihDBusError *err;
	va_list       args;

	nih_assert (name != NULL);
	nih_assert (format != NULL);

	err = NIH_MUST (nih_new (NULL, NihDBusError));

	err->number = NIH_DBUS_ERROR;

	err->name = NIH_MUST (nih_strdup (err, name));

	va_start (args, format);
	err->message = NIH_MUST (nih_vsprintf (err, format, args));
	va_end (args);

	nih_error_raise_error ((NihError *)err);
}
Esempio n. 6
0
/**
 * session_new:
 * @parent: parent,
 * @chroot: full chroot path,
 * @user: user id.
 *
 * Create a new session.
 *
 * Return new Session, or NULL on error.
 **/
Session *
session_new (const void *parent,
	     const char *chroot,
	     uid_t       user)
{
	Session *session;

	nih_assert ((chroot != NULL) || (user != 0));

	session_init ();

	session = nih_new (parent, Session);
	if (! session)
		return NULL;

	nih_list_init (&session->entry);

	if (chroot) {
		session->chroot = nih_strdup (session, chroot);
		if (! session->chroot) {
			nih_free (session);
			return NULL;
		}
	} else {
		session->chroot = NULL;
	}

	session->user = user;

	session->conf_path = NULL;

	nih_alloc_set_destructor (session, nih_list_destroy);

	nih_list_add (sessions, &session->entry);

	return session;
}
Esempio n. 7
0
/**
 * _nih_error_raise_system:
 * @filename: filename where the error was raised,
 * @line: line number of @filename where the error was raised,
 * @function: function name the error was raised within.
 *
 * Raises an error with details taken from the current value of errno,
 * if an unhandled error already exists then an error message is emmitted
 * through the logging system; you should try to avoid this.
 *
 * This function should never be called directly, instead use the
 * nih_error_raise_system() macro to pass the correct arguments for @filename,
 * @line and @function.
 **/
void
_nih_error_raise_system (const char *filename,
			 int         line,
			 const char *function)
{
	NihError *error;
	int       saved_errno;

	nih_assert (filename != NULL);
	nih_assert (line > 0);
	nih_assert (function != NULL);
	nih_assert (errno > 0);
	saved_errno = errno;

	nih_error_init ();

	error = NIH_MUST (nih_new (NULL, NihError));

	error->number = saved_errno;
	error->message = NIH_MUST (nih_strdup (error, strerror (saved_errno)));

	_nih_error_raise_error (filename, line, function, error);
	errno = saved_errno;
}
int
my_method_sync (const void *        parent,
                NihDBusProxy *      proxy,
                MyMethodStructure **structure)
{
	DBusMessage *      method_call;
	DBusMessageIter    iter;
	DBusError          error;
	DBusMessage *      reply;
	MyMethodStructure *structure_local;
	DBusMessageIter    structure_local_iter;
	const char *       structure_local_item0_dbus;
	char *             structure_local_item0;
	uint32_t           structure_local_item1;

	nih_assert (proxy != NULL);
	nih_assert (structure != NULL);

	/* Construct the method call message. */
	method_call = dbus_message_new_method_call (proxy->name, proxy->path, "com.netsplit.Nih.Test", "Method");
	if (! method_call)
		nih_return_no_memory_error (-1);

	dbus_message_set_auto_start (method_call, proxy->auto_start);

	dbus_message_iter_init_append (method_call, &iter);

	/* Send the message, and wait for the reply. */
	dbus_error_init (&error);

	reply = dbus_connection_send_with_reply_and_block (proxy->connection, method_call, -1, &error);
	if (! reply) {
		dbus_message_unref (method_call);

		if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY)) {
			nih_error_raise_no_memory ();
		} else {
			nih_dbus_error_raise (error.name, error.message);
		}

		dbus_error_free (&error);
		return -1;
	}

	dbus_message_unref (method_call);

	/* Iterate the arguments of the reply */
	dbus_message_iter_init (reply, &iter);

	do {
		__label__ enomem;

		/* Demarshal a structure from the message */
		if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRUCT) {
			dbus_message_unref (reply);
			nih_return_error (-1, NIH_DBUS_INVALID_ARGS,
			                  _(NIH_DBUS_INVALID_ARGS_STR));
		}

		dbus_message_iter_recurse (&iter, &structure_local_iter);

		structure_local = nih_new (parent, MyMethodStructure);
		if (! structure_local) {
			*structure = NULL;
			goto enomem;
		}

		/* Demarshal a char * from the message */
		if (dbus_message_iter_get_arg_type (&structure_local_iter) != DBUS_TYPE_STRING) {
			nih_free (structure_local);
			dbus_message_unref (reply);
			nih_return_error (-1, NIH_DBUS_INVALID_ARGS,
			                  _(NIH_DBUS_INVALID_ARGS_STR));
		}

		dbus_message_iter_get_basic (&structure_local_iter, &structure_local_item0_dbus);

		structure_local_item0 = nih_strdup (structure_local, structure_local_item0_dbus);
		if (! structure_local_item0) {
			nih_free (structure_local);
			*structure = NULL;
			goto enomem;
		}

		dbus_message_iter_next (&structure_local_iter);

		structure_local->item0 = structure_local_item0;

		/* Demarshal a uint32_t from the message */
		if (dbus_message_iter_get_arg_type (&structure_local_iter) != DBUS_TYPE_UINT32) {
			nih_free (structure_local);
			dbus_message_unref (reply);
			nih_return_error (-1, NIH_DBUS_INVALID_ARGS,
			                  _(NIH_DBUS_INVALID_ARGS_STR));
		}

		dbus_message_iter_get_basic (&structure_local_iter, &structure_local_item1);

		dbus_message_iter_next (&structure_local_iter);

		structure_local->item1 = structure_local_item1;

		if (dbus_message_iter_get_arg_type (&structure_local_iter) != DBUS_TYPE_INVALID) {
			nih_free (structure_local);
			dbus_message_unref (reply);
			nih_return_error (-1, NIH_DBUS_INVALID_ARGS,
			                  _(NIH_DBUS_INVALID_ARGS_STR));
		}

		dbus_message_iter_next (&iter);

		*structure = structure_local;
	enomem: __attribute__ ((unused));
	} while (! *structure);

	if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID) {
		nih_free (structure_local);
		*structure = NULL;
		dbus_message_unref (reply);
		nih_return_error (-1, NIH_DBUS_INVALID_ARGS,
		                  _(NIH_DBUS_INVALID_ARGS_STR));
	}

	dbus_message_unref (reply);

	return 0;
}
Esempio n. 9
0
int list_children_main (void *parent, char *controller, const char *cgroup,
		    struct ucred p, struct ucred r, char ***output)
{
	DBusMessage *message;
	DBusMessageIter iter;
	int sv[2], ret = -1;
	uint32_t len;
	int32_t nrkids;
	nih_local char * paths = NULL;
	char *s;
	int i;

	*output = NULL;
	if (memcmp(&p, &r, sizeof(struct ucred)) != 0) {
		nih_error("%s: proxy != requestor", __func__);
		return -1;
	}

	if (!sane_cgroup(cgroup)) {
		nih_error("%s: unsafe cgroup", __func__);
		return -1;
	}

	if (!(message = start_dbus_request("ListChildrenScm", sv))) {
		nih_error("%s: error starting dbus request", __func__);
		return -1;
	}

	dbus_message_iter_init_append(message, &iter);
	if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &controller)) {
		nih_error("%s: out of memory", __func__);
		dbus_message_unref(message);
		goto out;
	}
	if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &cgroup)) {
		nih_error("%s: out of memory", __func__);
		dbus_message_unref(message);
		goto out;
	}
	if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_UNIX_FD, &sv[1])) {
		nih_error("%s: out of memory", __func__);
		dbus_message_unref(message);
		goto out;
	}

	if (!complete_dbus_request(message, sv, &r, NULL)) {
		nih_error("%s: error completing dbus request", __func__);
		goto out;
	}

	if (proxyrecv(sv[0], &nrkids, sizeof(int32_t)) != sizeof(int32_t))
		goto out;
	if (nrkids == 0) {
		ret = 0;
		goto out;
	}
	if (nrkids < 0) {
		nih_error("%s: Server encountered an error: bad cgroup?", __func__);
		ret = -1;
		goto out;
	}
	if (proxyrecv(sv[0], &len, sizeof(uint32_t)) != sizeof(uint32_t))
		goto out;

	paths = nih_alloc(NULL, len+1);
	paths[len] = '\0';
	if (read(sv[0], paths, len) != len) {
		nih_error("%s: Failed getting paths from server", __func__);
		goto out;
	}

	*output = NIH_MUST( nih_alloc(parent, sizeof( char*)*(nrkids+1)) );
	memset(*output, 0, (nrkids + 1) * sizeof(char *));

	s = paths;
	for (i=0; i<nrkids; i++) {
		if (s > paths + len) {
			ret = -1;
			nih_error("%s: corrupted result from cgmanager",
					__func__);
			goto out;
		}
		(*output)[i] = NIH_MUST( nih_strdup(parent, s) );
		s += strlen(s) + 1;
	}
	ret = nrkids;
out:
	close(sv[0]);
	close(sv[1]);
	return ret;
}
Esempio n. 10
0
int get_value_main (void *parent, char *controller, const char *cgroup,
		 const char *key, struct ucred p, struct ucred r, char **value)
{
	DBusMessage *message;
	DBusMessageIter iter;
	int sv[2], ret = -1;
	char output[MAXPATHLEN] = { 0 };

	if (memcmp(&p, &r, sizeof(struct ucred)) != 0) {
		nih_error("%s: proxy != requestor", __func__);
		return -1;
	}

	if (!sane_cgroup(cgroup)) {
		nih_error("%s: unsafe cgroup", __func__);
		return -1;
	}

	if (!(message = start_dbus_request("GetValueScm", sv))) {
		nih_error("%s: error starting dbus request", __func__);
		return -1;
	}

	dbus_message_iter_init_append(message, &iter);
	if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &controller)) {
		nih_error("%s: out of memory", __func__);
		dbus_message_unref(message);
		goto out;
	}
	if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &cgroup)) {
		nih_error("%s: out of memory", __func__);
		dbus_message_unref(message);
		goto out;
	}
	if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key)) {
		nih_error("%s: out of memory", __func__);
		dbus_message_unref(message);
		goto out;
	}
	if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_UNIX_FD, &sv[1])) {
		nih_error("%s: out of memory", __func__);
		dbus_message_unref(message);
		goto out;
	}

	if (!complete_dbus_request(message, sv, &r, NULL)) {
		nih_error("%s: error completing dbus request", __func__);
		goto out;
	}

	if (proxyrecv(sv[0], output, MAXPATHLEN) <= 0) {
		nih_error("%s: Failed reading string from cgmanager: %s",
			__func__, strerror(errno));
	} else {
		*value = NIH_MUST( nih_strdup(parent, output) );
		ret = 0;
	}
out:
	close(sv[0]);
	close(sv[1]);
	return ret;
}
static DBusHandlerResult
my_com_netsplit_Nih_Test_Poke_method (NihDBusObject * object,
                                      NihDBusMessage *message)
{
	DBusMessageIter iter;
	DBusMessage *   reply;
	uint32_t        address;
	char *          value;
	const char *    value_dbus;

	nih_assert (object != NULL);
	nih_assert (message != NULL);

	/* Iterate the arguments to the message and demarshal into arguments
	 * for our own function call.
	 */
	dbus_message_iter_init (message->message, &iter);

	/* Demarshal a uint32_t from the message */
	if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32) {
		reply = dbus_message_new_error (message->message, DBUS_ERROR_INVALID_ARGS,
		                                "Invalid arguments to Poke method");
		if (! reply)
			return DBUS_HANDLER_RESULT_NEED_MEMORY;

		if (! dbus_connection_send (message->connection, reply, NULL)) {
			dbus_message_unref (reply);
			return DBUS_HANDLER_RESULT_NEED_MEMORY;
		}

		dbus_message_unref (reply);
		return DBUS_HANDLER_RESULT_HANDLED;
	}

	dbus_message_iter_get_basic (&iter, &address);

	dbus_message_iter_next (&iter);

	/* Demarshal a char * from the message */
	if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING) {
		reply = dbus_message_new_error (message->message, DBUS_ERROR_INVALID_ARGS,
		                                "Invalid arguments to Poke method");
		if (! reply)
			return DBUS_HANDLER_RESULT_NEED_MEMORY;

		if (! dbus_connection_send (message->connection, reply, NULL)) {
			dbus_message_unref (reply);
			return DBUS_HANDLER_RESULT_NEED_MEMORY;
		}

		dbus_message_unref (reply);
		return DBUS_HANDLER_RESULT_HANDLED;
	}

	dbus_message_iter_get_basic (&iter, &value_dbus);

	value = nih_strdup (message, value_dbus);
	if (! value) {
		return DBUS_HANDLER_RESULT_NEED_MEMORY;
	}

	dbus_message_iter_next (&iter);

	if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID) {
		reply = dbus_message_new_error (message->message, DBUS_ERROR_INVALID_ARGS,
		                                "Invalid arguments to Poke method");
		if (! reply)
			return DBUS_HANDLER_RESULT_NEED_MEMORY;

		if (! dbus_connection_send (message->connection, reply, NULL)) {
			dbus_message_unref (reply);
			return DBUS_HANDLER_RESULT_NEED_MEMORY;
		}

		dbus_message_unref (reply);
		return DBUS_HANDLER_RESULT_HANDLED;
	}

	/* Call the handler function */
	nih_error_push_context ();
	if (my_test_poke (object->data, message, address, value) < 0) {
		NihError *err;

		err = nih_error_get ();
		if (err->number == ENOMEM) {
			nih_free (err);
			nih_error_pop_context ();

			return DBUS_HANDLER_RESULT_NEED_MEMORY;
		} else if (err->number == NIH_DBUS_ERROR) {
			NihDBusError *dbus_err = (NihDBusError *)err;

			reply = NIH_MUST (dbus_message_new_error (message->message, dbus_err->name, err->message));
			nih_free (err);
			nih_error_pop_context ();

			NIH_MUST (dbus_connection_send (message->connection, reply, NULL));

			dbus_message_unref (reply);
			return DBUS_HANDLER_RESULT_HANDLED;
		} else {
			reply = NIH_MUST (dbus_message_new_error (message->message, DBUS_ERROR_FAILED, err->message));
			nih_free (err);
			nih_error_pop_context ();

			NIH_MUST (dbus_connection_send (message->connection, reply, NULL));

			dbus_message_unref (reply);
			return DBUS_HANDLER_RESULT_HANDLED;
		}
	}
	nih_error_pop_context ();

	/* If the sender doesn't care about a reply, don't bother wasting
	 * effort constructing and sending one.
	 */
	if (dbus_message_get_no_reply (message->message))
		return DBUS_HANDLER_RESULT_HANDLED;

	do {
		__label__ enomem;

		/* Construct the reply message. */
		reply = dbus_message_new_method_return (message->message);
		if (! reply)
			goto enomem;

		dbus_message_iter_init_append (reply, &iter);
	enomem: __attribute__ ((unused));
	} while (! reply);

	/* Send the reply, appending it to the outgoing queue. */
	NIH_MUST (dbus_connection_send (message->connection, reply, NULL));

	dbus_message_unref (reply);

	return DBUS_HANDLER_RESULT_HANDLED;
}
Esempio n. 12
0
int list_keys_main (void *parent, char *controller, const char *cgroup,
		    struct ucred p, struct ucred r,
		    struct keys_return_type ***output)
{
	DBusMessage *message;
	DBusMessageIter iter;
	int sv[2], ret = -1;
	uint32_t len;
	int32_t nrkeys;
	nih_local char * results = NULL;
	char *s;
	int i;

	*output = NULL;
	if (memcmp(&p, &r, sizeof(struct ucred)) != 0) {
		nih_error("%s: proxy != requestor", __func__);
		return -1;
	}

	if (!sane_cgroup(cgroup)) {
		nih_error("%s: unsafe cgroup", __func__);
		return -1;
	}

	if (!(message = start_dbus_request("ListKeysScm", sv))) {
		nih_error("%s: error starting dbus request", __func__);
		return -1;
	}

	dbus_message_iter_init_append(message, &iter);
	if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &controller)) {
		nih_error("%s: out of memory", __func__);
		dbus_message_unref(message);
		goto out;
	}
	if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &cgroup)) {
		nih_error("%s: out of memory", __func__);
		dbus_message_unref(message);
		goto out;
	}
	if (! dbus_message_iter_append_basic (&iter, DBUS_TYPE_UNIX_FD, &sv[1])) {
		nih_error("%s: out of memory", __func__);
		dbus_message_unref(message);
		goto out;
	}

	if (!complete_dbus_request(message, sv, &r, NULL)) {
		nih_error("%s: error completing dbus request", __func__);
		goto out;
	}

	if (proxyrecv(sv[0], &nrkeys, sizeof(int32_t)) != sizeof(int32_t))
		goto out;
	if (nrkeys == 0) {
		ret = 0;
		goto out;
	}
	if (nrkeys < 0) {
		nih_error("%s: Server encountered an error: bad cgroup?", __func__);
		ret = -1;
		goto out;
	}
	if (proxyrecv(sv[0], &len, sizeof(uint32_t)) != sizeof(uint32_t))
		goto out;

	results = nih_alloc(NULL, len+1);
	results[len] = '\0';
	if (read(sv[0], results, len) != len) {
		nih_error("%s: Failed getting results from server", __func__);
		goto out;
	}

	*output = NIH_MUST( nih_alloc(parent, sizeof(**output)*(nrkeys+1)) );
	memset(*output, 0, (nrkeys + 1) * sizeof(**output));

	s = results;
	for (i=0; i<nrkeys; i++) {
		struct keys_return_type *tmp;
		char *s2 = find_eol(s);
		if (s2 > results + len)
			goto bad;
		*s2 = '\0';
		(*output)[i] = tmp = NIH_MUST( nih_new(*output, struct keys_return_type) );
		tmp->name = NIH_MUST( nih_strdup(tmp, s) );
		s = s2 + 1;
		s2 = find_eol(s);
		if (s2 > results + len)
			goto bad;
		if (sscanf(s, "%u\n", &tmp->uid) != 1)
			goto bad;
		s = s2 + 1;
		s2 = find_eol(s);
		if (sscanf(s, "%u\n", &tmp->gid) != 1)
			goto bad;
		s = s2 + 1;
		s2 = find_eol(s);
		if (sscanf(s, "%u\n", &tmp->perms) != 1)
			goto bad;
		s = s2 + 1;
	}
	ret = nrkeys;
out:
	close(sv[0]);
	close(sv[1]);
	return ret;

bad:
	ret = -1;
	nih_error("%s: corrupted result from cgmanager", __func__);
	goto out;
}
Esempio n. 13
0
void
test_strncat (void)
{
    char *str, *ret;

    TEST_FUNCTION ("nih_strncat");

    /* Check that we can extend a string with the first number of bytes
     * from another, resulting in the original string being modified and
     * the new pointer stored in the argument and returned.
     */
    TEST_FEATURE ("with larger string than length");
    TEST_ALLOC_FAIL {
        char *tmp;

        TEST_ALLOC_SAFE {
            str = nih_strdup (NULL, "this is a test");
        }

        tmp = str;
        ret = nih_strncat (&str, NULL, " of strndup", 3);

        if (test_alloc_failed) {
            TEST_EQ_P (ret, NULL);
            TEST_EQ_P (str, tmp);
            TEST_EQ_STR (str, "this is a test");

            nih_free (str);
            continue;
        }

        TEST_NE (ret, NULL);
        TEST_EQ_P (ret, str);

        TEST_ALLOC_SIZE (str, 18);
        TEST_EQ_STR (str, "this is a test of");

        nih_free (str);
    }


    /* Check that if a longer length than the string is given, enough
     * space is reserved but the string copy stops at the NULL.
     */
    TEST_FEATURE ("with larger length than string");
    TEST_ALLOC_FAIL {
        char *tmp;

        TEST_ALLOC_SAFE {
            str = nih_strdup (NULL, "this is a test");
        }

        tmp = str;
        ret = nih_strncat (&str, NULL, " of strndup", 21);

        if (test_alloc_failed) {
            TEST_EQ_P (ret, NULL);
            TEST_EQ_P (str, tmp);
            TEST_EQ_STR (str, "this is a test");

            nih_free (str);
            continue;
        }

        TEST_NE (ret, NULL);
        TEST_EQ_P (ret, str);

        TEST_ALLOC_SIZE (str, 36);
        TEST_EQ_STR (str, "this is a test of strndup");

        nih_free (str);
    }


    /* Check that when no string is passed, this behaves as strndup.
     */
    TEST_FEATURE ("with NULL");
    TEST_ALLOC_FAIL {
        str = NULL;
        ret = nih_strncat (&str, NULL, "test of strndup", 12);

        if (test_alloc_failed) {
            TEST_EQ_P (ret, NULL);
            TEST_EQ_P (str, NULL);
            continue;
        }

        TEST_NE (ret, NULL);
        TEST_EQ_P (ret, str);

        TEST_ALLOC_SIZE (str, 13);
        TEST_EQ_STR (str, "test of strn");

        nih_free (str);
    }
}
Esempio n. 14
0
void
test_cgroup_new (void)
{
	nih_local char *parent = NULL;
	CGroup         *cgroup;

	TEST_FUNCTION ("cgroup_new");

	parent = nih_strdup (NULL, "a parent object");
	TEST_NE_P (parent, NULL);

	TEST_FEATURE ("no parent, controller");
	TEST_ALLOC_FAIL {

		cgroup = cgroup_new (NULL, "cpuset");

		if (test_alloc_failed) {
			TEST_EQ_P (cgroup, NULL);
			continue;
		}

		TEST_NE_P (cgroup, NULL);

		TEST_ALLOC_SIZE (cgroup, sizeof (CGroup));

		TEST_ALLOC_PARENT (cgroup, NULL);

		TEST_EQ_STR (cgroup->controller, "cpuset");
		TEST_ALLOC_SIZE (cgroup->controller, 1+strlen ("cpuset"));
		TEST_ALLOC_PARENT (cgroup->controller, cgroup);

		TEST_LIST_EMPTY (&cgroup->names);

		nih_free (cgroup);
	}

	TEST_FEATURE ("parent, controller");
	TEST_ALLOC_FAIL {

		cgroup = cgroup_new (parent, "perf_event");

		if (test_alloc_failed) {
			TEST_EQ_P (cgroup, NULL);
			continue;
		}

		TEST_NE_P (cgroup, NULL);

		TEST_ALLOC_SIZE (cgroup, sizeof (CGroup));

		TEST_ALLOC_PARENT (cgroup, parent);

		TEST_EQ_STR (cgroup->controller, "perf_event");
		TEST_ALLOC_SIZE (cgroup->controller, 1+strlen ("perf_event"));
		TEST_ALLOC_PARENT (cgroup->controller, cgroup);

		TEST_LIST_EMPTY (&cgroup->names);

		nih_free (cgroup);
	}
}
void
my_com_netsplit_Nih_Test_property_get_notify (DBusPendingCall *   pending_call,
                                              NihDBusPendingData *pending_data)
{
	DBusMessage *   reply;
	DBusMessageIter iter;
	DBusMessageIter variter;
	NihDBusMessage *message;
	DBusError       error;
	const char *    value_dbus;
	char *          value;

	nih_assert (pending_call != NULL);
	nih_assert (pending_data != NULL);

	nih_assert (dbus_pending_call_get_completed (pending_call));

	/* Steal the reply from the pending call. */
	reply = dbus_pending_call_steal_reply (pending_call);
	nih_assert (reply != NULL);

	/* Handle error replies */
	if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
		message = NIH_MUST (nih_dbus_message_new (pending_data, pending_data->connection, reply));

		dbus_error_init (&error);
		dbus_set_error_from_message (&error, message->message);

		nih_error_push_context ();
		nih_dbus_error_raise (error.name, error.message);
		pending_data->error_handler (pending_data->data, message);
		nih_error_pop_context ();

		dbus_error_free (&error);
		nih_free (message);
		dbus_message_unref (reply);
		return;
	}

	nih_assert (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN);

	do {
		__label__ enomem;

		/* Create a message context for the reply, and iterate
		 * over and recurse into the arguments.
		 */
		message = nih_dbus_message_new (pending_data, pending_data->connection, reply);
		if (! message)
			goto enomem;

		dbus_message_iter_init (message->message, &iter);

		if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_VARIANT) {
			nih_error_push_context ();
			nih_error_raise (NIH_DBUS_INVALID_ARGS,
			                 _(NIH_DBUS_INVALID_ARGS_STR));
			pending_data->error_handler (pending_data->data, message);
			nih_error_pop_context ();

			nih_free (message);
			dbus_message_unref (reply);
			return;
		}

		dbus_message_iter_recurse (&iter, &variter);

		/* Demarshal a char * from the message */
		if (dbus_message_iter_get_arg_type (&variter) != DBUS_TYPE_STRING) {
			nih_error_push_context ();
			nih_error_raise (NIH_DBUS_INVALID_ARGS,
			                 _(NIH_DBUS_INVALID_ARGS_STR));
			pending_data->error_handler (pending_data->data, message);
			nih_error_pop_context ();

			nih_free (message);
			dbus_message_unref (reply);
			return;
		}

		dbus_message_iter_get_basic (&variter, &value_dbus);

		value = nih_strdup (message, value_dbus);
		if (! value) {
			nih_free (message);
			message = NULL;
			goto enomem;
		}

		dbus_message_iter_next (&variter);

		dbus_message_iter_next (&iter);

		if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID) {
			nih_error_push_context ();
			nih_error_raise (NIH_DBUS_INVALID_ARGS,
			                 _(NIH_DBUS_INVALID_ARGS_STR));
			pending_data->error_handler (pending_data->data, message);
			nih_error_pop_context ();

			nih_free (message);
			dbus_message_unref (reply);
			return;
		}

	enomem: __attribute__ ((unused));
	} while (! message);

	/* Call the handler function */
	nih_error_push_context ();
	((MyGetPropertyReply)pending_data->handler) (pending_data->data, message, value);
	nih_error_pop_context ();

	nih_free (message);
	dbus_message_unref (reply);
}
Esempio n. 16
0
void
test_libupstart (void)
{
	nih_local NihDBusProxy  *upstart = NULL;
	nih_local char          *version = NULL;
	int                      ret;
	pid_t                    upstart_pid;
	pid_t                    dbus_pid;
	char                     xdg_runtime_dir[PATH_MAX];
	nih_local char          *orig_xdg_runtime_dir = NULL;
	nih_local char          *session_file = NULL;
	nih_local char          *path = NULL;

	TEST_GROUP ("libupstart");

	TEST_FEATURE ("version");

        TEST_FILENAME (xdg_runtime_dir);
        TEST_EQ (mkdir (xdg_runtime_dir, 0755), 0);

	/* Take care to avoid disrupting users environment by saving and
	 * restoring this variable (assuming the tests all pass...).
	 */
	orig_xdg_runtime_dir = getenv ("XDG_RUNTIME_DIR");
	if (orig_xdg_runtime_dir)
		orig_xdg_runtime_dir = NIH_MUST (nih_strdup (NULL, orig_xdg_runtime_dir));

	assert0 (setenv ("XDG_RUNTIME_DIR", xdg_runtime_dir, 1));

	/*******************************************************************/

	/* Create a private Session Init instance to connect to */
	TEST_DBUS (dbus_pid);
	START_UPSTART (upstart_pid, TRUE);

	upstart = upstart_open (NULL);
	TEST_NE_P (upstart, NULL);

	/* Basic test (that does not change the state of the system
	 * running this test) to see if we can query version of running
	 * Upstart instance.
	 */
	ret = upstart_get_version_sync (NULL, upstart, &version);
	TEST_EQ (ret, 0);

	nih_message ("Running instance version: '%s'", version);
	assert0 (fnmatch ("init (upstart*)", version, 0x0));

	STOP_UPSTART (upstart_pid);
	TEST_DBUS_END (dbus_pid);

	/*******************************************************************/

	if (orig_xdg_runtime_dir) {
		/* restore */
		setenv ("XDG_RUNTIME_DIR", orig_xdg_runtime_dir, 1);
	} else {
		assert0 (unsetenv ("XDG_RUNTIME_DIR"));
	}

	session_file = get_session_file (xdg_runtime_dir, upstart_pid);
	unlink (session_file);

	/* Remove the directory tree the Session Init created */
	path = NIH_MUST (nih_sprintf (NULL, "%s/upstart/sessions", xdg_runtime_dir));
        assert0 (rmdir (path));
	path = NIH_MUST (nih_sprintf (NULL, "%s/upstart", xdg_runtime_dir));
        assert0 (rmdir (path));

        assert0 (rmdir (xdg_runtime_dir));
}
Esempio n. 17
0
/**
 * warning_message:
 * @message: user message.
 *
 * Prefixes the message with details about how long until the shutdown
 * completes.
 *
 * Returns: newly allocated string.
 **/
static char *
warning_message (const char *message)
{
	nih_local char *banner = NULL;
	char *          msg;

	nih_assert (message != NULL);

	if ((runlevel == '0')
	    && init_halt && (! strcmp (init_halt, "POWEROFF"))) {
		if (delay) {
			banner = nih_sprintf (
				NULL, _n("The system is going down for "
					 "power off in %d minute!",
					 "The system is going down for "
					 "power off in %d minutes!",
					 delay), delay);
		} else {
			banner = nih_strdup (
				NULL, _("The system is going down for "
					"power off NOW!"));
		}
	} else if (runlevel == '0') {
		if (delay) {
			banner = nih_sprintf (
				NULL, _n("The system is going down for "
					 "halt in %d minute!",
					 "The system is going down for "
					 "halt in %d minutes!",
					 delay), delay);
		} else {
			banner = nih_strdup (
				NULL, _("The system is going down for "
					"halt NOW!"));
		}
	} else if (runlevel == '1') {
		if (delay) {
			banner = nih_sprintf (
				NULL, _n("The system is going down for "
					 "maintenance in %d minute!",
					 "The system is going down for "
					 "maintenance in %d minutes!",
					 delay), delay);
		} else {
			banner = nih_strdup (
				NULL, _("The system is going down for "
					"maintenance NOW!"));
		}
	} else if (runlevel == '6') {
		if (delay) {
			banner = nih_sprintf (
				NULL, _n("The system is going down for "
					 "reboot in %d minute!",
					 "The system is going down for "
					 "reboot in %d minutes!",
					 delay), delay);
		} else {
			banner = nih_strdup (
				NULL, _("The system is going down for "
					"reboot NOW!"));
		}
	}

	if (! banner)
		return NULL;

	msg = nih_sprintf (NULL, "\r%s\r\n%s", banner, message);

	return msg;
}
Esempio n. 18
0
int
main (int   argc,
      char *argv[])
{
	char **         args;
	nih_local char *message = NULL;
	size_t          messagelen;
	nih_local char *msg = NULL;
	int             arg;
	pid_t           pid = 0;

	nih_main_init (argv[0]);

	nih_option_set_usage (_("TIME [MESSAGE]"));
	nih_option_set_synopsis (_("Bring the system down."));
	nih_option_set_help (
		_("TIME may have different formats, the most common is simply "
		  "the word 'now' which will bring the system down "
		  "immediately.  Other valid formats are +m, where m is the "
		  "number of minutes to wait until shutting down and hh:mm "
		  "which specifies the time on the 24hr clock.\n"
		  "\n"
		  "Logged in users are warned by a message sent to their "
		  "terminal, you may include an optional MESSAGE included "
		  "with this.  Messages can be sent without actually "
		  "bringing the system down by using the -k option.\n"
		  "\n"
		  "If TIME is given, the command will remain in the "
		  "foreground until the shutdown occurs.  It can be cancelled "
		  "by Control-C, or by another user using the -c option.\n"
		  "\n"
		  "The system is brought down into maintenance (single-user) "
		  "mode by default, you can change this with either the -r or "
		  "-h option which specify a reboot or system halt "
		  "respectively.  The -h option can be further modified with "
		  "-H or -P to specify whether to halt the system, or to "
		  "power it off afterwards.  The default is left up to the "
		  "shutdown scripts."));

	args = nih_option_parser (NULL, argc, argv, options, FALSE);
	if (! args)
		exit (1);

	/* If the runlevel wasn't given explicitly, set it to 1 so we go
	 * down into single-user mode.
	 */
	if (! runlevel) {
		runlevel = '1';
		init_halt = NULL;
	}


	/* When may be specified with -g, or must be first argument */
	if (! (cancel || when || args[0])) {
		fprintf (stderr, _("%s: time expected\n"), program_name);
		nih_main_suggest_help ();
		exit (1);
	} else if (! (cancel || when)) {
		when = NIH_MUST (nih_strdup (NULL, args[0]));
		arg = 1;
	} else {
		arg = 0;
	}

	/* Parse the time argument */
	if (when) {
		if (! strcmp (when, "now")) {
			/* "now" means, err, now */
			delay = 0;
		} else if (strchr (when, ':')) {
			/* Clock time */
			long       hours, mins;
			char      *endptr;
			struct tm *tm;
			time_t     now;

			hours = strtoul (when, &endptr, 10);
			if ((*endptr != ':') || (hours < 0) || (hours > 23)) {
				fprintf (stderr, _("%s: illegal hour value\n"),
					 program_name);
				nih_main_suggest_help ();
				exit (1);
			}

			mins = strtoul (endptr + 1, &endptr, 10);
			if (*endptr || (mins < 0) || (mins > 59)) {
				fprintf (stderr,
					 _("%s: illegal minute value\n"),
					 program_name);
				nih_main_suggest_help ();
				exit (1);
			}

			/* Subtract the current time to get the delay.
			 * Add a whole day if we go negative */
			now = time (NULL);
			tm = localtime (&now);
			delay = (((hours * 60) + mins)
				 - ((tm->tm_hour * 60) + tm->tm_min));
			if (delay < 0)
				delay += 1440;
		} else {
			/* Delay in minutes */
			char *endptr;

			delay = strtoul (when, &endptr, 10);
			if (*endptr || (delay < 0)) {
				fprintf (stderr, _("%s: illegal time value\n"),
					 program_name);
				nih_main_suggest_help ();
				exit (1);
			}
		}
		nih_free (when);
	}


	/* The rest of the arguments are a message.
	 * Really this should be just the next argument, but that's not
	 * how this has been traditionally done *sigh*
	 */
	message = NIH_MUST (nih_strdup (NULL, ""));
	messagelen = 0;
	for (; args[arg]; arg++) {
		message = NIH_MUST (nih_realloc (
				  message, NULL,
				  messagelen + strlen(args[arg]) + 4));

		strcat (message, args[arg]);
		strcat (message, " ");
		messagelen += strlen (args[arg]) + 1;
	}

	/* Terminate with \r\n */
	if (messagelen)
		strcat (message, "\r\n");


	/* Check we're root, or setuid root */
	setuid (geteuid ());
	if (getuid ()) {
		nih_fatal (_("Need to be root"));
		exit (1);
	}

	/* Look for an existing pid file and deal with the existing
	 * process if there is one.
	 */
	pid = nih_main_read_pidfile ();
	if (pid > 0) {
		if (cancel) {
			if (kill (pid, SIGINT) < 0) {
				nih_error (_("Shutdown is not running"));
				exit (1);
			}

			if (messagelen)
				wall (message);

			exit (0);
		} else if (kill (pid, 0) == 0) {
			nih_error (_("Another shutdown is already running"));
			exit (1);
		}
	} else if (cancel) {
		nih_error (_("Cannot find pid of running shutdown"));
		exit (1);
	}

	/* Send an initial message */
	msg = NIH_MUST (warning_message (message));
	wall (msg);

	if (warn_only)
		exit (0);


	/* Give us a sane environment */
	if (chdir ("/") < 0)
		nih_warn ("%s: %s", _("Unable to change directory"),
			  strerror (errno));
	umask (022);

	/* Shutdown now? */
	if (! delay)
		shutdown_now ();

	/* Save our pid so we can be interrupted later */
	if (nih_main_write_pidfile (getpid ()) < 0) {
		NihError *err;

		err = nih_error_get ();
		nih_warn ("%s: %s: %s", nih_main_get_pidfile(),
			  _("Unable to write pid file"), err->message);
		nih_free (err);
	}


	/* Ignore a whole bunch of signals */
	nih_signal_set_ignore (SIGCHLD);
	nih_signal_set_ignore (SIGHUP);
	nih_signal_set_ignore (SIGTSTP);
	nih_signal_set_ignore (SIGTTIN);
	nih_signal_set_ignore (SIGTTOU);

	/* Catch the usual quit signals */
	nih_signal_set_handler (SIGINT, nih_signal_handler);
	NIH_MUST (nih_signal_add_handler (NULL, SIGINT,
					  cancel_callback, NULL));
	nih_signal_set_handler (SIGQUIT, nih_signal_handler);
	NIH_MUST (nih_signal_add_handler (NULL, SIGQUIT,
					  cancel_callback, NULL));
	nih_signal_set_handler (SIGTERM, nih_signal_handler);
	NIH_MUST (nih_signal_add_handler (NULL, SIGTERM,
					  cancel_callback, NULL));

	/* Call a timer every minute until we shutdown */
	NIH_MUST (nih_timer_add_periodic (NULL, 60,
					  (NihTimerCb)timer_callback,
					  message));

	/* Hang around */
	nih_main_loop ();

	return 0;
}
Esempio n. 19
0
void
test_strcat_vsprintf (void)
{
    char *str, *ret;

    TEST_FUNCTION ("test_strcat_vsprintf");

    /* Check that we can extend a string with a formatted string,
     * resulting in the original string being modified and the new
     * pointer stored in the argument and returned.
     */
    TEST_FEATURE ("with original string");
    TEST_ALLOC_FAIL {
        char *tmp;

        TEST_ALLOC_SAFE {
            str = nih_strdup (NULL, "this");
        }

        tmp = str;
        ret = my_strcat_vsprintf (&str, NULL,
        " %s a test %d", "is", 54321);

        if (test_alloc_failed) {
            TEST_EQ_P (ret, NULL);
            TEST_EQ_P (str, tmp);
            TEST_EQ_STR (str, "this");

            nih_free (str);
            continue;
        }

        TEST_NE (ret, NULL);
        TEST_EQ_P (ret, str);

        TEST_ALLOC_SIZE (str, 21);
        TEST_EQ_STR (str, "this is a test 54321");

        nih_free (str);
    }


    /* Check that when no string is passed, this behaves as sprintf.
     */
    TEST_FEATURE ("with NULL");
    TEST_ALLOC_FAIL {
        str = NULL;
        ret = my_strcat_vsprintf (&str, NULL,
        "%s a test %d", "is", 54321);

        if (test_alloc_failed) {
            TEST_EQ_P (ret, NULL);
            TEST_EQ_P (str, NULL);
            continue;
        }

        TEST_NE (ret, NULL);
        TEST_EQ_P (ret, str);

        TEST_ALLOC_SIZE (str, 15);
        TEST_EQ_STR (str, "is a test 54321");

        nih_free (str);
    }
}
Esempio n. 20
0
int
main (int   argc,
      char *argv[])
{
	NihList              prototypes;
	NihList              typedefs;
	NihList              structs;
	nih_local Interface *interface = NULL;
	nih_local Property * property = NULL;
	nih_local char *     code = NULL;
	nih_local char *     block = NULL;

	printf ("#include <dbus/dbus.h>\n"
		"\n"
		"#include <nih/macros.h>\n"
		"#include <nih/alloc.h>\n"
		"#include <nih/string.h>\n"
		"#include <nih/logging.h>\n"
		"#include <nih/error.h>\n"
		"\n"
		"#include <nih-dbus/dbus_error.h>\n"
		"#include <nih-dbus/dbus_message.h>\n"
		"#include <nih-dbus/dbus_object.h>\n"
		"#include <nih-dbus/dbus_pending_data.h>\n"
		"#include <nih-dbus/dbus_proxy.h>\n"
		"#include <nih-dbus/errors.h>\n"
		"\n"
		"#include \"tests/interface_code.h\"\n"
		"\n"
		"\n");

	interface = interface_new (NULL, "com.netsplit.Nih.Test");
	interface->symbol = NULL;

	property = property_new (interface, "name", "s", NIH_DBUS_READWRITE);
	property->symbol = nih_strdup (property, "name");
	nih_list_add (&interface->properties, &property->entry);

	property = property_new (interface, "size", "u", NIH_DBUS_READWRITE);
	property->symbol = nih_strdup (property, "size");
	nih_list_add (&interface->properties, &property->entry);


	nih_list_init (&prototypes);
	nih_list_init (&structs);

	interface->name = "com.netsplit.Nih.TestA";

	code = interface_proxy_get_all_function (NULL, "my", interface,
						 &prototypes, &structs);

	printf ("extern void my_com_netsplit_Nih_TestA_get_all_notify (DBusPendingCall *pending_call, "
		"NihDBusPendingData *pending_data);\n");
	printf ("\n");

	printf ("%s"
		"\n", code);


	nih_list_init (&prototypes);
	nih_list_init (&typedefs);
	nih_list_init (&structs);

	interface->name = "com.netsplit.Nih.Test";

	code = interface_proxy_get_all_notify_function (NULL, "my", interface,
							&prototypes, &typedefs,
							&structs);

	printf ("%s", code);
	printf ("\n"
		"\n");


	nih_list_init (&prototypes);
	nih_list_init (&structs);

	code = interface_proxy_get_all_sync_function (NULL, "my", interface,
						      &prototypes, &structs);

	printf ("%s"
		"\n", code);

	return 0;
}
Esempio n. 21
0
/**
 * type_of:
 * @parent: parent object for new string,
 * @iter: D-Bus signature iterator.
 *
 * Converts the D-Bus basic type at the current element of the iterator
 * @iter into an appropriate C type to hold it.
 *
 * If @parent is not NULL, it should be a pointer to another object which
 * will be used as a parent for the returned string.  When all parents
 * of the returned string are freed, the returned string will also be
 * freed.
 *
 * Returns: newly allocated string or NULL if allocation failed.
 **/
char *
type_of (const void *       parent,
	 DBusSignatureIter *iter)
{
	int dbus_type;

	nih_assert (iter != NULL);

	dbus_type = dbus_signature_iter_get_current_type (iter);

	switch (dbus_type) {
	case DBUS_TYPE_BYTE:
		return nih_strdup (parent, "uint8_t");
	case DBUS_TYPE_BOOLEAN:
		return nih_strdup (parent, "int");
	case DBUS_TYPE_INT16:
		return nih_strdup (parent, "int16_t");
	case DBUS_TYPE_UINT16:
		return nih_strdup (parent, "uint16_t");
	case DBUS_TYPE_INT32:
		return nih_strdup (parent, "int32_t");
	case DBUS_TYPE_UINT32:
		return nih_strdup (parent, "uint32_t");
	case DBUS_TYPE_INT64:
		return nih_strdup (parent, "int64_t");
	case DBUS_TYPE_UINT64:
		return nih_strdup (parent, "uint64_t");
	case DBUS_TYPE_DOUBLE:
		return nih_strdup (parent, "double");
	case DBUS_TYPE_STRING:
		return nih_strdup (parent, "char *");
	case DBUS_TYPE_OBJECT_PATH:
		return nih_strdup (parent, "char *");
	case DBUS_TYPE_SIGNATURE:
		return nih_strdup (parent, "char *");
	case DBUS_TYPE_UNIX_FD:
		return nih_strdup (parent, "int");
	default:
		nih_assert_not_reached ();
	}
}
Esempio n. 22
0
void
test_cgroup_setting_new (void)
{
	CGroupSetting   *setting;
	nih_local char  *parent= NULL;

	parent = nih_strdup (NULL, "a parent object");
	TEST_NE_P (parent, NULL);

	TEST_FUNCTION ("cgroup_setting_new");

	TEST_FEATURE ("no parent, key, no value");
	TEST_ALLOC_FAIL {
		setting = cgroup_setting_new (NULL, "foo", NULL);

		if (test_alloc_failed) {
			TEST_EQ_P (setting, NULL);
			continue;
		}

		TEST_ALLOC_SIZE (setting, sizeof (CGroupSetting));
		TEST_ALLOC_PARENT (setting, NULL);
		TEST_EQ_STR (setting->key, "foo");
		TEST_ALLOC_SIZE (setting->key, 1+strlen ("foo"));
		TEST_ALLOC_PARENT (setting->key, setting);

		nih_free (setting);
	}

	TEST_FEATURE ("parent, key, no value");
	TEST_ALLOC_FAIL {
		setting = cgroup_setting_new (parent, "hello world", NULL);

		if (test_alloc_failed) {
			TEST_EQ_P (setting, NULL);
			continue;
		}

		TEST_ALLOC_SIZE (setting, sizeof (CGroupSetting));
		TEST_ALLOC_PARENT (setting, parent);
		TEST_EQ_STR (setting->key, "hello world");
		TEST_ALLOC_SIZE (setting->key, 1+strlen ("hello world"));
		TEST_ALLOC_PARENT (setting->key, setting);

		nih_free (setting);
	}

	TEST_FEATURE ("no parent, key, value");
	TEST_ALLOC_FAIL {
		setting = cgroup_setting_new (NULL, "hello world", "a value");

		if (test_alloc_failed) {
			TEST_EQ_P (setting, NULL);
			continue;
		}

		TEST_ALLOC_SIZE (setting, sizeof (CGroupSetting));
		TEST_ALLOC_PARENT (setting, NULL);

		TEST_EQ_STR (setting->key, "hello world");
		TEST_ALLOC_SIZE (setting->key, 1+strlen ("hello world"));
		TEST_ALLOC_PARENT (setting->key, setting);

		TEST_EQ_STR (setting->value, "a value");
		TEST_ALLOC_SIZE (setting->value, 1+strlen ("a value"));
		TEST_ALLOC_PARENT (setting->value, setting);

		nih_free (setting);
	}

	TEST_FEATURE ("parent, key, value");
	TEST_ALLOC_FAIL {
		setting = cgroup_setting_new (parent, "hello world", "a value");

		if (test_alloc_failed) {
			TEST_EQ_P (setting, NULL);
			continue;
		}

		TEST_ALLOC_SIZE (setting, sizeof (CGroupSetting));
		TEST_ALLOC_PARENT (setting, parent);

		TEST_EQ_STR (setting->key, "hello world");
		TEST_ALLOC_SIZE (setting->key, 1+strlen ("hello world"));
		TEST_ALLOC_PARENT (setting->key, setting);

		TEST_EQ_STR (setting->value, "a value");
		TEST_ALLOC_SIZE (setting->value, 1+strlen ("a value"));
		TEST_ALLOC_PARENT (setting->value, setting);

		nih_free (setting);
	}
}
Esempio n. 23
0
int list_controllers_main (void *parent, char ***output)
{
	DBusMessage *message = NULL, *reply = NULL;
	char **         output_local = NULL;
	DBusError       error;
	DBusMessageIter iter;
	int		ret = -1;
	DBusMessageIter output_local_iter;
	size_t          output_local_size;

	*output = NULL;
	message = dbus_message_new_method_call(dbus_bus_get_unique_name(server_conn),
			"/org/linuxcontainers/cgmanager",
			"org.linuxcontainers.cgmanager0_0", "ListControllers");

	dbus_error_init (&error);

	reply = dbus_connection_send_with_reply_and_block (server_conn, message, -1, &error);
	if (! reply) {
		dbus_message_unref (message);

		nih_error("%s: error completing dbus request: %s %s", __func__,
			error.name, error.message);

		dbus_error_free (&error);
		return -1;
	}
	dbus_message_unref (message);

	dbus_message_iter_init (reply, &iter);

	if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)
		goto out;

	dbus_message_iter_recurse (&iter, &output_local_iter);

	output_local_size = 0;
	output_local = NULL;

	output_local = NIH_MUST( nih_alloc (parent, sizeof (char *)) );

	output_local[output_local_size] = NULL;

	while (dbus_message_iter_get_arg_type (&output_local_iter) != DBUS_TYPE_INVALID) {
		const char *output_local_element_dbus;
		char **     output_local_tmp;
		char *      output_local_element;

		if (dbus_message_iter_get_arg_type (&output_local_iter) != DBUS_TYPE_STRING)
			goto out;

		dbus_message_iter_get_basic (&output_local_iter, &output_local_element_dbus);

		output_local_element = NIH_MUST( nih_strdup (output_local, output_local_element_dbus) );

		dbus_message_iter_next (&output_local_iter);

		output_local_tmp = NIH_MUST( nih_realloc (output_local, parent, sizeof (char *) * (output_local_size + 2)) );

		output_local = output_local_tmp;
		output_local[output_local_size] = output_local_element;
		output_local[output_local_size + 1] = NULL;

		output_local_size++;
	}

	dbus_message_iter_next (&iter);

	if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID)
		goto out;

	*output = output_local;

	ret = 0;

out:
	if (reply)
		dbus_message_unref (reply);
	if (ret)
		nih_free (output_local);
	return ret;
}
Esempio n. 24
0
	max = 0;
	NIH_LIST_FOREACH (vars, iter) {
		TypeVar *var = (TypeVar *)iter;
		size_t   this_len;

		this_len = strlen (var->type);
		if (! strchr (var->type, '*'))
			this_len++;

		if (this_len > max)
			max = this_len;
	}

	/* Allocate a string with each of the variables on each line. */
	len = 0;
	str = nih_strdup (parent, "");
	if (! str)
		return NULL;

	NIH_LIST_FOREACH (vars, iter) {
		TypeVar *var = (TypeVar *)iter;
		char *   new_str;

		new_str = nih_realloc (str, parent,
				       (len + max + strlen (var->name)
					+ (var->array ? 2 : 0) + 3));
		if (! new_str) {
			nih_free (str);
			return NULL;
		}
Esempio n. 25
0
void
test_strcat (void)
{
    char *str, *ret;

    TEST_FUNCTION ("nih_strcat");

    /* Check that we can extend a string with another, resulting in the
     * original string being modified and the new pointer stored in the
     * argument and returned.
     */
    TEST_FEATURE ("with string");
    TEST_ALLOC_FAIL {
        char *tmp;

        TEST_ALLOC_SAFE {
            str = nih_strdup (NULL, "this is a test");
        }

        tmp = str;
        ret = nih_strcat (&str, NULL, " of strdup");

        if (test_alloc_failed) {
            TEST_EQ_P (ret, NULL);
            TEST_EQ_P (str, tmp);
            TEST_EQ_STR (str, "this is a test");

            nih_free (str);
            continue;
        }

        TEST_NE (ret, NULL);
        TEST_EQ_P (ret, str);

        TEST_ALLOC_SIZE (str, 25);
        TEST_EQ_STR (str, "this is a test of strdup");

        nih_free (str);
    }


    /* Check that when no string is passed, this behaves as strdup.
     */
    TEST_FEATURE ("with NULL");
    TEST_ALLOC_FAIL {
        str = NULL;
        ret = nih_strcat (&str, NULL, "test of strdup");

        if (test_alloc_failed) {
            TEST_EQ_P (ret, NULL);
            TEST_EQ_P (str, NULL);
            continue;
        }

        TEST_NE (ret, NULL);
        TEST_EQ_P (ret, str);

        TEST_ALLOC_SIZE (str, 15);
        TEST_EQ_STR (str, "test of strdup");

        nih_free (str);
    }
}
Esempio n. 26
0
int remove_main(const char *controller, const char *cgroup, struct ucred p,
		struct ucred r, int recursive, int32_t *existed)
{
	char rcgpath[MAXPATHLEN];
	size_t cgroup_len;
	nih_local char *working = NULL, *copy = NULL, *wcgroup = NULL;
	char *p1;

	*existed = 1;

	if (!sane_cgroup(cgroup)) {
		nih_error("%s: unsafe cgroup", __func__);
		return -1;
	}

	// Get r's current cgroup in rcgpath
	if (!compute_pid_cgroup(r.pid, controller, "", rcgpath, NULL)) {
		nih_error("%s: Could not determine the requested cgroup", __func__);
		return -1;
	}

	cgroup_len = strlen(cgroup);

	if (strlen(rcgpath) + cgroup_len > MAXPATHLEN) {
		nih_error("%s: Path name too long", __func__);
		return -1;
	}

	wcgroup = NIH_MUST( nih_strdup(NULL, cgroup) );
	if (!normalize_path(wcgroup))
		return -1;

	working = NIH_MUST( nih_strdup(NULL, rcgpath) );
	NIH_MUST( nih_strcat(&working, NULL, "/") );
	NIH_MUST( nih_strcat(&working, NULL, wcgroup) );

	if (!dir_exists(working)) {
		*existed = -1;
		return 0;
	}
	// must have write access to the parent dir
	copy = NIH_MUST( nih_strdup(NULL, working) );
	if (!(p1 = strrchr(copy, '/')))
		return -1;
	*p1 = '\0';
	if (!may_access(r.pid, r.uid, r.gid, copy, O_WRONLY)) {
		nih_error("%s: pid %d (%u:%u) may not remove %s", __func__,
			r.pid, r.uid, r.gid, copy);
		return -1;
	}

	if (!recursive) {
		if (rmdir(working) < 0) {
			nih_error("%s: Failed to remove %s: %s", __func__, working, strerror(errno));
			return -1;
		}
	} else if (recursive_rmdir(working) < 0)
			return -1;

	nih_info(_("Removed %s for %d (%u:%u)"), working, r.pid,
		 r.uid, r.gid);
	return 0;
}
void
my_com_netsplit_Nih_Test_get_all_notify (DBusPendingCall *   pending_call,
                                         NihDBusPendingData *pending_data)
{
	DBusMessage *   reply;
	DBusMessageIter iter;
	DBusMessageIter arrayiter;
	DBusMessageIter dictiter;
	DBusMessageIter variter;
	NihDBusMessage *message;
	DBusError       error;
	const char *    property;
	MyProperties *  properties;
	size_t          property_count;
	char *          name;
	const char *    name_dbus;
	uint32_t        size;

	nih_assert (pending_call != NULL);
	nih_assert (pending_data != NULL);

	nih_assert (dbus_pending_call_get_completed (pending_call));

	/* Steal the reply from the pending call. */
	reply = dbus_pending_call_steal_reply (pending_call);
	nih_assert (reply != NULL);

	/* Handle error replies */
	if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
		message = NIH_MUST (nih_dbus_message_new (pending_data, pending_data->connection, reply));

		dbus_error_init (&error);
		dbus_set_error_from_message (&error, message->message);

		nih_error_push_context ();
		nih_dbus_error_raise (error.name, error.message);
		pending_data->error_handler (pending_data->data, message);
		nih_error_pop_context ();

		dbus_error_free (&error);
		nih_free (message);
		dbus_message_unref (reply);
		return;
	}

	nih_assert (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN);

	/* Create a message context for the reply, and iterate
	 * over and recurse into the arguments.
	 */
	message = NIH_MUST (nih_dbus_message_new (pending_data, pending_data->connection, reply));

	/* Iterate the method arguments, recursing into the array */
	dbus_message_iter_init (reply, &iter);

	if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) {
		nih_error_push_context ();
		nih_error_raise (NIH_DBUS_INVALID_ARGS,
		                 _(NIH_DBUS_INVALID_ARGS_STR));
		pending_data->error_handler (pending_data->data, message);
		nih_error_pop_context ();

		nih_free (message);
		dbus_message_unref (reply);
		return;
	}

	properties = NIH_MUST (nih_new (message, MyProperties));
	property_count = 0;

	dbus_message_iter_recurse (&iter, &arrayiter);

	while (dbus_message_iter_get_arg_type (&arrayiter) != DBUS_TYPE_INVALID) {
		__label__ enomem;

		if (dbus_message_iter_get_arg_type (&arrayiter) != DBUS_TYPE_DICT_ENTRY) {
			nih_error_push_context ();
			nih_error_raise (NIH_DBUS_INVALID_ARGS,
			                 _(NIH_DBUS_INVALID_ARGS_STR));
			pending_data->error_handler (pending_data->data, message);
			nih_error_pop_context ();

			nih_free (message);
			dbus_message_unref (reply);
			return;
		}

		dbus_message_iter_recurse (&arrayiter, &dictiter);

		if (dbus_message_iter_get_arg_type (&dictiter) != DBUS_TYPE_STRING) {
			nih_error_push_context ();
			nih_error_raise (NIH_DBUS_INVALID_ARGS,
			                 _(NIH_DBUS_INVALID_ARGS_STR));
			pending_data->error_handler (pending_data->data, message);
			nih_error_pop_context ();

			nih_free (message);
			dbus_message_unref (reply);
			return;
		}

		dbus_message_iter_get_basic (&dictiter, &property);

		dbus_message_iter_next (&dictiter);

		if (dbus_message_iter_get_arg_type (&dictiter) != DBUS_TYPE_VARIANT) {
			nih_error_push_context ();
			nih_error_raise (NIH_DBUS_INVALID_ARGS,
			                 _(NIH_DBUS_INVALID_ARGS_STR));
			pending_data->error_handler (pending_data->data, message);
			nih_error_pop_context ();

			nih_free (message);
			dbus_message_unref (reply);
			return;
		}

		dbus_message_iter_recurse (&dictiter, &variter);

		if (! strcmp (property, "name")) {
			/* Demarshal a char * from the message */
			if (dbus_message_iter_get_arg_type (&variter) != DBUS_TYPE_STRING) {
				nih_error_push_context ();
				nih_error_raise (NIH_DBUS_INVALID_ARGS,
				                 _(NIH_DBUS_INVALID_ARGS_STR));
				pending_data->error_handler (pending_data->data, message);
				nih_error_pop_context ();

				nih_free (message);
				dbus_message_unref (reply);
				return;
			}

			dbus_message_iter_get_basic (&variter, &name_dbus);

			name = nih_strdup (properties, name_dbus);
			if (! name) {
				goto enomem;
			}

			dbus_message_iter_next (&variter);

			properties->name = name;

			nih_assert (++property_count);
		}

		if (! strcmp (property, "size")) {
			/* Demarshal a uint32_t from the message */
			if (dbus_message_iter_get_arg_type (&variter) != DBUS_TYPE_UINT32) {
				nih_error_push_context ();
				nih_error_raise (NIH_DBUS_INVALID_ARGS,
				                 _(NIH_DBUS_INVALID_ARGS_STR));
				pending_data->error_handler (pending_data->data, message);
				nih_error_pop_context ();

				nih_free (message);
				dbus_message_unref (reply);
				return;
			}

			dbus_message_iter_get_basic (&variter, &size);

			dbus_message_iter_next (&variter);

			properties->size = size;

			nih_assert (++property_count);
		}

		dbus_message_iter_next (&dictiter);

		if (dbus_message_iter_get_arg_type (&dictiter) != DBUS_TYPE_INVALID) {
			nih_error_push_context ();
			nih_error_raise (NIH_DBUS_INVALID_ARGS,
			                 _(NIH_DBUS_INVALID_ARGS_STR));
			pending_data->error_handler (pending_data->data, message);
			nih_error_pop_context ();

			nih_free (message);
			dbus_message_unref (reply);
			return;
		}

		dbus_message_iter_next (&arrayiter);
	enomem: __attribute__ ((unused));
	}

	dbus_message_iter_next (&iter);

	if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_INVALID) {
		nih_error_push_context ();
		nih_error_raise (NIH_DBUS_INVALID_ARGS,
		                 _(NIH_DBUS_INVALID_ARGS_STR));
		pending_data->error_handler (pending_data->data, message);
		nih_error_pop_context ();

		nih_free (message);
		dbus_message_unref (reply);
		return;
	}

	if (property_count < 2) {
		nih_error_push_context ();
		nih_error_raise (NIH_DBUS_INVALID_ARGS,
		                 _(NIH_DBUS_INVALID_ARGS_STR));
		pending_data->error_handler (pending_data->data, message);
		nih_error_pop_context ();

		nih_free (message);
		dbus_message_unref (reply);
		return;
	}

	/* Call the handler function */
	nih_error_push_context ();
	((MyGetAllReply)pending_data->handler) (pending_data->data, message, properties);
	nih_error_pop_context ();

	nih_free (message);
	dbus_message_unref (reply);
}