AmendHub

Download:

jcs

/

subtext

/

amendments

/

402

fidopkt: A single packet can have multiple messages in it

Asking Areafix to rescan an area will generate a single packet with
all of those rescanned messages in it.

jcs made amendment 402 about 1 year ago
--- fidopkt.c Sat Mar 11 09:02:35 2023 +++ fidopkt.c Mon Mar 13 22:37:19 2023 @@ -81,7 +81,7 @@ static const char *months[] = { size_t fidopkt_read_until(char **buf, size_t *buf_len, char delim, size_t max_len, char *ret, bool terminate); -bool fidopkt_parse_msgid(struct fidopkt *pkt); +bool fidopkt_parse_msgid(struct fidopkt_message *msg); size_t fidopkt_read_until(char **buf, size_t *buf_len, char delim, @@ -99,7 +99,7 @@ fidopkt_read_until(char **buf, size_t *buf_len, char d ret[retpos++] = (ch == delim ? '\0' : ch); max_len--; (*buf_len)--; - if (ch == delim) { + if (ch == delim || ch == '\0') { found = true; break; } @@ -130,72 +130,73 @@ fidopkt_parse_address(char *str, struct fidopkt_addres } bool -fidopkt_parse_msgid(struct fidopkt *pkt) +fidopkt_parse_msgid(struct fidopkt_message *msg) { static char garbage[50]; unsigned short zone, net, node, point = 0; unsigned long id; /* 37246.fsxnet_fsx_gen@21:1/137.1 28583dba */ - if (sscanf(pkt->msgid_orig, "%49[^@]@%d:%d/%d.%d %lx", + if (sscanf(msg->msgid_orig, "%49[^@]@%u:%u/%u.%u %lx", &garbage, &zone, &net, &node, &point, &id) == 6) goto found; /* 37246.fsxnet_fsx_gen@21:1/137 28583dba */ - if (sscanf(pkt->msgid_orig, "%49[^@]@%d:%d/%d %lx", + if (sscanf(msg->msgid_orig, "%49[^@]@%u:%u/%u %lx", &garbage, &zone, &net, &node, &id) == 5) goto found; /* 21:3/110.10@fsxnet 05996db9 */ - if (sscanf(pkt->msgid_orig, "%d:%d/%d.%d@%49s %lx", + if (sscanf(msg->msgid_orig, "%u:%u/%u.%u@%49s %lx", &zone, &net, &node, &point, &garbage, &id) == 6) goto found; /* 21:3/110@fsxnet 05996db9 */ - if (sscanf(pkt->msgid_orig, "%d:%d/%d@%49s %lx", + if (sscanf(msg->msgid_orig, "%u:%u/%u@%49s %lx", &zone, &net, &node, &garbage, &id) == 5) goto found; /* 21:3/102.1 63f277aa */ - if (sscanf(pkt->msgid_orig, "%d:%d/%d.%d %lx", + if (sscanf(msg->msgid_orig, "%u:%u/%u.%u %lx", &zone, &net, &node, &point, &id) == 5) goto found; /* 21:3/102 63f277aa */ - if (sscanf(pkt->msgid_orig, "%d:%d/%d %lx", + if (sscanf(msg->msgid_orig, "%u:%u/%u %lx", &zone, &net, &node, &id) == 4) goto found; - logger_printf("[fidopkt] failed parsing msgid \"%s\"", pkt->msgid_orig); return false; found: - pkt->msgid.id = id; - pkt->msgid.zone = zone; - pkt->msgid.net = net; - pkt->msgid.node = node; - pkt->msgid.point = point; + msg->msgid.id = id; + msg->msgid.zone = zone; + msg->msgid.net = net; + msg->msgid.node = node; + msg->msgid.point = point; #ifdef FIDOPKT_DEBUG - logger_printf("[fidopkt] %s -> zone:%d net:%d node:%d point:%d id:%lu", - pkt->msgid_orig, pkt->msgid.zone, pkt->msgid.net, - pkt->msgid.node, pkt->msgid.point, pkt->msgid.id); + logger_printf("[fidopkt] %s -> zone:%u net:%u node:%u point:%u id:%lu", + msg->msgid_orig, msg->msgid.zone, msg->msgid.net, + msg->msgid.node, msg->msgid.point, msg->msgid.id); #endif return true; } -struct fidopkt * -fidopkt_parse(char *packet_filename, char *buf, size_t len) +struct fidopkt_message * +fidopkt_parse_message(char *packet_filename, struct fidopkt_header *header, + char **bufp, size_t *lenp) { static char line[100]; #ifdef FIDOPKT_DEBUG static char datetime[100], tz[50], ct[50]; char *lastbreak, was; #endif - struct fidopkt *ret; + char *buf; + struct fidopkt_message *ret; struct tm tm = { 0 }; struct fidopkt_address orig_address, dest_address; - size_t body_len, llen; + size_t body_len, len, llen, msg_size; long tzoff = 0; char dmon[6]; short dday, dyear, dhour, dmin, dsec, dutc, attr, n; @@ -204,50 +205,54 @@ fidopkt_parse(char *packet_filename, char *buf, size_t #ifdef FIDOPKT_DEBUG logger_printf("[fidopkt] Parsing %s ==========", packet_filename); #endif - - if (len < FIDOPKT_HEADER_SIZE) { - logger_printf("[fidopkt] packet too small (%ld)", len); - return; - } - if (GET_U16(buf + FIDOPKT_PKTTYPE) != 2) { - logger_printf("[fidopkt] not a fidonet packet"); - return; - } - - if (GET_U16(buf + FIDOPKT_BAUD) == 2) { - logger_printf("[fidopkt] 5d format not supported"); - return; - } - - if (buf[FIDOPKT_CWVALIDCOPY] != buf[FIDOPKT_CAPABILWORD + 1] || - buf[FIDOPKT_CWVALIDCOPY + 1] != buf[FIDOPKT_CAPABILWORD]) { - logger_printf("[fidopkt] not in 4d format"); - return; - } + buf = *bufp; + len = *lenp; - if (GET_U16(buf + FIDOPKT_ORIGZONE) != 0) { - orig_address.zone = GET_U16(buf + FIDOPKT_ORIGZONE); - dest_address.zone = GET_U16(buf + FIDOPKT_DESTZONE); - } else if (GET_U16(buf + FIDOPKT_QORIGZONE) != 0) { - orig_address.zone = GET_U16(buf + FIDOPKT_QORIGZONE); - dest_address.zone = GET_U16(buf + FIDOPKT_QDESTZONE); - } else { - orig_address.zone = 0; - dest_address.zone = 0; - } + if (header == NULL) { + if (len < FIDOPKT_HEADER_SIZE) { + logger_printf("[fidopkt] packet too small (%ld)", len); + return; + } - orig_address.net = GET_U16(buf + FIDOPKT_ORIGNET); - orig_address.node = GET_U16(buf + FIDOPKT_ORIGNODE); - orig_address.point = GET_U16(buf + FIDOPKT_ORIGPOINT); + if (GET_U16(buf + FIDOPKT_PKTTYPE) != 2) { + logger_printf("[fidopkt] not a fidonet packet"); + return; + } - dest_address.net = GET_U16(buf + FIDOPKT_DESTNET); - dest_address.node = GET_U16(buf + FIDOPKT_DESTNODE); - dest_address.point = GET_U16(buf + FIDOPKT_DESTPOINT); - - buf += FIDOPKT_HEADER_SIZE; - len -= FIDOPKT_HEADER_SIZE; - + if (GET_U16(buf + FIDOPKT_BAUD) == 2) { + logger_printf("[fidopkt] 5d format not supported"); + return; + } + + if (buf[FIDOPKT_CWVALIDCOPY] != buf[FIDOPKT_CAPABILWORD + 1] || + buf[FIDOPKT_CWVALIDCOPY + 1] != buf[FIDOPKT_CAPABILWORD]) { + logger_printf("[fidopkt] not in 4d format"); + return; + } + + if (GET_U16(buf + FIDOPKT_ORIGZONE) != 0) { + orig_address.zone = GET_U16(buf + FIDOPKT_ORIGZONE); + dest_address.zone = GET_U16(buf + FIDOPKT_DESTZONE); + } else if (GET_U16(buf + FIDOPKT_QORIGZONE) != 0) { + orig_address.zone = GET_U16(buf + FIDOPKT_QORIGZONE); + dest_address.zone = GET_U16(buf + FIDOPKT_QDESTZONE); + } else { + orig_address.zone = 0; + dest_address.zone = 0; + } + + orig_address.net = GET_U16(buf + FIDOPKT_ORIGNET); + orig_address.node = GET_U16(buf + FIDOPKT_ORIGNODE); + orig_address.point = GET_U16(buf + FIDOPKT_ORIGPOINT); + dest_address.net = GET_U16(buf + FIDOPKT_DESTNET); + dest_address.node = GET_U16(buf + FIDOPKT_DESTNODE); + dest_address.point = GET_U16(buf + FIDOPKT_DESTPOINT); + + buf += FIDOPKT_HEADER_SIZE; + len -= FIDOPKT_HEADER_SIZE; + } + if (len < FIDOPKT_MSG_HEADER_SIZE) { logger_printf("[fidopkt] message header too short"); return; @@ -259,20 +264,24 @@ fidopkt_parse(char *packet_filename, char *buf, size_t } attr = GET_U16(buf + FIDOPKT_MSG_ATTR); - + buf += FIDOPKT_MSG_HEADER_SIZE; len -= FIDOPKT_MSG_HEADER_SIZE; - ret = calloc(sizeof(struct fidopkt), 1); + ret = xmalloczero(sizeof(struct fidopkt_message)); if (ret == NULL) { logger_printf("[fidopkt] malloc failed"); goto parse_fail; } - ret->orig = orig_address; - ret->dest = dest_address; + if (header == NULL) { + ret->header.orig = orig_address; + ret->header.dest = dest_address; + } else { + memcpy(&ret->header, header, sizeof(ret->header)); + } ret->attr = attr; - + fidopkt_read_until(&buf, &len, '\0', sizeof(line), line, true); if (len == 0) { logger_printf("[fidopkt] short read"); @@ -322,16 +331,26 @@ fidopkt_parse(char *packet_filename, char *buf, size_t goto parse_fail; } - ret->body = malloc(len); + /* body will be terminated by a null, packet with two nulls */ + for (msg_size = 0; msg_size < len - 1; msg_size++) { + if (buf[msg_size] == '\0') { + msg_size++; + break; + } + } + + len -= msg_size; + + ret->body = xmalloc(msg_size); if (ret->body == NULL) { - logger_printf("[fidopkt] malloc(%lu) failed", len); + logger_printf("[fidopkt] malloc(%lu) failed", msg_size); goto parse_fail; } body_len = 0; tear = false; - while (len) { - llen = fidopkt_read_until(&buf, &len, '\r', sizeof(line), line, + while (msg_size) { + llen = fidopkt_read_until(&buf, &msg_size, '\r', sizeof(line), line, false); if (body_len == 0 && strncmp(line, "AREA:", 5) == 0) { @@ -363,7 +382,6 @@ fidopkt_parse(char *packet_filename, char *buf, size_t */ strlcpy(ret->msgid_orig, line + 1 + 7, sizeof(ret->msgid_orig)); - fidopkt_parse_msgid(ret); } else if (strncmp(line + 1, "REPLY: ", 7) == 0) strlcpy(ret->reply, line + 1 + 7, sizeof(ret->reply)); } else if (tear && strncmp(line, " * Origin: ", 11) == 0) { @@ -372,8 +390,7 @@ fidopkt_parse(char *packet_filename, char *buf, size_t } else if (!tear) { if (line[0] == ' ' && line[1] == ' ') continue; - if (body_len == 0 && - (line[0] == '\n' || line[0] == '\r' || line[0] == '\0')) + if (body_len == 0 && (line[0] == '\n' || line[0] == '\r')) continue; if (line[llen - 1] == '\0') { memcpy(ret->body + body_len, line, llen - 1); @@ -388,6 +405,7 @@ fidopkt_parse(char *packet_filename, char *buf, size_t } } + /* trim trailing newlines */ while (body_len > 1) { if (ret->body[body_len - 1] == '\n' && ret->body[body_len - 2] == '\r') @@ -408,14 +426,31 @@ fidopkt_parse(char *packet_filename, char *buf, size_t /* make time UTC */ ret->time -= tzoff; + if (ret->msgid_orig[0] == '\0') { + /* no msgid, invent a stable one */ + snprintf(ret->msgid_orig, sizeof(ret->msgid_orig), + "nomsgid@%u:%u/%u.%u %08lx", + ret->header.orig.zone, ret->header.orig.net, + ret->header.orig.node, ret->header.orig.point, + ret->time); + } + + if (!fidopkt_parse_msgid(ret)) { + logger_printf("[fidopkt] failed parsing msgid \"%s\"", + ret->msgid_orig); + goto parse_fail; + } + #ifdef FIDOPKT_DEBUG - logger_printf("[fidopkt] ID: %d:%d/%d.%d %08lx (%s)", ret->msgid.zone, + logger_printf("[fidopkt] ID: %u:%u/%u.%u %08lx (%s)", ret->msgid.zone, ret->msgid.net, ret->msgid.node, ret->msgid.point, ret->msgid.id, ret->msgid_orig); - logger_printf("[fidopkt] Orig Node: %d:%d/%d.%d", ret->orig.zone, - ret->orig.net, ret->orig.node, ret->orig.point); - logger_printf("[fidopkt] Dest Node: %d:%d/%d.%d", ret->dest.zone, - ret->dest.net, ret->dest.node, ret->dest.point); + logger_printf("[fidopkt] Orig Node: %u:%u/%u.%u", + ret->header.orig.zone, ret->header.orig.net, ret->header.orig.node, + ret->header.orig.point); + logger_printf("[fidopkt] Dest Node: %u:%u/%u.%u", + ret->header.dest.zone, ret->header.dest.net, ret->header.dest.node, + ret->header.dest.point); logger_printf("[fidopkt] Origin: %s", ret->origin); logger_printf("[fidopkt] Reply To: %s", ret->reply); logger_printf("[fidopkt] Area: %s", ret->area); @@ -442,40 +477,52 @@ fidopkt_parse(char *packet_filename, char *buf, size_t } #endif + /* packets are terminated by two nulls */ + if (len == 2 && buf[0] == '\0') { + buf++; + len--; + } + if (len == 1 && buf[0] == '\0') { + buf++; + len--; + } + + *bufp = buf; + *lenp = len; return ret; parse_fail: - fidopkt_free(&ret); + fidopkt_message_free(&ret); return NULL; } size_t -fidopkt_encode(struct fidopkt *pkt, char **ret_buf, char *pkt_password, - short tzoff) +fidopkt_encode_message(struct fidopkt_message *msg, char **ret_buf, + char *pkt_password, short tzoff) { static char scratch[30]; struct tm *tm; char *buf; size_t len, off, buf_size, subject_len, n; - subject_len = strlen(pkt->subject); + subject_len = strlen(msg->subject); buf_size = FIDOPKT_HEADER_SIZE + FIDOPKT_MSG_HEADER_SIZE + - subject_len + pkt->body_len + 512; + subject_len + msg->body_len + 512; buf = xmalloczero(buf_size); - tm = localtime(&pkt->time); + tm = localtime(&msg->time); - PUT_U16(buf + FIDOPKT_ORIGZONE, pkt->orig.zone); - PUT_U16(buf + FIDOPKT_QORIGZONE, pkt->orig.zone); - PUT_U16(buf + FIDOPKT_ORIGNET, pkt->orig.net); - PUT_U16(buf + FIDOPKT_ORIGNODE, pkt->orig.node); + PUT_U16(buf + FIDOPKT_ORIGZONE, msg->header.orig.zone); + PUT_U16(buf + FIDOPKT_QORIGZONE, msg->header.orig.zone); + PUT_U16(buf + FIDOPKT_ORIGNET, msg->header.orig.net); + PUT_U16(buf + FIDOPKT_ORIGNODE, msg->header.orig.node); memcpy(buf + FIDOPKT_PASSWORD, pkt_password, strlen(pkt_password)); - PUT_U16(buf + FIDOPKT_DESTZONE, pkt->dest.zone); - PUT_U16(buf + FIDOPKT_QDESTZONE, pkt->dest.zone); - PUT_U16(buf + FIDOPKT_DESTNET, pkt->dest.net); - PUT_U16(buf + FIDOPKT_DESTNODE, pkt->dest.node); + PUT_U16(buf + FIDOPKT_DESTZONE, msg->header.dest.zone); + PUT_U16(buf + FIDOPKT_QDESTZONE, msg->header.dest.zone); + PUT_U16(buf + FIDOPKT_DESTNET, msg->header.dest.net); + PUT_U16(buf + FIDOPKT_DESTNODE, msg->header.dest.node); PUT_U32(buf + FIDOPKT_PRODDATA, 'SUBT'); @@ -497,49 +544,49 @@ fidopkt_encode(struct fidopkt *pkt, char **ret_buf, ch PUT_U16(buf + FIDOPKT_HEADER_SIZE + FIDOPKT_MSG_PKTTYPE, 2); PUT_U16(buf + FIDOPKT_HEADER_SIZE + FIDOPKT_MSG_DESTNET, - pkt->dest.net); + msg->header.dest.net); PUT_U16(buf + FIDOPKT_HEADER_SIZE + FIDOPKT_MSG_DESTNODE, - pkt->dest.node); + msg->header.dest.node); PUT_U16(buf + FIDOPKT_HEADER_SIZE + FIDOPKT_MSG_ORIGNET, - pkt->orig.net); + msg->header.orig.net); PUT_U16(buf + FIDOPKT_HEADER_SIZE + FIDOPKT_MSG_ORIGNODE, - pkt->orig.node); + msg->header.orig.node); - PUT_U16(buf + FIDOPKT_HEADER_SIZE + FIDOPKT_MSG_ATTR, pkt->attr); + PUT_U16(buf + FIDOPKT_HEADER_SIZE + FIDOPKT_MSG_ATTR, msg->attr); off = FIDOPKT_HEADER_SIZE + FIDOPKT_MSG_HEADER_SIZE; - /* date, null-terminated */ + /* date, null-terminated, with two spaces between year and hour */ if (!grow_to_fit(&buf, &buf_size, off, 21, 21)) goto fail; off += strftime(buf + off, 20, "%d %b %y %H:%M:%S", tm); off++; /* to, null-terminated */ - len = strlen(pkt->to); + len = strlen(msg->to); if (!grow_to_fit(&buf, &buf_size, off, len + 1, len + 1)) goto fail; - memcpy(buf + off, pkt->to, len); + memcpy(buf + off, msg->to, len); off += len + 1; /* from, null-terminated */ - len = strlen(pkt->from); + len = strlen(msg->from); if (!grow_to_fit(&buf, &buf_size, off, len + 1, len + 1)) goto fail; - memcpy(buf + off, pkt->from, len); + memcpy(buf + off, msg->from, len); off += len + 1; /* subject, null-terminated */ if (!grow_to_fit(&buf, &buf_size, off, subject_len + 1, subject_len + 1)) goto fail; - memcpy(buf + off, pkt->subject, subject_len); + memcpy(buf + off, msg->subject, subject_len); off += subject_len + 1; - /* optional area (non-kludge) \r-terminated, no space */ - if (pkt->area[0] != '\0') { - len = snprintf(scratch, sizeof(scratch), "AREA:%s\r", pkt->area); + /* optional area (non-kludge) \r-terminated, no space after colon */ + if (msg->area[0] != '\0') { + len = snprintf(scratch, sizeof(scratch), "AREA:%s\r", msg->area); if (len > sizeof(scratch)) goto fail; if (!grow_to_fit(&buf, &buf_size, off, len, len)) @@ -548,12 +595,13 @@ fidopkt_encode(struct fidopkt *pkt, char **ret_buf, ch off += len; } - if (pkt->area[0] == '\0') { + if (msg->area[0] == '\0') { /* kludge line: INTL to from, \r-terminated, but not on net mail */ len = snprintf(scratch, sizeof(scratch), "%cINTL %d:%d/%d %d:%d/%d\r", - 0x1, pkt->dest.zone, pkt->dest.net, pkt->dest.node, - pkt->orig.zone, pkt->orig.net, pkt->orig.node); + 0x1, msg->header.dest.zone, msg->header.dest.net, + msg->header.dest.node, msg->header.orig.zone, + msg->header.orig.net, msg->header.orig.node); if (len > sizeof(scratch)) goto fail; if (!grow_to_fit(&buf, &buf_size, off, len, len)) @@ -574,7 +622,7 @@ fidopkt_encode(struct fidopkt *pkt, char **ret_buf, ch /* kludge line: MSGID zone:net/node id, \r-terminated */ len = snprintf(scratch, sizeof(scratch), "%cMSGID: %d:%d/%d %08lx\r", - 0x1, pkt->msgid.zone, pkt->msgid.net, pkt->msgid.node, pkt->msgid.id); + 0x1, msg->msgid.zone, msg->msgid.net, msg->msgid.node, msg->msgid.id); if (len > sizeof(scratch)) goto fail; if (!grow_to_fit(&buf, &buf_size, off, len, len)) @@ -583,9 +631,9 @@ fidopkt_encode(struct fidopkt *pkt, char **ret_buf, ch off += len; /* kludge line: REPLY orig-msgid, \r-terminated */ - if (pkt->reply[0] != '\0') { + if (msg->reply[0] != '\0') { len = snprintf(scratch, sizeof(scratch), "%cREPLY: %s\r", - 0x1, pkt->reply); + 0x1, msg->reply); if (len > sizeof(scratch)) goto fail; if (!grow_to_fit(&buf, &buf_size, off, len, len)) @@ -604,37 +652,42 @@ fidopkt_encode(struct fidopkt *pkt, char **ret_buf, ch memcpy(buf + off, scratch, len); off += len; - if (!grow_to_fit(&buf, &buf_size, off, pkt->body_len + 7, - pkt->body_len + 7)) + if (!grow_to_fit(&buf, &buf_size, off, msg->body_len + 7, + msg->body_len + 7)) goto fail; /* * FidoNet messages can only have \r line-breaks and we probably used * \r\n during the message editor, so strip out \n. */ - for (n = 0; n < pkt->body_len; n++) { - if (n == pkt->body_len - 1 && pkt->body[n] == '\r') + for (n = 0; n < msg->body_len; n++) { + if (n == msg->body_len - 1 && msg->body[n] == '\r') /* supress trailing \r, we'll add two next */ continue; - if (pkt->body[n] == '\n') { - if (pkt->body[n - 1] == '\r') + if (msg->body[n] == '\n') { + if (msg->body[n - 1] == '\r') continue; buf[off++] = '\r'; } else - buf[off++] = pkt->body[n]; + buf[off++] = msg->body[n]; } /* add tear line */ off += sprintf(buf + off, "\r\r--- \r"); - if (pkt->origin[0]) { - len = 11 + strlen(pkt->origin) + 2; + if (msg->origin[0]) { + len = 11 + strlen(msg->origin) + 2; if (!grow_to_fit(&buf, &buf_size, off, len, len)) goto fail; - - off += sprintf(buf + off, " * Origin: %s\r", pkt->origin); + off += sprintf(buf + off, " * Origin: %s\r", msg->origin); } + /* packets are terminated by two nulls */ + if (!grow_to_fit(&buf, &buf_size, off, 2, 2)) + goto fail; + buf[off++] = '\0'; + buf[off++] = '\0'; + *ret_buf = buf; return off; @@ -645,12 +698,12 @@ fail: } void -fidopkt_free(struct fidopkt **pktp) +fidopkt_message_free(struct fidopkt_message **msgp) { - struct fidopkt *pkt = (struct fidopkt *)*pktp; + struct fidopkt_message *msg = (struct fidopkt_message *)*msgp; - if (pkt->body) - free(pkt->body); - free(pkt); - *pktp = NULL; + if (msg->body) + xfree(&msg->body); + xfree(&msg); + *msgp = NULL; } --- fidopkt.h Thu Mar 9 14:49:58 2023 +++ fidopkt.h Mon Mar 13 13:28:30 2023 @@ -34,30 +34,33 @@ struct fidopkt_msgid { u_int16_t point; }; -struct fidopkt { - time_t time; +struct fidopkt_header { struct fidopkt_address orig; struct fidopkt_address dest; +}; +struct fidopkt_message { + struct fidopkt_header header; + u_int16_t attr; +#define FIDOPKT_MSG_ATTR_PRIVATE (1 << 0) +#define FIDOPKT_MSG_ATTR_CRASH (1 << 1) + time_t time; char to[36]; char from[36]; char subject[72]; char area[16]; char origin[72]; - char reply[32]; - char msgid_orig[64]; struct fidopkt_msgid msgid; - u_int16_t attr; -#define FIDOPKT_MSG_ATTR_PRIVATE (1 << 0) -#define FIDOPKT_MSG_ATTR_CRASH (1 << 1) + char msgid_orig[64]; + char reply[32]; char *body; size_t body_len; }; bool fidopkt_parse_address(char *str, struct fidopkt_address *address); -struct fidopkt * fidopkt_parse(char *packet_filename, char *buf, - size_t len); -size_t fidopkt_encode(struct fidopkt *pkt, char **buf, char *pkt_password, - short tzoff); -void fidopkt_free(struct fidopkt **pktp); +struct fidopkt_message * fidopkt_parse_message(char *packet_filename, + struct fidopkt_header *header, char **bufp, size_t *lenp); +size_t fidopkt_encode_message(struct fidopkt_message *msg, char **bufp, + char *pkt_password, short tzoff); +void fidopkt_message_free(struct fidopkt_message **pktp); #endif