in ncrx/libncrx.c [195:278]
static int parse_packet(const char *payload, struct ncrx_msg *msg)
{
char buf[1024];
char *p, *tok;
int idx;
memset(msg, 0, sizeof(*msg));
p = strchr(payload, ';');
if (!p || p - payload >= (signed)sizeof(buf))
goto einval;
memcpy(buf, payload, p - payload);
buf[p - payload] = '\0';
msg->text = p + 1;
msg->text_len = strlen(msg->text);
if (msg->text_len > NCRX_LINE_MAX)
msg->text_len = NCRX_LINE_MAX;
/* <level>,<sequnum>,<timestamp>,<contflag>[,KEY=VAL]* */
idx = 0;
p = buf;
while ((tok = strsep(&p, ","))) {
char *endp, *key, *val;
unsigned long long v;
switch (idx++) {
case 0:
v = strtoul(tok, &endp, 0);
if (*endp != '\0' || v > UINT8_MAX)
goto einval;
msg->facility = v >> 3;
msg->level = v & ((1 << 3) - 1);
continue;
case 1:
v = strtoull(tok, &endp, 0);
if (*endp != '\0')
goto einval;
msg->seq = v;
continue;
case 2:
v = strtoull(tok, &endp, 0);
if (*endp != '\0')
goto einval;
msg->ts_usec = v;
continue;
case 3:
if (tok[0] == 'c')
msg->cont_start = 1;
else if (tok[0] == '+')
msg->cont = 1;
continue;
}
val = tok;
key = strsep(&val, "=");
if (!val)
continue;
if (!strcmp(key, "ncfrag")) {
unsigned nf_off, nf_len;
if (sscanf(val, "%u/%u", &nf_off, &nf_len) != 2)
goto einval;
if (!msg->text_len ||
nf_len >= NCRX_LINE_MAX ||
nf_off + msg->text_len > nf_len)
goto einval;
msg->ncfrag_off = nf_off;
msg->ncfrag_len = msg->text_len;
msg->ncfrag_left = nf_len - msg->ncfrag_len;
msg->text_len = nf_len;
} else if (!strcmp(key, "ncemg")) {
v = strtoul(val, &endp, 0);
if (*endp != '\0')
goto einval;
msg->emg = v;
}
}
return 0;
einval:
errno = EINVAL;
return -1;
}