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); }
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; }
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; }
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); }
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); }
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; }
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; }