/* * Send message to serial port */ static int serial_term_send_msg(struct ipmi_intf * intf, uint8_t * msg, int msg_len) { int i, size, tmp = 0; uint8_t * buf, * data; if (verbose > 3) { fprintf(stderr, "Sending request:\n"); fprintf(stderr, " NetFN/rsLUN = 0x%x\n", msg[0]); fprintf(stderr, " rqSeq = 0x%x\n", msg[1]); fprintf(stderr, " cmd = 0x%x\n", msg[2]); if (msg_len > 7) { fprintf(stderr, " data_len = %d\n", msg_len - 3); fprintf(stderr, " data = %s\n", buf2str(msg + 3, msg_len - 3)); } } if (verbose > 4) { fprintf(stderr, "Message data:\n"); fprintf(stderr, " %s\n", buf2str(msg, msg_len)); } /* calculate required buffer size */ size = msg_len * 2 + 4; /* allocate buffer for output data */ buf = data = (uint8_t *) alloca(size); if (!buf) { lperror(LOG_ERR, "ipmitool: alloca error"); return -1; } /* start character */ *buf++ = '['; /* body */ for (i = 0; i < msg_len; i++) { buf += sprintf( buf, "%02x", msg[i]); } /* stop character */ *buf++ = ']'; /* carriage return */ *buf++ = '\r'; /* line feed */ *buf++ = '\n'; /* write data to serial port */ tmp = write(intf->fd, data, size); if (tmp <= 0) { lperror(LOG_ERR, "ipmitool: write error"); return -1; } return 0; }
static int add_header(grpc_http_parser *parser) { uint8_t *beg = parser->cur_line; uint8_t *cur = beg; uint8_t *end = beg + parser->cur_line_length; size_t *hdr_count = NULL; grpc_http_header **hdrs = NULL; grpc_http_header hdr = {NULL, NULL}; GPR_ASSERT(cur != end); if (*cur == ' ' || *cur == '\t') { if (grpc_http1_trace) gpr_log(GPR_ERROR, "Continued header lines not supported yet"); goto error; } while (cur != end && *cur != ':') { cur++; } if (cur == end) { if (grpc_http1_trace) { gpr_log(GPR_ERROR, "Didn't find ':' in header string"); } goto error; } GPR_ASSERT(cur >= beg); hdr.key = buf2str(beg, (size_t)(cur - beg)); cur++; /* skip : */ while (cur != end && (*cur == ' ' || *cur == '\t')) { cur++; } GPR_ASSERT((size_t)(end - cur) >= parser->cur_line_end_length); hdr.value = buf2str(cur, (size_t)(end - cur) - parser->cur_line_end_length); if (parser->type == GRPC_HTTP_RESPONSE) { hdr_count = &parser->http.response.hdr_count; hdrs = &parser->http.response.hdrs; } else if (parser->type == GRPC_HTTP_REQUEST) { hdr_count = &parser->http.request.hdr_count; hdrs = &parser->http.request.hdrs; } else { return 0; } if (*hdr_count == parser->hdr_capacity) { parser->hdr_capacity = GPR_MAX(parser->hdr_capacity + 1, parser->hdr_capacity * 3 / 2); *hdrs = gpr_realloc(*hdrs, parser->hdr_capacity * sizeof(**hdrs)); } (*hdrs)[(*hdr_count)++] = hdr; return 1; error: gpr_free(hdr.key); gpr_free(hdr.value); return 0; }
/* * Read and parse data from serial port */ static int serial_bm_recv_msg(struct ipmi_intf * intf, struct serial_bm_recv_ctx * recv_ctx, uint8_t * msg_data, size_t msg_len) { struct serial_bm_parse_ctx parse_ctx; int rv; parse_ctx.state = MSG_NONE; parse_ctx.msg = msg_data; parse_ctx.max_len = msg_len; do { /* wait for data in the port */ if (serial_bm_wait_for_data(intf)) { return 0; } /* read data into buffer */ rv = read(intf->fd, recv_ctx->buffer + recv_ctx->buffer_size, recv_ctx->max_buffer_size - recv_ctx->buffer_size); if (rv < 0) { lperror(LOG_ERR, "ipmitool: read error"); return -1; } if (verbose > 5) { fprintf(stderr, "Received serial data:\n %s\n", buf2str(recv_ctx->buffer + recv_ctx->buffer_size, rv)); } /* increment buffer size */ recv_ctx->buffer_size += rv; /* parse buffer */ rv = serial_bm_parse_buffer(recv_ctx->buffer, recv_ctx->buffer_size, &parse_ctx); if (rv < recv_ctx->buffer_size) { /* move non-parsed part of the buffer to the beginning */ memmove(recv_ctx->buffer, recv_ctx->buffer + rv, recv_ctx->buffer_size - rv); } /* decrement buffer size */ recv_ctx->buffer_size -= rv; } while (parse_ctx.state != MSG_DONE); if (verbose > 4) { printf("Received message:\n %s\n", buf2str(msg_data, parse_ctx.msg_len)); } /* received a message */ return parse_ctx.msg_len; }
static int handle_request_line(grpc_http_parser *parser) { uint8_t *beg = parser->cur_line; uint8_t *cur = beg; uint8_t *end = beg + parser->cur_line_length; uint8_t vers_major = 0; uint8_t vers_minor = 0; while (cur != end && *cur++ != ' ') ; if (cur == end) goto error; parser->http.request.method = buf2str(beg, (size_t)(cur - beg - 1)); beg = cur; while (cur != end && *cur++ != ' ') ; if (cur == end) goto error; parser->http.request.path = buf2str(beg, (size_t)(cur - beg - 1)); if (cur == end || *cur++ != 'H') goto error; if (cur == end || *cur++ != 'T') goto error; if (cur == end || *cur++ != 'T') goto error; if (cur == end || *cur++ != 'P') goto error; if (cur == end || *cur++ != '/') goto error; vers_major = (uint8_t)(*cur++ - '1' + 1); ++cur; if (cur == end) goto error; vers_minor = (uint8_t)(*cur++ - '1' + 1); if (vers_major == 1) { if (vers_minor == 0) { parser->http.request.version = GRPC_HTTP_HTTP10; } else if (vers_minor == 1) { parser->http.request.version = GRPC_HTTP_HTTP11; } else { goto error; } } else if (vers_major == 2) { if (vers_minor == 0) { parser->http.request.version = GRPC_HTTP_HTTP20; } else { goto error; } } else { goto error; } return 1; error: if (grpc_http1_trace) gpr_log(GPR_ERROR, "Failed parsing request line"); return 0; }
static void rndr_tablecell(struct buf *ob, const struct buf *text, int align, void *opaque) { VALUE rb_align; switch (align) { case MKD_TABLE_ALIGN_L: rb_align = CSTR2SYM("left"); break; case MKD_TABLE_ALIGN_R: rb_align = CSTR2SYM("right"); break; case MKD_TABLE_ALIGN_CENTER: rb_align = CSTR2SYM("center"); break; default: rb_align = Qnil; break; } BLOCK_CALLBACK("table_cell", 2, buf2str(text), rb_align); }
/* * multi-session authcode generation for MD5 * H(password + session_id + msg + session_seq + password) * * Use OpenSSL implementation of MD5 algorithm if found */ uint8_t * ipmi_auth_md5(struct ipmi_session * s, uint8_t * data, int data_len) { md5_state_t state; static md5_byte_t digest[16]; uint32_t temp; memset(digest, 0, 16); memset(&state, 0, sizeof(md5_state_t)); md5_init(&state); md5_append(&state, (const md5_byte_t *)s->authcode, 16); md5_append(&state, (const md5_byte_t *)&s->session_id, 4); md5_append(&state, (const md5_byte_t *)data, data_len); if(!isLittleEndian()) temp = BSWAP_32(s->in_seq); else temp = s->in_seq; md5_append(&state, (const md5_byte_t *)&temp, 4); md5_append(&state, (const md5_byte_t *)s->authcode, 16); md5_finish(&state, digest); if (verbose > 3) printf(" MD5 AuthCode : %s\n", buf2str(digest, 16)); return digest; }
/* * Wait for request response */ static int serial_term_wait_response(struct ipmi_intf * intf, struct serial_term_request_ctx * req_ctx, uint8_t * msg, size_t max_len) { struct serial_term_hdr * hdr = (struct serial_term_hdr *) msg; int msg_len; /* wait for response(s) */ do { /* receive message */ msg_len = recv_response(intf, msg, max_len); /* check if valid message received */ if (msg_len > 0) { /* validate message size */ if (msg_len < 4) { /* either bad response or non-related message */ continue; } /* check for the waited response */ if (hdr->netFn == (req_ctx->netFn|4) && (hdr->seq & ~3) == req_ctx->seq && hdr->cmd == req_ctx->cmd) { /* check if something new has been parsed */ if (verbose > 3) { fprintf(stderr, "Got response:\n"); fprintf(stderr, " NetFN/rsLUN = 0x%x\n", msg[0]); fprintf(stderr, " rqSeq/Bridge = 0x%x\n", msg[1]); fprintf(stderr, " cmd = 0x%x\n", msg[2]); fprintf(stderr, " completion code = 0x%x\n", msg[3]); if (msg_len > 8) { fprintf(stderr, " data_len = %d\n", msg_len - 4); fprintf(stderr, " data = %s\n", buf2str(msg + 4, msg_len - 4)); } } /* move to start from completion code */ memmove(msg, hdr + 1, msg_len - sizeof (*hdr)); /* the waited one */ return msg_len - sizeof (*hdr); } } } while (msg_len > 0); return 0; }
size_t LLXMLRPCTransaction::Impl::curlDownloadCallback( char* data, size_t size, size_t nmemb, void* user_data) { Impl& impl(*(Impl*)user_data); size_t n = size * nmemb; #ifdef CWDEBUG if (n < 80) Dout(dc::curl, "Entering LLXMLRPCTransaction::Impl::curlDownloadCallback(\"" << buf2str(data, n) << "\", " << size << ", " << nmemb << ", " << user_data << ")"); else Dout(dc::curl, "Entering LLXMLRPCTransaction::Impl::curlDownloadCallback(\"" << buf2str(data, 40) << "\"...\"" << buf2str(data + n - 40, 40) << "\", " << size << ", " << nmemb << ", " << user_data << ")"); #endif impl.mResponseText.append(data, n); if (impl.mStatus == LLXMLRPCTransaction::StatusStarted) { impl.setStatus(LLXMLRPCTransaction::StatusDownloading); } return n; }
static void rndr_paragraph(struct buf *ob, const struct buf *text, void *opaque) { BLOCK_CALLBACK("paragraph", 1, buf2str(text)); }
static void rndr_listitem(struct buf *ob, const struct buf *text, int flags, void *opaque) { BLOCK_CALLBACK("list_item", 2, buf2str(text), (flags & MKD_LIST_ORDERED) ? CSTR2SYM("ordered") : CSTR2SYM("unordered")); }
static void rndr_header(struct buf *ob, const struct buf *text, int level, void *opaque) { BLOCK_CALLBACK("header", 2, buf2str(text), INT2FIX(level)); }
static int rndr_codespan(struct buf *ob, const struct buf *text, void *opaque) { SPAN_CALLBACK("codespan", 1, buf2str(text)); }
static struct ipmi_rs * ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) { struct ipmi_recv recv; struct ipmi_addr addr; struct ipmi_system_interface_addr bmc_addr = { .addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE, .channel = IPMI_BMC_CHANNEL, }; struct ipmi_ipmb_addr ipmb_addr = { .addr_type = IPMI_IPMB_ADDR_TYPE, }; struct ipmi_req _req; static struct ipmi_rs rsp; struct timeval read_timeout; static int curr_seq = 0; fd_set rset; uint8_t * data = NULL; int data_len = 0; int retval = 0; if (intf == NULL || req == NULL) return NULL; ipmb_addr.channel = intf->target_channel & 0x0f; if (intf->opened == 0 && intf->open != NULL) if (intf->open(intf) < 0) return NULL; if (verbose > 2) { fprintf(stderr, "OpenIPMI Request Message Header:\n"); fprintf(stderr, " netfn = 0x%x\n", req->msg.netfn ); fprintf(stderr, " cmd = 0x%x\n", req->msg.cmd); printbuf(req->msg.data, req->msg.data_len, "OpenIPMI Request Message Data"); } /* * setup and send message */ memset(&_req, 0, sizeof(struct ipmi_req)); if (intf->target_addr != 0 && intf->target_addr != intf->my_addr) { /* use IPMB address if needed */ ipmb_addr.slave_addr = intf->target_addr; ipmb_addr.lun = req->msg.lun; lprintf(LOG_DEBUG, "Sending request 0x%x to " "IPMB target @ 0x%x:0x%x (from 0x%x)", req->msg.cmd, intf->target_addr,intf->target_channel, intf->my_addr); if(intf->transit_addr != 0 && intf->transit_addr != intf->my_addr) { uint8_t index = 0; lprintf(LOG_DEBUG, "Encapsulating data sent to " "end target [0x%02x,0x%02x] using transit [0x%02x,0x%02x] from 0x%x ", (0x40 | intf->target_channel), intf->target_addr, intf->transit_channel, intf->transit_addr, intf->my_addr ); /* Convert Message to 'Send Message' */ /* Supplied req : req , internal req : _req */ if (verbose > 4) { fprintf(stderr, "Converting message:\n"); fprintf(stderr, " netfn = 0x%x\n", req->msg.netfn ); fprintf(stderr, " cmd = 0x%x\n", req->msg.cmd); if (req->msg.data && req->msg.data_len) { fprintf(stderr, " data_len = %d\n", req->msg.data_len); fprintf(stderr, " data = %s\n", buf2str(req->msg.data,req->msg.data_len)); } } /* Modify target address to use 'transit' instead */ ipmb_addr.slave_addr = intf->transit_addr; ipmb_addr.channel = intf->transit_channel; /* FIXME backup "My address" */ data_len = req->msg.data_len + 8; data = malloc(data_len); if (data == NULL) { lprintf(LOG_ERR, "ipmitool: malloc failure"); return NULL; } memset(data, 0, data_len); data[index++] = (0x40|intf->target_channel); data[index++] = intf->target_addr; data[index++] = ( req->msg.netfn << 2 ) | req->msg.lun ; data[index++] = ipmi_csum(data+1, 2); data[index++] = 0xFF; /* normally 0x20 , overwritten by IPMC */ data[index++] = ( (0) << 2) | 0 ; /* FIXME */ data[index++] = req->msg.cmd; memcpy( (data+index) , req->msg.data, req->msg.data_len); index += req->msg.data_len; data[index++] = ipmi_csum( (data+4),(req->msg.data_len + 3) ); if (verbose > 4) { fprintf(stderr, "Encapsulated message:\n"); fprintf(stderr, " netfn = 0x%x\n", IPMI_NETFN_APP ); fprintf(stderr, " cmd = 0x%x\n", 0x34 ); if (data && data_len) { fprintf(stderr, " data_len = %d\n", data_len); fprintf(stderr, " data = %s\n", buf2str(data,data_len)); } } } _req.addr = (unsigned char *) &ipmb_addr; _req.addr_len = sizeof(ipmb_addr); } else { /* otherwise use system interface */ lprintf(LOG_DEBUG+2, "Sending request 0x%x to " "System Interface", req->msg.cmd); bmc_addr.lun = req->msg.lun; _req.addr = (unsigned char *) &bmc_addr; _req.addr_len = sizeof(bmc_addr); } _req.msgid = curr_seq++; /* In case of a bridge request */ if( data != NULL && data_len != 0 ) { _req.msg.data = data; _req.msg.data_len = data_len; _req.msg.netfn = IPMI_NETFN_APP; _req.msg.cmd = 0x34; } else { _req.msg.data = req->msg.data; _req.msg.data_len = req->msg.data_len; _req.msg.netfn = req->msg.netfn; _req.msg.cmd = req->msg.cmd; } if (ioctl(intf->fd, IPMICTL_SEND_COMMAND, &_req) < 0) { lperror(LOG_ERR, "Unable to send command"); if (data != NULL) { free(data); data = NULL; } return NULL; } /* * wait for and retrieve response */ if (intf->noanswer) { if (data != NULL) { free(data); data = NULL; } return NULL; } FD_ZERO(&rset); FD_SET(intf->fd, &rset); read_timeout.tv_sec = IPMI_OPENIPMI_READ_TIMEOUT; read_timeout.tv_usec = 0; retval = select(intf->fd+1, &rset, NULL, NULL, &read_timeout); if (retval < 0) { lperror(LOG_ERR, "I/O Error"); if (data != NULL) { free(data); data = NULL; } return NULL; } else if (retval == 0) { lprintf(LOG_ERR, "No data available"); if (data != NULL) { free(data); data = NULL; } return NULL; } if (FD_ISSET(intf->fd, &rset) == 0) { lprintf(LOG_ERR, "No data available"); if (data != NULL) { free(data); data = NULL; } return NULL; } recv.addr = (unsigned char *) &addr; recv.addr_len = sizeof(addr); recv.msg.data = rsp.data; recv.msg.data_len = sizeof(rsp.data); /* get data */ if (ioctl(intf->fd, IPMICTL_RECEIVE_MSG_TRUNC, &recv) < 0) { lperror(LOG_ERR, "Error receiving message"); if (errno != EMSGSIZE) { if (data != NULL) { free(data); data = NULL; } return NULL; } } if (verbose > 4) { fprintf(stderr, "Got message:"); fprintf(stderr, " type = %d\n", recv.recv_type); fprintf(stderr, " channel = 0x%x\n", addr.channel); fprintf(stderr, " msgid = %ld\n", recv.msgid); fprintf(stderr, " netfn = 0x%x\n", recv.msg.netfn); fprintf(stderr, " cmd = 0x%x\n", recv.msg.cmd); if (recv.msg.data && recv.msg.data_len) { fprintf(stderr, " data_len = %d\n", recv.msg.data_len); fprintf(stderr, " data = %s\n", buf2str(recv.msg.data, recv.msg.data_len)); } } if(intf->transit_addr != 0 && intf->transit_addr != intf->my_addr) { /* ipmb_addr.transit_slave_addr = intf->transit_addr; */ lprintf(LOG_DEBUG, "Decapsulating data received from transit " "IPMB target @ 0x%x", intf->transit_addr); /* comp code */ /* Check data */ if( recv.msg.data[0] == 0 ) { recv.msg.netfn = recv.msg.data[2] >> 2; recv.msg.cmd = recv.msg.data[6]; recv.msg.data = memmove(recv.msg.data ,recv.msg.data+7 , recv.msg.data_len - 7); recv.msg.data_len -=8; if (verbose > 4) { fprintf(stderr, "Decapsulated message:\n"); fprintf(stderr, " netfn = 0x%x\n", recv.msg.netfn ); fprintf(stderr, " cmd = 0x%x\n", recv.msg.cmd); if (recv.msg.data && recv.msg.data_len) { fprintf(stderr, " data_len = %d\n", recv.msg.data_len); fprintf(stderr, " data = %s\n", buf2str(recv.msg.data,recv.msg.data_len)); } } }
static int rndr_quote(struct buf *ob, const struct buf *text, void *opaque) { SPAN_CALLBACK("quote", 1, buf2str(text)); }
/** * direct writes */ static void rndr_entity(struct buf *ob, const struct buf *text, void *opaque) { BLOCK_CALLBACK("entity", 1, buf2str(text)); }
static int rndr_superscript(struct buf *ob, const struct buf *text, void *opaque) { SPAN_CALLBACK("superscript", 1, buf2str(text)); }
static int rndr_strikethrough(struct buf *ob, const struct buf *text, void *opaque) { SPAN_CALLBACK("strikethrough", 1, buf2str(text)); }
static int rndr_triple_emphasis(struct buf *ob, const struct buf *text, void *opaque) { SPAN_CALLBACK("triple_emphasis", 1, buf2str(text)); }
static int rndr_raw_html(struct buf *ob, const struct buf *text, void *opaque) { SPAN_CALLBACK("raw_html", 1, buf2str(text)); }
static int rndr_link(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *content, void *opaque) { SPAN_CALLBACK("link", 3, buf2str(link), buf2str(title), buf2str(content)); }
static int rndr_image(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *alt, void *opaque) { SPAN_CALLBACK("image", 3, buf2str(link), buf2str(title), buf2str(alt)); }
static void rndr_table(struct buf *ob, const struct buf *header, const struct buf *body, void *opaque) { BLOCK_CALLBACK("table", 2, buf2str(header), buf2str(body)); }
/* * Send message to serial port */ static int serial_bm_send_msg(struct ipmi_intf * intf, uint8_t * msg, int msg_len) { int i, size, tmp = 0; uint8_t * buf, * data; if (verbose > 3) { fprintf(stderr, "Sending request:\n"); fprintf(stderr, " rsSA = 0x%x\n", msg[0]); fprintf(stderr, " NetFN/rsLUN = 0x%x\n", msg[1]); fprintf(stderr, " rqSA = 0x%x\n", msg[3]); fprintf(stderr, " rqSeq/rqLUN = 0x%x\n", msg[4]); fprintf(stderr, " cmd = 0x%x\n", msg[5]); if (msg_len > 7) { fprintf(stderr, " data_len = %d\n", msg_len - 7); fprintf(stderr, " data = %s\n", buf2str(msg + 6, msg_len - 7)); } } if (verbose > 4) { fprintf(stderr, "Message data:\n"); fprintf(stderr, " %s\n", buf2str(msg, msg_len)); } /* calculate escaped characters number */ for (i = 0; i < msg_len; i++) { if (serial_bm_get_escaped_char(msg[i]) != msg[i]) { tmp++; } } /* calculate required buffer size */ size = msg_len + tmp + 2; /* allocate buffer for output data */ buf = data = (uint8_t *) alloca(size); if (!buf) { lperror(LOG_ERR, "ipmitool: alloca error"); return -1; } /* start character */ *buf++ = 0xA0; for (i = 0; i < msg_len; i++) { tmp = serial_bm_get_escaped_char(msg[i]); if (tmp != msg[i]) { *buf++ = 0xAA; } *buf++ = tmp; } /* stop character */ *buf++ = 0xA5; if (verbose > 5) { fprintf(stderr, "Sent serial data:\n %s\n", buf2str(data, size)); } /* write data to serial port */ tmp = write(intf->fd, data, size); if (tmp <= 0) { lperror(LOG_ERR, "ipmitool: write error"); return -1; } return 0; }
static void rndr_tablerow(struct buf *ob, const struct buf *text, void *opaque) { BLOCK_CALLBACK("table_row", 1, buf2str(text)); }
/* * Wait for request response */ static int serial_bm_wait_response(struct ipmi_intf * intf, struct serial_bm_request_ctx * req_ctx, struct serial_bm_recv_ctx * read_ctx, uint8_t * msg, size_t max_len) { struct ipmb_msg_hdr * hdr = (struct ipmb_msg_hdr *) msg; int msg_len, netFn, rqSeq; /* receive and match message */ while ((msg_len = serial_bm_recv_msg(intf, read_ctx, msg, max_len)) > 0) { /* validate message size */ if (msg_len < 8) { lprintf(LOG_ERR, "ipmitool: response is too short"); continue; } /* validate checksum 1 */ if (ipmi_csum(msg, 3)) { lprintf(LOG_ERR, "ipmitool: bad checksum 1"); continue; } /* validate checksum 2 */ if (ipmi_csum(msg + 3, msg_len - 3)) { lprintf(LOG_ERR, "ipmitool: bad checksum 2"); continue; } /* swap requester and responder LUNs */ netFn = ((req_ctx->netFn|4) & ~3) | (req_ctx->rqSeq & 3); rqSeq = (req_ctx->rqSeq & ~3) | (req_ctx->netFn & 3); /* check for the waited response */ if (hdr->rsSA == req_ctx->rqSA && hdr->netFn == netFn && hdr->rqSA == req_ctx->rsSA && hdr->rqSeq == rqSeq && hdr->cmd == req_ctx->cmd) { /* check if something new has been parsed */ if (verbose > 3) { fprintf(stderr, "Got response:\n"); fprintf(stderr, " rsSA = 0x%x\n", msg[0]); fprintf(stderr, " NetFN/rsLUN = 0x%x\n", msg[1]); fprintf(stderr, " rqSA = 0x%x\n", msg[3]); fprintf(stderr, " rqSeq/rqLUN = 0x%x\n", msg[4]); fprintf(stderr, " cmd = 0x%x\n", msg[5]); fprintf(stderr, " completion code = 0x%x\n", msg[6]); if (msg_len > 8) { fprintf(stderr, " data_len = %d\n", msg_len - 8); fprintf(stderr, " data = %s\n", buf2str(msg + 7, msg_len - 8)); } } /* copy only completion and response data */ memmove(msg, hdr + 1, msg_len - sizeof (*hdr) - 1); /* update message length */ msg_len -= sizeof (*hdr) + 1; /* the waited one */ break; } } return msg_len; }
static void rndr_blockcode(struct buf *ob, const struct buf *text, const struct buf *lang, void *opaque) { BLOCK_CALLBACK("block_code", 2, buf2str(text), buf2str(lang)); }
static void rndr_blockquote(struct buf *ob, const struct buf *text, void *opaque) { BLOCK_CALLBACK("block_quote", 1, buf2str(text)); }
static void rndr_raw_block(struct buf *ob, const struct buf *text, void *opaque) { BLOCK_CALLBACK("block_html", 1, buf2str(text)); }
static void rndr_normal_text(struct buf *ob, const struct buf *text, void *opaque) { BLOCK_CALLBACK("normal_text", 1, buf2str(text)); }
/*** * SPAN LEVEL */ static int rndr_autolink(struct buf *ob, const struct buf *link, enum mkd_autolink type, void *opaque) { SPAN_CALLBACK("autolink", 2, buf2str(link), type == MKDA_NORMAL ? CSTR2SYM("url") : CSTR2SYM("email")); }