int hsignature_serialize(char **buf, int *buflen, const hsignature_t *sig)
{
    int i, count, total;

    count = snprintf_serial(buf, buflen, "sig: ");
    if (count < 0) goto invalid;
    total = count;

    count = printstr_serial(buf, buflen, sig->name);
    if (count < 0) goto error;
    total += count;

    count = snprintf_serial(buf, buflen, "%d ", sig->range_len);
    if (count < 0) goto invalid;
    total += count;

    for (i = 0; i < sig->range_len; ++i) {
        count = hrange_serialize(buf, buflen, &sig->range[i]);
        if (count < 0) goto error;
        total += count;
    }
    return total;

invalid:
    errno = EINVAL;
error:
    return -1;
}
Example #2
0
int hcfg_serialize(char **buf, int *buflen, const hcfg_t *cfg)
{
    int i, count, total;

    count = snprintf_serial(buf, buflen, "hcfg:%u %u ",
                            cfg->count, cfg->logsize);
    if (count < 0) goto invalid;
    total = count;

    for (i = 0; i < (1 << cfg->logsize); ++i) {
        if (cfg->hash[i].key) {
            count = printstr_serial(buf, buflen, cfg->hash[i].key);
            if (count < 0) goto invalid;
            total += count;

            count = printstr_serial(buf, buflen, cfg->hash[i].val);
            if (count < 0) goto invalid;
            total += count;
        }
    }
    return total;

  invalid:
    errno = EINVAL;
    return -1;
}
int hrange_serialize(char **buf, int *buflen, const hrange_t *range)
{
    int i, count, total;
    const char *type_str;

    count = snprintf_serial(buf, buflen, "range: ");
    if (count < 0) goto error;
    total = count;

    count = printstr_serial(buf, buflen, range->name);
    if (count < 0) goto error;
    total += count;

    switch (range->type) {
    case HVAL_INT:
        type_str = "INT";
        break;
    case HVAL_REAL:
        type_str = "REL";
        break;
    case HVAL_STR:
        type_str = "STR";
        break;
    default:
        goto invalid;
    }

    count = snprintf_serial(buf, buflen, "%s ", type_str);
    if (count < 0) goto invalid;
    total += count;

    switch (range->type) {
    case HVAL_INT:
        count = snprintf_serial(buf, buflen, "%ld %ld %ld ",
                                range->bounds.i.min,
                                range->bounds.i.max,
                                range->bounds.i.step);
        if (count < 0) goto invalid;
        total += count;
        break;

    case HVAL_REAL:
        count = snprintf_serial(buf, buflen, "%la %la %la ",
                                range->bounds.r.min,
                                range->bounds.r.max,
                                range->bounds.r.step);
        if (count < 0) goto invalid;
        total += count;
        break;

    case HVAL_STR:
        count = snprintf_serial(buf, buflen, "%d ", range->bounds.s.set_len);
        if (count < 0) goto invalid;
        total += count;

        for (i = 0; i < range->bounds.s.set_len; ++i) {
            count = printstr_serial(buf, buflen, range->bounds.s.set[i]);
            if (count < 0) goto invalid;
            total += count;
        }
        break;

    default:
        goto invalid;
    }
    return total;

invalid:
    errno = EINVAL;
error:
    return -1;
}
Example #4
0
int hmesg_serialize(hmesg_t *mesg)
{
    const char *type_str, *status_str;
    char hdr[HMESG_HDRLEN + 1];
    char *buf;
    int buflen, count, total;

  top:
    buf = mesg->buf;
    buflen = mesg->buflen;

    /* Leave room for a header. */
    buf += HMESG_HDRLEN;
    buflen -= HMESG_HDRLEN;
    if (buflen < 0)
        buflen = 0;
    total = HMESG_HDRLEN;

    switch (mesg->type) {
    case HMESG_UNKNOWN: type_str = "UNK"; break;
    case HMESG_SESSION: type_str = "SES"; break;
    case HMESG_JOIN:    type_str = "JOI"; break;
    case HMESG_GETCFG:  type_str = "QRY"; break;
    case HMESG_SETCFG:  type_str = "INF"; break;
    case HMESG_FETCH:   type_str = "FET"; break;
    case HMESG_REPORT:  type_str = "REP"; break;
    default: goto invalid;
    }

    switch (mesg->status) {
    case HMESG_STATUS_REQ:  status_str = "REQ"; break;
    case HMESG_STATUS_OK:   status_str = "ACK"; break;
    case HMESG_STATUS_FAIL: status_str = "ERR"; break;
    case HMESG_STATUS_BUSY: status_str = "BSY"; break;
    default: goto invalid;
    }

    count = snprintf_serial(&buf, &buflen, ":%d:%s:%s:", mesg->dest,
                            type_str, status_str);
    if (count < 0) goto error;
    total += count;

    count = printstr_serial(&buf, &buflen, mesg->src_id);
    if (count < 0) goto error;
    total += count;

    if (mesg->status == HMESG_STATUS_BUSY) {
        /* Busy messages contain no data. */
    }
    else if (mesg->status == HMESG_STATUS_FAIL) {
        count = printstr_serial(&buf, &buflen, mesg->data.string);
        if (count < 0) goto error;
        total += count;
    }
    else {
        switch (mesg->type) {
        case HMESG_SESSION:
            if (mesg->status == HMESG_STATUS_REQ) {
                count = hsession_serialize(&buf, &buflen, &mesg->data.session);
                if (count < 0) goto error;
                total += count;
            }
            break;

        case HMESG_JOIN:
            count = hsignature_serialize(&buf, &buflen, &mesg->data.join);
            if (count < 0) goto error;
            total += count;
            break;

        case HMESG_GETCFG:
        case HMESG_SETCFG:
            count = printstr_serial(&buf, &buflen, mesg->data.string);
            if (count < 0) goto error;
            total += count;
            break;

        case HMESG_FETCH:
            if (mesg->status == HMESG_STATUS_REQ) {
                count = snprintf_serial(&buf, &buflen, "%d ",
                                        mesg->data.fetch.best.id);
                if (count < 0) goto error;
                total += count;
            }
            else if (mesg->status == HMESG_STATUS_OK) {
                count = hpoint_serialize(&buf, &buflen,
                                         &mesg->data.fetch.cand);
                if (count < 0) goto error;
                total += count;

                count = hpoint_serialize(&buf, &buflen,
                                         &mesg->data.fetch.best);
                if (count < 0) goto error;
                total += count;
            }
            break;

        case HMESG_REPORT:
            if (mesg->status == HMESG_STATUS_REQ) {
                count = hpoint_serialize(&buf, &buflen,
                                         &mesg->data.report.cand);
                if (count < 0) goto error;
                total += count;

                count = snprintf_serial(&buf, &buflen, "%la ",
                                        mesg->data.report.perf);
                if (count < 0) goto error;
                total += count;
            }
            break;

        default:
            goto invalid;
        }
    }

    if (total >= mesg->buflen) {
        buf = (char *) realloc(mesg->buf, total + 1);
        if (!buf)
            goto error;

        mesg->buf = buf;
        mesg->buflen = total + 1;
        goto top;
    }

    snprintf(hdr, sizeof(hdr), "XXXX%04d%02x", total, HMESG_VERSION);
    *(unsigned int *)(hdr) = htonl(HMESG_MAGIC);
    memcpy(mesg->buf, hdr, HMESG_HDRLEN);

    return total;

  invalid:
    errno = EINVAL;
  error:
    return -1;
}