Ejemplo n.º 1
0
static gboolean angel_connection_read(liAngelConnection *acon, GError **err) {
	for ( ;; ) {
		if (!acon->parse.have_header) {
			gint32 magic;
			if (!angel_fill_buffer(acon, 8*4, err)) return FALSE;
			if (acon->in.data->len - acon->in.pos < 8*4) return TRUE; /* need more data */

			if (!li_angel_data_read_int32(&acon->in, &magic, err)) return FALSE;
			if (!li_angel_data_read_int32(&acon->in, &acon->parse.type, err)) return FALSE;
			if (!li_angel_data_read_int32(&acon->in, &acon->parse.id, err)) return FALSE;
			if (!li_angel_data_read_int32(&acon->in, &acon->parse.mod_len, err)) return FALSE;
			if (!li_angel_data_read_int32(&acon->in, &acon->parse.action_len, err)) return FALSE;
			if (!li_angel_data_read_int32(&acon->in, &acon->parse.error_len, err)) return FALSE;
			if (!li_angel_data_read_int32(&acon->in, &acon->parse.data_len, err)) return FALSE;
			if (!li_angel_data_read_int32(&acon->in, &acon->parse.missing_fds, err)) return FALSE;

			if (ANGEL_MAGIC != magic) {
				g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_INVALID_DATA,
					"Invalid magic: 0x%x (should be 0x%x)", (gint) magic, (gint) ANGEL_MAGIC);
				return FALSE;
			}

			acon->parse.body_size = acon->parse.mod_len + acon->parse.action_len + acon->parse.error_len + acon->parse.data_len;
			acon->parse.have_header = TRUE;
		}

		if (!angel_fill_buffer(acon, acon->parse.body_size, err)) return FALSE;
		if (acon->in.data->len - acon->in.pos < acon->parse.body_size) return TRUE; /* need more data */
		while (acon->parse.missing_fds > 0) {
			int fd = -1;
			switch (li_receive_fd(acon->fd, &fd)) {
			case 0:
				g_array_append_val(acon->parse.fds, fd);
				acon->parse.missing_fds--;
				break;
			case -1:
				g_set_error(err, LI_ANGEL_CONNECTION_ERROR, LI_ANGEL_CONNECTION_CLOSED,
					"receive fd error: %s", g_strerror(errno));
				return FALSE;
			case -2:
				return TRUE; /* need more data */
			}
		}

		acon->parse.have_header = FALSE;
		if (!li_angel_data_read_mem(&acon->in, &acon->parse.mod, acon->parse.mod_len, err)) return FALSE;
		if (!li_angel_data_read_mem(&acon->in, &acon->parse.action, acon->parse.action_len, err)) return FALSE;
		if (!li_angel_data_read_mem(&acon->in, &acon->parse.error, acon->parse.error_len, err)) return FALSE;
		if (!li_angel_data_read_mem(&acon->in, &acon->parse.data, acon->parse.data_len, err)) return FALSE;

		if (!angel_dispatch(acon, err)) return FALSE;

		g_string_truncate(acon->parse.error, 0);
		g_string_truncate(acon->parse.data, 0);
		g_array_set_size(acon->parse.fds, 0);
	}
}
Ejemplo n.º 2
0
gboolean li_angel_data_read_str  (liAngelBuffer *buf, GString **val, GError **err) {
	gint32 ilen;
	g_return_val_if_fail(err == NULL || *err == NULL, FALSE);

	if (buf->data->len - buf->pos < sizeof(gint32)) {
		return error_eof(err, "string-length");
	}
	memcpy(&ilen, buf->data->str + buf->pos, sizeof(ilen));
	buf->pos += sizeof(gint32);
	if (ilen < 0 || ilen > LI_ANGEL_DATA_MAX_STR_LEN) {
		buf->pos -= sizeof(gint32);
		g_set_error(err,
			LI_ANGEL_DATA_ERROR,
			LI_ANGEL_DATA_ERROR_INVALID_STRING_LENGTH,
			"String length in buffer invalid: %i", (gint) ilen);
		return FALSE;
	}
	if (!li_angel_data_read_mem(buf, val, (gsize) ilen, err)) {
		buf->pos -= sizeof(gint32);
		return FALSE;
	}
	return TRUE;
}