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

10 years ago
  1. /* -*- coding: utf-8 -*-
  2. * ----------------------------------------------------------------------
  3. * Copyright © 2010-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. ipset_save_to_stream(struct cork_stream_consumer *stream,
  58. const struct ip_set *set)
  59. {
  60. return ipset_node_cache_save(stream, set->cache, set->set_bdd);
  61. }
  62. int
  63. ipset_save(FILE *fp, const struct ip_set *set)
  64. {
  65. struct file_consumer stream = {
  66. { file_consumer_data, file_consumer_eof, NULL }, fp
  67. };
  68. return ipset_save_to_stream(&stream.parent, set);
  69. }
  70. int
  71. ipset_save_dot(FILE *fp, const struct ip_set *set)
  72. {
  73. struct file_consumer stream = {
  74. { file_consumer_data, file_consumer_eof, NULL }, fp
  75. };
  76. return ipset_node_cache_save_dot(&stream.parent, set->cache, set->set_bdd);
  77. }
  78. struct ip_set *
  79. ipset_load(FILE *stream)
  80. {
  81. struct ip_set *set;
  82. ipset_node_id new_bdd;
  83. set = ipset_new();
  84. new_bdd = ipset_node_cache_load(stream, set->cache);
  85. if (cork_error_occurred()) {
  86. ipset_free(set);
  87. return NULL;
  88. }
  89. set->set_bdd = new_bdd;
  90. return set;
  91. }