Returns in-place, but copies if it has to. Updates *off. */
| 176 | |
| 177 | /* Returns in-place, but copies if it has to. Updates *off. */ |
| 178 | static bool get_log_entry(const tal_t *ctx, |
| 179 | const struct log_book *log, |
| 180 | struct log_hdr *hdr, |
| 181 | const char **msg, |
| 182 | const u8 **io, |
| 183 | size_t *off) |
| 184 | { |
| 185 | void *buf1, *buf2; |
| 186 | size_t buf1len, buf2len; |
| 187 | |
| 188 | if (ringbuf_used(log) < *off + sizeof(*hdr)) |
| 189 | return false; |
| 190 | |
| 191 | ringbuf_span(log, log->ringbuf_start + *off, sizeof(*hdr), |
| 192 | &buf1, &buf1len, &buf2, &buf2len); |
| 193 | *off += copy_from(hdr, sizeof(*hdr), buf1, buf1len, buf2, buf2len); |
| 194 | ringbuf_span(log, log->ringbuf_start + *off, hdr->msglen, |
| 195 | &buf1, &buf1len, &buf2, &buf2len); |
| 196 | if (buf2len != 0) { |
| 197 | char *bytes = tal_arr(ctx, char, buf1len + buf2len); |
| 198 | *off += copy_from(bytes, tal_bytelen(bytes), buf1, buf1len, buf2, buf2len); |
| 199 | *msg = bytes; |
| 200 | } else { |
| 201 | *msg = buf1; |
| 202 | *off += buf1len; |
| 203 | } |
| 204 | ringbuf_span(log, log->ringbuf_start + *off, hdr->iolen, |
| 205 | &buf1, &buf1len, &buf2, &buf2len); |
| 206 | if (buf2len != 0) { |
| 207 | u8 *bytes = tal_arr(ctx, u8, buf1len + buf2len); |
| 208 | *off += copy_from(bytes, tal_bytelen(bytes), buf1, buf1len, buf2, buf2len); |
| 209 | *io = bytes; |
| 210 | } else { |
| 211 | if (buf1len == 0) |
| 212 | *io = NULL; |
| 213 | else { |
| 214 | *io = buf1; |
| 215 | *off += buf1len; |
| 216 | } |
| 217 | } |
| 218 | return true; |
| 219 | } |
| 220 | |
| 221 | static struct log_prefix *log_prefix_get(struct log_prefix *lp) |
| 222 | { |