Пример #1
0
static int
write_header_v1(struct save_data *save_data,
                struct ipset_node_cache *cache, ipset_node_id root)
{
    /* Output the magic number for an IP set, and the file format
     * version that we're going to write. */
    rii_check(cork_stream_consumer_data(save_data->stream, NULL, 0, true));
    rii_check(write_string(save_data->stream, MAGIC_NUMBER));
    rii_check(write_uint16(save_data->stream, 0x0001));

    /* Determine how many reachable nodes there are, to calculate the
     * size of the set. */
    size_t  nonterminal_count = ipset_node_reachable_count(cache, root);
    size_t  set_size =
        MAGIC_NUMBER_LENGTH +    /* magic number */
        sizeof(uint16_t) +        /* version number  */
        sizeof(uint64_t) +        /* length of set */
        sizeof(uint32_t) +        /* number of nonterminals */
        (nonterminal_count *     /* for each nonterminal: */
         (sizeof(uint8_t) +       /*   variable number */
          sizeof(uint32_t) +      /*   low pointer */
          sizeof(uint32_t)        /*   high pointer */
         ));

    /* If the root is a terminal, we need to add 4 bytes to the set
     * size, for storing the terminal value. */
    if (ipset_node_get_type(root) == IPSET_TERMINAL_NODE) {
        set_size += sizeof(uint32_t);
    }

    rii_check(write_uint64(save_data->stream, set_size));
    rii_check(write_uint32(save_data->stream, nonterminal_count));
    return 0;
}
Пример #2
0
static int
write_header_dot(struct save_data *save_data,
                 struct ipset_node_cache *cache, ipset_node_id root)
{
    /* Output the opening clause of the GraphViz script. */
    rii_check(cork_stream_consumer_data(save_data->stream, NULL, 0, true));
    return write_string(save_data->stream, GRAPHVIZ_HEADER);
}
Пример #3
0
static int
cork_read_pipe_read(struct cork_read_pipe *p, char *buf, bool *progress)
{
    if (p->fds[0] == -1) {
        return 0;
    }

    do {
        DEBUG("[read] Reading from pipe %d\n", p->fds[0]);
        ssize_t  bytes_read = read(p->fds[0], buf, BUF_SIZE);
        if (bytes_read == -1) {
            if (errno == EAGAIN) {
                /* We've exhausted all of the data currently available. */
                DEBUG("[read]   No more bytes without blocking\n");
                return 0;
            } else if (errno == EINTR) {
                /* Interrupted by a signal; return so that our wait loop can
                 * catch that. */
                DEBUG("[read]   Interrupted by signal\n");
                return 0;
            } else {
                /* An actual error */
                cork_system_error_set();
                DEBUG("[read]   Error: %s\n", cork_error_message());
                return -1;
            }
        } else if (bytes_read == 0) {
            DEBUG("[read]   End of stream\n");
            *progress = true;
            rii_check(cork_stream_consumer_eof(p->consumer));
            rii_check_posix(close(p->fds[0]));
            p->fds[0] = -1;
            return 0;
        } else {
            DEBUG("[read]   Got %zd bytes\n", bytes_read);
            *progress = true;
            rii_check(cork_stream_consumer_data
                      (p->consumer, buf, bytes_read, p->first));
            p->first = false;
        }
    } while (true);
}
Пример #4
0
static int
clog_stream_handler__message(struct clog_handler *vself,
                             struct clog_message *msg)
{
    struct clog_stream_handler  *self =
        cork_container_of(vself, struct clog_stream_handler, parent);

    if (clog_stream_handler_claim(self)) {
        /* Just claimed the lock; clear the buffer */
        rii_check(clog_formatter_start(self->fmt));
    }

    rii_check(clog_formatter_finish(self->fmt, msg, &self->buf));
    cork_buffer_append(&self->buf, "\n", 1);
    rii_check(cork_stream_consumer_data
              (self->consumer, self->buf.buf, self->buf.size,
               self->first_chunk));
    self->first_chunk = false;
    clog_stream_handler_release(self);
    return CLOG_CONTINUE;
}
Пример #5
0
int
cork_consume_file(struct cork_stream_consumer *consumer, FILE *fp)
{
    char  buf[BUFFER_SIZE];
    size_t  bytes_read;
    bool  first = true;

    while (true) {
        while ((bytes_read = fread(buf, 1, BUFFER_SIZE, fp)) > 0) {
            rii_check(cork_stream_consumer_data
                      (consumer, buf, bytes_read, first));
            first = false;
        }

        if (feof(fp)) {
            return cork_stream_consumer_eof(consumer);
        } else if (errno != EINTR) {
            cork_system_error_set();
            return -1;
        }
    }
}
Пример #6
0
int
cork_consume_fd(struct cork_stream_consumer *consumer, int fd)
{
    char  buf[BUFFER_SIZE];
    ssize_t  bytes_read;
    bool  first = true;

    while (true) {
        while ((bytes_read = read(fd, buf, BUFFER_SIZE)) > 0) {
            rii_check(cork_stream_consumer_data
                      (consumer, buf, bytes_read, first));
            first = false;
        }

        if (bytes_read == 0) {
            return cork_stream_consumer_eof(consumer);
        } else if (errno != EINTR) {
            cork_system_error_set();
            return -1;
        }
    }
}
Пример #7
0
static int
write_uint64(struct cork_stream_consumer *stream, uint64_t val)
{
    CORK_UINT64_HOST_TO_BIG_IN_PLACE(val);
    return cork_stream_consumer_data(stream, &val, sizeof(uint64_t), false);
}
Пример #8
0
/**
 * Write a big-endian uint8 to a stream.  If we can't write the
 * integer for some reason, return an error.
 */
static int
write_uint8(struct cork_stream_consumer *stream, uint8_t val)
{
    /* for a byte, we don't need to endian-swap */
    return cork_stream_consumer_data(stream, &val, sizeof(uint8_t), false);
}
Пример #9
0
/**
 * Write a NUL-terminated string to a stream.  If we can't write the
 * string for some reason, return an error.
 */
static int
write_string(struct cork_stream_consumer *stream, const char *str)
{
    size_t  len = strlen(str);
    return cork_stream_consumer_data(stream, str, len, false);
}