Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
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;
}