You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

107 lines
2.5 KiB

/* -*- 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;
}