|
|
/* -*- coding: utf-8 -*-
* ---------------------------------------------------------------------- * Copyright © 2010-2012, RedJack, LLC. * All rights reserved. * * Please see the LICENSE.txt file in this distribution for license * details. * ---------------------------------------------------------------------- */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libcork/core.h>
#include "ipset/bdd/nodes.h"
#include "ipset/errors.h"
#include "ipset/ipset.h"
static void create_errno_error(FILE *stream) { if (ferror(stream)) { cork_error_set(IPSET_ERROR, IPSET_IO_ERROR, "%s", strerror(errno)); } else { cork_unknown_error(); } }
struct file_consumer { /* file_consumer is a subclass of cork_stream_consumer */ struct cork_stream_consumer parent; /* the file to write the data into */ FILE *fp; };
static int file_consumer_data(struct cork_stream_consumer *vself, const void *buf, size_t size, bool is_first) { struct file_consumer *self = cork_container_of(vself, struct file_consumer, parent); size_t bytes_written = fwrite(buf, 1, size, self->fp); /* If there was an error writing to the file, then signal this to
* the producer */ if (bytes_written == size) { return 0; } else { create_errno_error(self->fp); return -1; } }
static int file_consumer_eof(struct cork_stream_consumer *vself) { /* We don't close the file, so there's nothing special to do at
* end-of-stream. */ return 0; }
int ipset_save_to_stream(struct cork_stream_consumer *stream, const struct ip_set *set) { return ipset_node_cache_save(stream, set->cache, set->set_bdd); }
int ipset_save(FILE *fp, const struct ip_set *set) { struct file_consumer stream = { { file_consumer_data, file_consumer_eof, NULL }, fp }; return ipset_save_to_stream(&stream.parent, set); }
int ipset_save_dot(FILE *fp, const struct ip_set *set) { struct file_consumer stream = { { file_consumer_data, file_consumer_eof, NULL }, fp }; return ipset_node_cache_save_dot(&stream.parent, set->cache, set->set_bdd); }
struct ip_set * ipset_load(FILE *stream) { struct ip_set *set; ipset_node_id new_bdd;
set = ipset_new(); new_bdd = ipset_node_cache_load(stream, set->cache); if (cork_error_occurred()) { ipset_free(set); return NULL; }
set->set_bdd = new_bdd; return set; }
|