Пример #1
0
void uh_chunk_vprintf(struct client *cl, const char *format, va_list arg)
{
	char buf[256];
	va_list arg2;
	int len;

	if (cl->state == CLIENT_STATE_CLEANUP)
		return;

	uloop_timeout_set(&cl->timeout, conf.network_timeout * 1000);
	if (!uh_use_chunked(cl)) {
		ustream_vprintf(cl->us, format, arg);
		return;
	}

	va_copy(arg2, arg);
	len = vsnprintf(buf, sizeof(buf), format, arg2);
	va_end(arg2);

	ustream_printf(cl->us, "%X\r\n", len);
	if (len < sizeof(buf))
		ustream_write(cl->us, buf, len, true);
	else
		ustream_vprintf(cl->us, format, arg);
	ustream_printf(cl->us, "\r\n", len);
}
Пример #2
0
int u_tcp_write(const char *buf, int len, bool more)
{
    if (usfd.stream.write_error)
        return -1;

	ustream_write(&usfd.stream, buf, len, more);

	return 0;
}
Пример #3
0
static int s_ustream_write(void *ctx, const unsigned char *buf, size_t len)
{
    struct ustream *s = ctx;
    int ret;

    ret = ustream_write(s, (const char *) buf, len, false);
    if (ret < 0 || s->write_error)
        return POLARSSL_ERR_NET_SEND_FAILED;

    return ret;
}
Пример #4
0
void uh_chunk_write(struct client *cl, const void *data, int len)
{
	bool chunked = uh_use_chunked(cl);

	if (cl->state == CLIENT_STATE_CLEANUP)
		return;

	uloop_timeout_set(&cl->timeout, conf.network_timeout * 1000);
	if (chunked)
		ustream_printf(cl->us, "%X\r\n", len);
	ustream_write(cl->us, data, len, true);
	if (chunked)
		ustream_printf(cl->us, "\r\n", len);
}
Пример #5
0
static int
s_ustream_write(BIO *b, const char *buf, int len)
{
	struct ustream *s;

	if (!buf || len <= 0)
		return 0;

	s = (struct ustream *)b->ptr;
	if (!s)
		return 0;

	if (s->write_error)
		return len;

	return ustream_write(s, buf, len, false);
}
Пример #6
0
static bool
rpc_plugin_lookup_plugin(struct ubus_context *ctx, struct ubus_object *obj,
                         char *strptr)
{
	struct rpc_plugin_lookup_context c = { .id = obj->id, .name = strptr };

	if (ubus_lookup(ctx, NULL, rpc_plugin_lookup_plugin_cb, &c))
		return false;

	return c.found;
}

struct call_context {
	char path[PATH_MAX];
	const char *argv[4];
	char *method;
	char *input;
	json_tokener *tok;
	json_object *obj;
	bool input_done;
	bool output_done;
};

static int
rpc_plugin_call_stdin_cb(struct ustream *s, void *priv)
{
	struct call_context *c = priv;

	if (!c->input_done)
	{
		ustream_write(s, c->input, strlen(c->input), false);
		c->input_done = true;
	}

	return 0;
}

static int
rpc_plugin_call_stdout_cb(struct blob_buf *blob, char *buf, int len, void *priv)
{
	struct call_context *c = priv;

	if (!c->output_done)
	{
		c->obj = json_tokener_parse_ex(c->tok, buf, len);

		if (json_tokener_get_error(c->tok) != json_tokener_continue)
			c->output_done = true;
	}

	return len;
}

static int
rpc_plugin_call_stderr_cb(struct blob_buf *blob, char *buf, int len, void *priv)
{
	return len;
}

static int
rpc_plugin_call_finish_cb(struct blob_buf *blob, int stat, void *priv)
{
	struct call_context *c = priv;
	int rv = UBUS_STATUS_INVALID_ARGUMENT;

	if (json_tokener_get_error(c->tok) == json_tokener_success)
	{
		if (c->obj)
		{
			if (json_object_get_type(c->obj) == json_type_object &&
			    blobmsg_add_object(blob, c->obj))
				rv = UBUS_STATUS_OK;

			json_object_put(c->obj);
		}
		else
		{
			rv = UBUS_STATUS_NO_DATA;
		}
	}

	json_tokener_free(c->tok);

	free(c->input);
	free(c->method);

	return rv;
}

static int
rpc_plugin_call(struct ubus_context *ctx, struct ubus_object *obj,
                struct ubus_request_data *req, const char *method,
                struct blob_attr *msg)
{
	int rv = UBUS_STATUS_UNKNOWN_ERROR;
	struct call_context *c;
	char *plugin;

	c = calloc(1, sizeof(*c));

	if (!c)
		goto fail;

	c->method = strdup(method);
	c->input = blobmsg_format_json(msg, true);
	c->tok = json_tokener_new();

	if (!c->method || !c->input || !c->tok)
		goto fail;

	plugin = c->path + sprintf(c->path, "%s/", RPC_PLUGIN_DIRECTORY);

	if (!rpc_plugin_lookup_plugin(ctx, obj, plugin))
	{
		rv = UBUS_STATUS_NOT_FOUND;
		goto fail;
	}

	c->argv[0] = c->path;
	c->argv[1] = "call";
	c->argv[2] = c->method;

	return rpc_exec(c->argv, rpc_plugin_call_stdin_cb,
	                rpc_plugin_call_stdout_cb, rpc_plugin_call_stderr_cb,
	                rpc_plugin_call_finish_cb, c, ctx, req);

fail:
	if (c)
	{
		if (c->method)
			free(c->method);

		if (c->input)
			free(c->input);

		if (c->tok)
			json_tokener_free(c->tok);

		free(c);
	}

	return rv;
}
Пример #7
0
int ustream_vprintf(struct ustream *s, const char *format, va_list arg)
{
	struct ustream_buf_list *l = &s->w;
	char *buf;
	va_list arg2;
	int wr, maxlen, buflen;

	if (s->write_error)
		return 0;

	if (!l->data_bytes) {
		buf = alloca(MAX_STACK_BUFLEN);
		va_copy(arg2, arg);
		maxlen = vsnprintf(buf, MAX_STACK_BUFLEN, format, arg2);
		va_end(arg2);
		if (maxlen < MAX_STACK_BUFLEN) {
			wr = s->write(s, buf, maxlen, false);
			if (wr < 0) {
				ustream_write_error(s);
				return wr;
			}
			if (wr == maxlen)
				return wr;

			buf += wr;
			maxlen -= wr;
			return ustream_write_buffered(s, buf, maxlen, wr);
		} else {
			buf = malloc(maxlen + 1);
			wr = vsnprintf(buf, maxlen + 1, format, arg);
			wr = ustream_write(s, buf, wr, false);
			free(buf);
			return wr;
		}
	}

	if (!ustream_prepare_buf(s, l, 1))
		return 0;

	buf = l->data_tail->tail;
	buflen = l->data_tail->end - buf;

	va_copy(arg2, arg);
	maxlen = vsnprintf(buf, buflen, format, arg2);
	va_end(arg2);

	wr = maxlen;
	if (wr >= buflen)
		wr = buflen - 1;

	l->data_tail->tail += wr;
	l->data_bytes += wr;
	if (maxlen < buflen)
		return wr;

	buf = malloc(maxlen + 1);
	maxlen = vsnprintf(buf, maxlen + 1, format, arg);
	wr = ustream_write_buffered(s, buf + wr, maxlen - wr, wr);
	free(buf);

	return wr;
}