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.

101 lines
2.4 KiB

10 years ago
  1. /* -*- coding: utf-8 -*-
  2. * ----------------------------------------------------------------------
  3. * Copyright © 2009-2012, RedJack, LLC.
  4. * All rights reserved.
  5. *
  6. * Please see the LICENSE.txt file in this distribution for license
  7. * details.
  8. * ----------------------------------------------------------------------
  9. */
  10. #include <errno.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <libcork/core.h>
  15. #include "ipset/bdd/nodes.h"
  16. #include "ipset/errors.h"
  17. #include "ipset/ipset.h"
  18. static void
  19. create_errno_error(FILE *stream)
  20. {
  21. if (ferror(stream)) {
  22. cork_error_set(IPSET_ERROR, IPSET_IO_ERROR, "%s", strerror(errno));
  23. } else {
  24. cork_unknown_error();
  25. }
  26. }
  27. struct file_consumer {
  28. /* file_consumer is a subclass of cork_stream_consumer */
  29. struct cork_stream_consumer parent;
  30. /* the file to write the data into */
  31. FILE *fp;
  32. };
  33. static int
  34. file_consumer_data(struct cork_stream_consumer *vself,
  35. const void *buf, size_t size, bool is_first)
  36. {
  37. struct file_consumer *self =
  38. cork_container_of(vself, struct file_consumer, parent);
  39. size_t bytes_written = fwrite(buf, 1, size, self->fp);
  40. /* If there was an error writing to the file, then signal this to
  41. * the producer */
  42. if (bytes_written == size) {
  43. return 0;
  44. } else {
  45. create_errno_error(self->fp);
  46. return -1;
  47. }
  48. }
  49. static int
  50. file_consumer_eof(struct cork_stream_consumer *vself)
  51. {
  52. /* We don't close the file, so there's nothing special to do at
  53. * end-of-stream. */
  54. return 0;
  55. }
  56. int
  57. ipmap_save_to_stream(struct cork_stream_consumer *stream,
  58. const struct ip_map *map)
  59. {
  60. return ipset_node_cache_save(stream, map->cache, map->map_bdd);
  61. }
  62. int
  63. ipmap_save(FILE *fp, const struct ip_map *map)
  64. {
  65. struct file_consumer stream = {
  66. { file_consumer_data, file_consumer_eof, NULL }, fp
  67. };
  68. return ipmap_save_to_stream(&stream.parent, map);
  69. }
  70. struct ip_map *
  71. ipmap_load(FILE *stream)
  72. {
  73. struct ip_map *map;
  74. ipset_node_id new_bdd;
  75. /* It doesn't matter what default value we use here, because we're
  76. * going to replace it with the default BDD we load in from the
  77. * file. */
  78. map = ipmap_new(0);
  79. new_bdd = ipset_node_cache_load(stream, map->cache);
  80. if (cork_error_occurred()) {
  81. ipmap_free(map);
  82. return NULL;
  83. }
  84. map->map_bdd = new_bdd;
  85. return map;
  86. }