int hcfg_deserialize(hcfg_t *cfg, char *buf) { int count, total; unsigned int i, kcount, logsize; const char *key, *val; if (sscanf(buf, " hcfg:%u %u%n", &kcount, &logsize, &count) < 2) goto invalid; total = count; if (hash_resize(cfg, logsize) < 0) goto error; for (i = 0; i < kcount; ++i) { count = scanstr_serial(&key, buf + total); if (count < 0) goto invalid; total += count; count = scanstr_serial(&val, buf + total); if (count < 0) goto invalid; total += count; if (hcfg_set(cfg, key, val) < 0) goto error; } return total; invalid: errno = EINVAL; error: return -1; }
int hsignature_deserialize(hsignature_t *sig, char *buf) { int i, count, total; char *strptr; hrange_t *newbuf; for (i = 0; isspace(buf[i]); ++i); if (strncmp("sig:", buf + i, 4) != 0) goto invalid; total = i + 4; count = scanstr_serial((const char **)&strptr, buf + total); if (count < 0) goto invalid; total += count; sig->name = stralloc(strptr); if (!sig->name) goto error; if (sscanf(buf + total, " %d%n", &sig->range_len, &count) < 1) goto invalid; total += count; if (sig->range_cap < sig->range_len) { newbuf = (hrange_t *) realloc(sig->range, sizeof(hrange_t) * sig->range_len); if (!newbuf) goto error; sig->range = newbuf; sig->range_cap = sig->range_len; } for (i = 0; i < sig->range_len; ++i) { sig->range[i] = HRANGE_INITIALIZER; count = hrange_deserialize(&sig->range[i], buf + total); if (count < 0) goto invalid; total += count; } return total; invalid: errno = EINVAL; error: return -1; }
int hrange_deserialize(hrange_t *range, char *buf) { int i, count, total; char **newbuf; char *strptr; char type_str[4]; for (i = 0; isspace(buf[i]); ++i); if (strncmp("range:", buf + i, 6) != 0) goto invalid; total = i + 6; count = scanstr_serial((const char **)&strptr, buf + total); if (count < 0) goto invalid; total += count; range->name = stralloc(strptr); if (!range->name) goto error; if (sscanf(buf + total, " %3s%n", type_str, &count) < 1) goto invalid; total += count; if (strcmp(type_str, "INT") == 0) range->type = HVAL_INT; else if (strcmp(type_str, "REL") == 0) range->type = HVAL_REAL; else if (strcmp(type_str, "STR") == 0) range->type = HVAL_STR; else goto invalid; switch (range->type) { case HVAL_INT: if (sscanf(buf + total, " %ld %ld %ld%n", &range->bounds.i.min, &range->bounds.i.max, &range->bounds.i.step, &count) < 3) goto invalid; total += count; break; case HVAL_REAL: if (sscanf(buf + total, " %la %la %la%n", &range->bounds.r.min, &range->bounds.r.max, &range->bounds.r.step, &count) < 3) goto invalid; total += count; break; case HVAL_STR: if (sscanf(buf + total, " %d%n", &range->bounds.s.set_len, &count) < 1) goto invalid; total += count; if (range->bounds.s.set_cap < range->bounds.s.set_len) { newbuf = (char **) realloc(range->bounds.s.set, sizeof(char *) * range->bounds.s.set_len); if (!newbuf) goto error; range->bounds.s.set = newbuf; range->bounds.s.set_cap = range->bounds.s.set_len; } for (i = 0; i < range->bounds.s.set_len; ++i) { count = scanstr_serial((const char **)&strptr, buf + total); if (count < 0) goto invalid; total += count; range->bounds.s.set[i] = stralloc(strptr); if (!range->bounds.s.set[i]) goto error; } break; default: goto invalid; } return total; invalid: errno = EINVAL; error: return -1; }
int hmesg_deserialize(hmesg_t *mesg) { char type_str[4], status_str[4]; int count, total; unsigned int msgver; char *buf = mesg->buf; /* Verify HMESG_MAGIC and HMESG_VERSION */ if (ntohl(*(unsigned int *)buf) != HMESG_MAGIC) goto invalid; if (sscanf(buf + sizeof(unsigned int), "%*4d%2x", &msgver) < 1) goto invalid; if (msgver != HMESG_VERSION) goto invalid; total = HMESG_HDRLEN; if (sscanf(buf + total, " :%d:%3s:%3s:%n", &mesg->dest, type_str, status_str, &count) < 3) goto invalid; total += count; count = scanstr_serial(&mesg->src_id, buf + total); if (count < 0) goto invalid; total += count; /* Before we overwrite this message's type, make sure memory allocated * from previous usage has been released. */ if (strcmp(type_str, "UNK") == 0) mesg->type = HMESG_UNKNOWN; else if (strcmp(type_str, "SES") == 0) mesg->type = HMESG_SESSION; else if (strcmp(type_str, "JOI") == 0) mesg->type = HMESG_JOIN; else if (strcmp(type_str, "QRY") == 0) mesg->type = HMESG_GETCFG; else if (strcmp(type_str, "INF") == 0) mesg->type = HMESG_SETCFG; else if (strcmp(type_str, "FET") == 0) mesg->type = HMESG_FETCH; else if (strcmp(type_str, "REP") == 0) mesg->type = HMESG_REPORT; else goto invalid; if (strcmp(status_str, "REQ") == 0) mesg->status = HMESG_STATUS_REQ; else if (strcmp(status_str, "ACK") == 0) mesg->status = HMESG_STATUS_OK; else if (strcmp(status_str, "ERR") == 0) mesg->status = HMESG_STATUS_FAIL; else if (strcmp(status_str, "BSY") == 0) mesg->status = HMESG_STATUS_BUSY; else goto invalid; if (mesg->status == HMESG_STATUS_BUSY) { /* Busy messages contain no data. */ } else if (mesg->status == HMESG_STATUS_FAIL) { count = scanstr_serial(&mesg->data.string, buf + total); if (count < 0) goto error; total += count; } else { switch (mesg->type) { case HMESG_SESSION: if (mesg->status == HMESG_STATUS_REQ) { hsession_init(&mesg->data.session); count = hsession_deserialize(&mesg->data.session, buf + total); if (count < 0) goto error; total += count; } break; case HMESG_JOIN: mesg->data.join = HSIGNATURE_INITIALIZER; count = hsignature_deserialize(&mesg->data.join, buf + total); if (count < 0) goto error; total += count; break; case HMESG_GETCFG: case HMESG_SETCFG: count = scanstr_serial(&mesg->data.string, buf + total); if (count < 0) goto error; total += count; break; case HMESG_FETCH: if (mesg->status == HMESG_STATUS_REQ) { if (sscanf(buf + total, " %d%n", &mesg->data.fetch.best.id, &count) < 1) goto invalid; total += count; } else if (mesg->status == HMESG_STATUS_OK) { mesg->data.fetch.cand = HPOINT_INITIALIZER; count = hpoint_deserialize(&mesg->data.fetch.cand, buf + total); if (count < 0) goto error; total += count; mesg->data.fetch.best = HPOINT_INITIALIZER; count = hpoint_deserialize(&mesg->data.fetch.best, buf + total); if (count < 0) goto error; total += count; } break; case HMESG_REPORT: if (mesg->status == HMESG_STATUS_REQ) { mesg->data.fetch.cand = HPOINT_INITIALIZER; count = hpoint_deserialize(&mesg->data.report.cand, buf + total); if (count < 0) goto error; total += count; if (sscanf(buf + total, " %la%n", &mesg->data.report.perf, &count) < 1) goto invalid; total += count; } break; default: goto invalid; } } return total; invalid: errno = EINVAL; error: return -1; }