void sj_conf_emit_str(struct mbuf *b, const char *prefix, const char *s, const char *suffix) { mbuf_append(b, prefix, strlen(prefix)); /* TODO(rojer): JSON escaping. */ if (s != NULL) mbuf_append(b, s, strlen(s)); mbuf_append(b, suffix, strlen(suffix)); }
struct mg_str mg_url_encode_opt(const struct mg_str src, const struct mg_str safe, unsigned int flags) { const char *hex = (flags & MG_URL_ENCODE_F_UPPERCASE_HEX ? "0123456789ABCDEF" : "0123456789abcdef"); size_t i = 0; struct mbuf mb; mbuf_init(&mb, src.len); for (i = 0; i < src.len; i++) { const unsigned char c = *((const unsigned char *) src.p + i); if (isalnum(c) || mg_strchr(safe, c) != NULL) { mbuf_append(&mb, &c, 1); } else if (c == ' ' && (flags & MG_URL_ENCODE_F_SPACE_AS_PLUS)) { mbuf_append(&mb, "+", 1); } else { mbuf_append(&mb, "%", 1); mbuf_append(&mb, &hex[c >> 4], 1); mbuf_append(&mb, &hex[c & 15], 1); } } mbuf_append(&mb, "", 1); mbuf_trim(&mb); return mg_mk_str_n(mb.buf, mb.len - 1); }
void cc3200_console_cloud_putc(char c) { if (s_cctx.in_console || !s_cctx.initialized) return; s_cctx.in_console = 1; /* If console is overfull, drop old message(s). */ int max_buf = get_cfg()->console.mem_cache_size; while (s_cctx.buf.len >= max_buf) { int l = cc3200_console_next_msg_len(); if (l == 0) { l = s_cctx.buf.len; s_cctx.msg_in_progress = 0; } mbuf_remove(&s_cctx.buf, l); } /* Construct valid JSON from the get-go. */ if (!s_cctx.msg_in_progress) { /* Skip empty lines */ if (c == '\n') goto out; mbuf_append(&s_cctx.buf, "{\"msg\":\"", 8); s_cctx.msg_in_progress = 1; } if (c == '"' || c == '\\') { mbuf_append(&s_cctx.buf, "\\", 1); } if (c >= 0x20) mbuf_append(&s_cctx.buf, &c, 1); if (c == '\n') { mbuf_append(&s_cctx.buf, "\"}\n", 3); s_cctx.msg_in_progress = 0; } out: s_cctx.in_console = 0; }
static int ns_dns_encode_name(struct mbuf *io, const char *name, size_t len) { const char *s; unsigned char n; size_t pos = io->len; do { if ((s = strchr(name, '.')) == NULL) { s = name + len; } if (s - name > 127) { return -1; /* TODO(mkm) cover */ } n = s - name; /* chunk length */ mbuf_append(io, &n, 1); /* send length */ mbuf_append(io, name, n); if (*s == '.') { n++; } name += n; len -= n; } while (*s != '\0'); mbuf_append(io, "\0", 1); /* Mark end of host name */ return io->len - pos; }
static int console_flush_buffer(struct cache *cache) { LOG(LL_DEBUG, ("file id=%d", (int) s_last_file_id)); int ret = 0, fn_len, files_count; FILE *file = NULL; files_count = cache->file_names.len / FILENAME_LEN; if (files_count >= get_cfg()->console.file_cache_max) { LOG(LL_ERROR, ("Out of space")); ret = -1; /* Game is over, no space to flash buffer */ if (files_count == get_cfg()->console.file_cache_max) { mbuf_free(&cache->logs); mbuf_append(&cache->logs, s_out_of_space_msg, sizeof(s_out_of_space_msg) - 1); /* Let write last phrase */ } else { goto clean; } } char file_name[sizeof(LOG_FILENAME_BASE) + FILE_ID_LEN]; fn_len = c_snprintf(file_name, sizeof(file_name), FILENAME_PATTERN, LOG_FILENAME_BASE, s_last_file_id); if (fn_len != FILENAME_LEN - 1) { LOG(LL_ERROR, ("Wrong file name")); /* Internal error, should not happen */ ret = -1; goto clean; } file = fopen(file_name, "w"); if (file == NULL) { LOG(LL_ERROR, ("Failed to open %s", file_name)); ret = -1; goto clean; } /* Put data */ if (fwrite(cache->logs.buf, 1, cache->logs.len, file) != cache->logs.len) { LOG(LL_ERROR, ("Failed to write %d bytes to %s", (int) cache->logs.len, file_name)); ret = -1; goto clean; } /* Using mbuf here instead of list to avoid memory overhead */ mbuf_append(&cache->file_names, file_name, FILENAME_LEN); mbuf_free(&cache->logs); s_last_file_id++; clean: if (file != NULL) { fclose(file); } return ret; }
static void ns_read_from_socket(struct ns_connection *conn) { char buf[NS_READ_BUFFER_SIZE]; int n = 0; if (conn->flags & NSF_CONNECTING) { int ok = 1, ret; (void) ret; socklen_t len = sizeof(ok); ret = getsockopt(conn->sock, SOL_SOCKET, SO_ERROR, (char *) &ok, &len); #ifdef NS_ENABLE_SSL if (ret == 0 && ok == 0 && conn->ssl != NULL) { ns_ssl_begin(conn); } #endif DBG(("%p connect ok=%d", conn, ok)); if (ok != 0) { conn->flags |= NSF_CLOSE_IMMEDIATELY; } else { conn->flags &= ~NSF_CONNECTING; } ns_call(conn, NS_CONNECT, &ok); return; } #ifdef NS_ENABLE_SSL if (conn->ssl != NULL) { if (conn->flags & NSF_SSL_HANDSHAKE_DONE) { /* SSL library may have more bytes ready to read then we ask to read. * Therefore, read in a loop until we read everything. Without the loop, * we skip to the next select() cycle which can just timeout. */ while ((n = SSL_read(conn->ssl, buf, sizeof(buf))) > 0) { DBG(("%p %d bytes <- %d (SSL)", conn, n, conn->sock)); mbuf_append(&conn->recv_mbuf, buf, n); ns_call(conn, NS_RECV, &n); } ns_ssl_err(conn, n); } else { ns_ssl_begin(conn); return; } } else #endif { while ((n = (int) NS_RECV_FUNC( conn->sock, buf, recv_avail_size(conn, sizeof(buf)), 0)) > 0) { DBG(("%p %d bytes (PLAIN) <- %d", conn, n, conn->sock)); mbuf_append(&conn->recv_mbuf, buf, n); ns_call(conn, NS_RECV, &n); } } if (ns_is_error(n)) { conn->flags |= NSF_CLOSE_IMMEDIATELY; } }
void mg_basic_auth_header(const struct mg_str user, const struct mg_str pass, struct mbuf *buf) { const char *header_prefix = "Authorization: Basic "; const char *header_suffix = "\r\n"; struct cs_base64_ctx ctx; cs_base64_init(&ctx, mg_mbuf_append_base64_putc, buf); mbuf_append(buf, header_prefix, strlen(header_prefix)); cs_base64_update(&ctx, user.p, user.len); if (pass.len > 0) { cs_base64_update(&ctx, ":", 1); cs_base64_update(&ctx, pass.p, pass.len); } cs_base64_finish(&ctx); mbuf_append(buf, header_suffix, strlen(header_suffix)); }
static struct visit *push_visit(struct mbuf *stack, ub_val_t obj) { struct visit *res; size_t pos = stack->len; mbuf_append(stack, NULL, sizeof(struct visit)); res = (struct visit *) (stack->buf + pos); memset(res, 0, sizeof(struct visit)); res->obj = obj; return res; }
/* * write to MBuf */ static int push_into_mbuf(PushFilter *next, void *arg, const uint8 *data, int len) { int res = 0; MBuf *mbuf = arg; if (len > 0) res = mbuf_append(mbuf, data, len); return res < 0 ? res : 0; }
static size_t ns_out(struct ns_connection *nc, const void *buf, size_t len) { if (nc->flags & NSF_UDP) { int n = sendto(nc->sock, buf, len, 0, &nc->sa.sa, sizeof(nc->sa.sin)); DBG(("%p %d %d %d %s:%hu", nc, nc->sock, n, errno, inet_ntoa(nc->sa.sin.sin_addr), ntohs(nc->sa.sin.sin_port))); return n < 0 ? 0 : n; } else { return mbuf_append(&nc->send_mbuf, buf, len); } }
static void context_save_unprocessed(struct update_context *ctx) { if (ctx->unprocessed.len == 0) { mbuf_append(&ctx->unprocessed, ctx->data, ctx->data_len); ctx->data = ctx->unprocessed.buf; ctx->data_len = ctx->unprocessed.len; LOG(LL_DEBUG, ("Added %d bytes to cached data", ctx->data_len)); } else { LOG(LL_DEBUG, ("Skip caching")); } }
bool sj_conf_parse(const struct mg_str json, const char *acl, const struct sj_conf_entry *schema, void *cfg) { struct parse_ctx ctx = { .schema = schema, .acl = acl, .cfg = cfg, .result = true}; return (json_walk(json.p, json.len, sj_conf_parse_cb, &ctx) >= 0 && ctx.result == true); } struct emit_ctx { const void *cfg; const void *base; bool pretty; struct mbuf *out; sj_conf_emit_cb_t cb; void *cb_param; }; static void sj_emit_indent(struct mbuf *m, int n) { mbuf_append(m, "\n", 1); for (int j = 0; j < n; j++) mbuf_append(m, " ", 1); }
static void sj_conf_emit_obj(struct emit_ctx *ctx, const struct sj_conf_entry *schema, int num_entries, int indent) { mbuf_append(ctx->out, "{", 1); bool first = true; for (int i = 0; i < num_entries;) { const struct sj_conf_entry *e = schema + i; if (sj_conf_value_eq(ctx->cfg, ctx->base, e)) { i += (e->type == CONF_TYPE_OBJECT ? e->num_desc : 1); continue; } if (!first) { mbuf_append(ctx->out, ",", 1); } else { first = false; } if (ctx->pretty) sj_emit_indent(ctx->out, indent); sj_json_emit_str(ctx->out, mg_mk_str(e->key), 1); mbuf_append(ctx->out, ": ", (ctx->pretty ? 2 : 1)); switch (e->type) { case CONF_TYPE_INT: { char buf[20]; int len = snprintf(buf, sizeof(buf), "%d", *((int *) (((char *) ctx->cfg) + e->offset))); mbuf_append(ctx->out, buf, len); break; } case CONF_TYPE_BOOL: { int v = *((int *) (((char *) ctx->cfg) + e->offset)); const char *s; int len; if (v != 0) { s = "true"; len = 4; } else { s = "false"; len = 5; } mbuf_append(ctx->out, s, len); break; } case CONF_TYPE_STRING: { const char *v = *((char **) (((char *) ctx->cfg) + e->offset)); sj_json_emit_str(ctx->out, mg_mk_str(v), 1); break; } case CONF_TYPE_OBJECT: { sj_conf_emit_obj(ctx, schema + i + 1, e->num_desc, indent + 2); break; } } i++; if (e->type == CONF_TYPE_OBJECT) i += e->num_desc; if (ctx->cb != NULL) ctx->cb(ctx->out, ctx->cb_param); } if (ctx->pretty) sj_emit_indent(ctx->out, indent - 2); mbuf_append(ctx->out, "}", 1); }
bool sj_conf_parse(const struct mg_str json, const char *acl, const struct sj_conf_entry *schema, void *cfg) { struct parse_ctx ctx = { .schema = schema, .acl = acl, .cfg = cfg, .result = true}; return (json_parse(json.p, json.len, sj_conf_parse_cb, &ctx) >= 0 && ctx.result == true); } struct emit_ctx { const void *cfg; const void *base; bool pretty; struct mbuf *out; sj_conf_emit_cb_t cb; void *cb_param; }; static void sj_conf_emit_str(struct mbuf *b, const char *s) { mbuf_append(b, "\"", 1); /* TODO(rojer): JSON escaping. */ if (s != NULL) mbuf_append(b, s, strlen(s)); mbuf_append(b, "\"", 1); }
int ns_dns_encode_record(struct mbuf *io, struct ns_dns_resource_record *rr, const char *name, size_t nlen, const void *rdata, size_t rlen) { size_t pos = io->len; uint16_t u16; uint32_t u32; if (rr->kind == NS_DNS_INVALID_RECORD) { return -1; /* LCOV_EXCL_LINE */ } if (ns_dns_encode_name(io, name, nlen) == -1) { return -1; } u16 = htons(rr->rtype); mbuf_append(io, &u16, 2); u16 = htons(rr->rclass); mbuf_append(io, &u16, 2); if (rr->kind == NS_DNS_ANSWER) { u32 = htonl(rr->ttl); mbuf_append(io, &u32, 4); if (rr->rtype == NS_DNS_CNAME_RECORD) { int clen; /* fill size after encoding */ size_t off = io->len; mbuf_append(io, &u16, 2); if ((clen = ns_dns_encode_name(io, (const char *) rdata, rlen)) == -1) { return -1; } u16 = clen; io->buf[off] = u16 >> 8; io->buf[off + 1] = u16 & 0xff; } else {
/* * During its work, updater requires requires to store some data. * For example, manifest file, zip header - must be received fully, while * content FW/FS files can be flashed directly from recv_mbuf * To avoid extra memory usage, context contains plain pointer (*data) * and mbuf (unprocessed); data is storing in memory only if where is no way * to process it right now. */ static void context_update(struct update_context *ctx, const char *data, size_t len) { if (ctx->unprocessed.len != 0) { /* We have unprocessed data, concatenate them with arrived */ mbuf_append(&ctx->unprocessed, data, len); ctx->data = ctx->unprocessed.buf; ctx->data_len = ctx->unprocessed.len; LOG(LL_DEBUG, ("Added %u bytes to cached data", len)); } else { /* No unprocessed, trying to process directly received data */ ctx->data = data; ctx->data_len = len; } LOG(LL_DEBUG, ("Data size: %u bytes", ctx->data_len)); }
void ub_bin_send(struct ub_ctx *ctx, void *d, size_t n) { if (n > ctx->bytes_left) { n = ctx->bytes_left; } ctx->bytes_left -= n; /* * TODO(mkm): * this is useless buffering, we should call ubjson cb directly */ mbuf_append(&ctx->out, d, n); ub_call_cb(ctx, 0); if (ctx->bytes_left == 0) { ub_render_cont(ctx); } }
void sj_conf_emit_cb(const void *cfg, const void *base, const struct sj_conf_entry *schema, bool pretty, struct mbuf *out, sj_conf_emit_cb_t cb, void *cb_param) { struct mbuf m; mbuf_init(&m, 0); if (out == NULL) out = &m; struct emit_ctx ctx = {.cfg = cfg, .base = base, .pretty = pretty, .out = out, .cb = cb, .cb_param = cb_param}; sj_conf_emit_obj(&ctx, schema + 1, schema->num_desc, 2); mbuf_append(out, "", 1); /* NUL */ if (cb != NULL) cb(out, cb_param); if (out == &m) mbuf_free(out); }
void mgos_uart_hal_dispatch_rx_top(struct mgos_uart_state *us) { int uart_no = us->uart_no; struct mbuf *rxb = &us->rx_buf; uint32_t rxn = 0; /* RX */ if (mgos_uart_rxb_free(us) > 0 && esp_uart_rx_fifo_len(uart_no) > 0) { int linger_counter = 0; /* 32 here is a constant measured (using system_get_time) to provide * linger time of rx_linger_micros. It basically means that one iteration * of the loop takes 3.2 us. * * Note: lingering may starve TX FIFO if the flow is bidirectional. * TODO(rojer): keep transmitting from tx_buf while lingering. */ int max_linger = us->cfg.rx_linger_micros / 10 * 32; #ifdef MEASURE_LINGER_TIME uint32_t st = system_get_time(); #endif while (mgos_uart_rxb_free(us) > 0 && linger_counter <= max_linger) { size_t rx_len = esp_uart_rx_fifo_len(uart_no); if (rx_len > 0) { rx_len = MIN(rx_len, mgos_uart_rxb_free(us)); if (rxb->size < rxb->len + rx_len) mbuf_resize(rxb, rxb->len + rx_len); while (rx_len > 0) { uint8_t b = rx_byte(uart_no); mbuf_append(rxb, &b, 1); rx_len--; rxn++; } if (linger_counter > 0) { us->stats.rx_linger_conts++; linger_counter = 0; } } else { linger_counter++; } } #ifdef MEASURE_LINGER_TIME fprintf(stderr, "Time spent reading: %u us\n", system_get_time() - st); #endif us->stats.rx_bytes += rxn; } CLEAR_PERI_REG_MASK(UART_INT_CLR(uart_no), UART_RX_INTS); }
void mgos_uart_hal_dispatch_rx_top(struct mgos_uart_state *us) { bool recd; struct cc32xx_uart_state *ds = (struct cc32xx_uart_state *) us->dev_data; cs_rbuf_t *irxb = &ds->isr_rx_buf; MAP_UARTIntDisable(ds->base, UART_RX_INTS); recv_more: recd = false; cc32xx_uart_rx_bytes(ds->base, irxb); while (irxb->used > 0 && mgos_uart_rxb_free(us) > 0) { int num_recd = 0; do { uint8_t *data; int num_to_get = MIN(mgos_uart_rxb_free(us), irxb->used); num_recd = cs_rbuf_get(irxb, num_to_get, &data); mbuf_append(&us->rx_buf, data, num_recd); cs_rbuf_consume(irxb, num_recd); us->stats.rx_bytes += num_recd; if (num_recd > 0) recd = true; cc32xx_uart_rx_bytes(ds->base, irxb); } while (num_recd > 0); } /* If we received something during this cycle and there is buffer space * available, "linger" for some more, maybe there's more to come. */ if (recd && mgos_uart_rxb_free(us) > 0 && us->cfg.rx_linger_micros > 0) { /* Magic constants below are tweaked so that the loop takes at most the * configured number of microseconds. */ int ctr = us->cfg.rx_linger_micros * 31 / 12; // HWREG(GPIOA1_BASE + GPIO_O_GPIO_DATA + 8) = 0xFF; /* Pin 64 */ while (ctr-- > 0) { if (MAP_UARTCharsAvail(ds->base)) { us->stats.rx_linger_conts++; goto recv_more; } } // HWREG(GPIOA1_BASE + GPIO_O_GPIO_DATA + 8) = 0; /* Pin 64 */ } MAP_UARTIntClear(ds->base, UART_RX_INTS); }
void sj_conf_emit_int(struct mbuf *b, int v) { char s[20]; int n = sprintf(s, "%d", v); if (n > 0) mbuf_append(b, s, n); }
static void console_make_clubby_call_mbuf(struct v7 *v7, struct mbuf *logs) { mbuf_append(logs, "\0", 1); console_make_clubby_call(v7, logs->buf); mbuf_free(logs); }
static bytea * decrypt_internal(int is_pubenc, int need_text, text *data, text *key, text *keypsw, text *args) { int err; MBuf *src = NULL, *dst = NULL; uint8 tmp[VARHDRSZ]; uint8 *restmp; bytea *res; int res_len; PGP_Context *ctx = NULL; struct debug_expect ex; int got_unicode = 0; init_work(&ctx, need_text, args, &ex); src = mbuf_create_from_data((uint8 *) VARDATA(data), VARSIZE(data) - VARHDRSZ); dst = mbuf_create(VARSIZE(data) + 2048); /* * reserve room for header */ mbuf_append(dst, tmp, VARHDRSZ); /* * set key */ if (is_pubenc) { uint8 *psw = NULL; int psw_len = 0; MBuf *kbuf; if (keypsw) { psw = (uint8 *) VARDATA(keypsw); psw_len = VARSIZE(keypsw) - VARHDRSZ; } kbuf = create_mbuf_from_vardata(key); err = pgp_set_pubkey(ctx, kbuf, psw, psw_len, 1); mbuf_free(kbuf); } else err = pgp_set_symkey(ctx, (uint8 *) VARDATA(key), VARSIZE(key) - VARHDRSZ); /* * decrypt */ if (err >= 0) err = pgp_decrypt(ctx, src, dst); /* * failed? */ if (err < 0) goto out; if (ex.expect) check_expect(ctx, &ex); /* remember the setting */ got_unicode = pgp_get_unicode_mode(ctx); out: if (src) mbuf_free(src); if (ctx) pgp_free(ctx); if (err) { px_set_debug_handler(NULL); if (dst) mbuf_free(dst); ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("%s", px_strerror(err)))); } res_len = mbuf_steal_data(dst, &restmp); mbuf_free(dst); /* res_len includes VARHDRSZ */ res = (bytea *) restmp; SET_VARSIZE(res, res_len); if (need_text && got_unicode) { text *utf = convert_from_utf8(res); if (utf != res) { clear_and_pfree(res); res = utf; } } px_set_debug_handler(NULL); /* * add successfull decryptions also into RNG */ add_entropy(res, key, keypsw); return res; }
static bytea * encrypt_internal(int is_pubenc, int is_text, text *data, text *key, text *args) { MBuf *src, *dst; uint8 tmp[VARHDRSZ]; uint8 *restmp; bytea *res; int res_len; PGP_Context *ctx; int err; struct debug_expect ex; text *tmp_data = NULL; /* * Add data and key info RNG. */ add_entropy(data, key, NULL); init_work(&ctx, is_text, args, &ex); if (is_text && pgp_get_unicode_mode(ctx)) { tmp_data = convert_to_utf8(data); if (tmp_data == data) tmp_data = NULL; else data = tmp_data; } src = create_mbuf_from_vardata(data); dst = mbuf_create(VARSIZE(data) + 128); /* * reserve room for header */ mbuf_append(dst, tmp, VARHDRSZ); /* * set key */ if (is_pubenc) { MBuf *kbuf = create_mbuf_from_vardata(key); err = pgp_set_pubkey(ctx, kbuf, NULL, 0, 0); mbuf_free(kbuf); } else err = pgp_set_symkey(ctx, (uint8 *) VARDATA(key), VARSIZE(key) - VARHDRSZ); /* * encrypt */ if (err >= 0) err = pgp_encrypt(ctx, src, dst); /* * check for error */ if (err) { if (ex.debug) px_set_debug_handler(NULL); if (tmp_data) clear_and_pfree(tmp_data); pgp_free(ctx); mbuf_free(src); mbuf_free(dst); ereport(ERROR, (errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION), errmsg("%s", px_strerror(err)))); } /* res_len includes VARHDRSZ */ res_len = mbuf_steal_data(dst, &restmp); res = (bytea *) restmp; SET_VARSIZE(res, res_len); if (tmp_data) clear_and_pfree(tmp_data); pgp_free(ctx); mbuf_free(src); mbuf_free(dst); px_set_debug_handler(NULL); return res; }
void mg_mbuf_append_base64_putc(char ch, void *user_data) { struct mbuf *mbuf = (struct mbuf *) user_data; mbuf_append(mbuf, &ch, sizeof(ch)); }
void mg_socket_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len) { mbuf_append(&nc->send_mbuf, buf, len); }
int ns_dns_copy_body(struct mbuf *io, struct ns_dns_message *msg) { return mbuf_append(io, msg->pkt.p + sizeof(struct ns_dns_header), msg->pkt.len - sizeof(struct ns_dns_header)); }
static void sj_emit_indent(struct mbuf *m, int n) { mbuf_append(m, "\n", 1); for (int j = 0; j < n; j++) mbuf_append(m, " ", 1); }
void mg_if_tcp_send(struct mg_connection *nc, const void *buf, size_t len) { mbuf_append(&nc->send_mbuf, buf, len); mg_lwip_mgr_schedule_poll(nc->mgr); }
static void cbor_write_byte(mbuf_t *hq, uint8_t c) { mbuf_append(hq, &c, 1); }