list.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /* $Id: list.c 1897 2007-08-25 04:57:38Z aturner $ */
  2. /*
  3. * Copyright (c) 2001-2004 Aaron Turner.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the names of the copyright owners nor the names of its
  16. * contributors may be used to endorse or promote products derived from
  17. * this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  20. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  23. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  25. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  27. * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  28. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  29. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. /*
  32. * A generic method to parse a list of integers which are
  33. * delimited by commas and dashes to indicate individual
  34. * numbers and ranges
  35. * Provides both a way to process the list and determine
  36. * if an integer exists in the list.
  37. */
  38. #include "config.h"
  39. #include "defines.h"
  40. #include "common.h"
  41. #include <stdlib.h>
  42. #include <string.h>
  43. #include <sys/types.h>
  44. #include <regex.h>
  45. #include <errno.h>
  46. /**
  47. * Creates a new tcpr_list entry. Malloc's memory.
  48. */
  49. tcpr_list_t *
  50. new_list()
  51. {
  52. tcpr_list_t *newlist;
  53. newlist = (tcpr_list_t *)safe_malloc(sizeof(tcpr_list_t));
  54. return (newlist);
  55. }
  56. /**
  57. * Processes a string (ourstr) containing the list in human readable
  58. * format and places the data in **list and finally returns 1 for
  59. * success, 0 for fail.
  60. */
  61. int
  62. parse_list(tcpr_list_t ** listdata, char *ourstr)
  63. {
  64. tcpr_list_t *listcur, *list_ptr;
  65. char *this = NULL;
  66. char *first, *second;
  67. int rcode;
  68. regex_t preg;
  69. char ebuf[EBUF_SIZE];
  70. char regex[] = "^[0-9]+(-[0-9]+)?$";
  71. char *token = NULL;
  72. /* compile the regex first */
  73. if ((rcode = regcomp(&preg, regex, REG_EXTENDED | REG_NOSUB)) != 0) {
  74. regerror(rcode, &preg, ebuf, sizeof(ebuf));
  75. errx(1, "Unable to compile regex (%s): %s", regex, ebuf);
  76. }
  77. /* first iteration */
  78. this = strtok_r(ourstr, ",", &token);
  79. first = this;
  80. second = NULL;
  81. /* regex test */
  82. if (regexec(&preg, this, 0, NULL, 0) != 0) {
  83. warnx("Unable to parse: %s", this);
  84. return 0;
  85. }
  86. *listdata = new_list();
  87. list_ptr = *listdata;
  88. listcur = list_ptr;
  89. for (u_int i = 0; i < strlen(this); i++) {
  90. if (this[i] == '-') {
  91. this[i] = '\0';
  92. second = &this[i + 1];
  93. }
  94. }
  95. list_ptr->min = strtoull(first, NULL, 0);
  96. if (second != NULL) {
  97. list_ptr->max = strtoull(second, NULL, 0);
  98. }
  99. else {
  100. list_ptr->max = list_ptr->min;
  101. }
  102. while (1) {
  103. this = strtok_r(NULL, ",", &token);
  104. if (this == NULL)
  105. break;
  106. first = this;
  107. second = NULL;
  108. /* regex test */
  109. if (regexec(&preg, this, 0, NULL, 0) != 0) {
  110. warnx("Unable to parse: %s", this);
  111. return 0;
  112. }
  113. listcur->next = new_list();
  114. listcur = listcur->next;
  115. for (u_int i = 0; i < strlen(this); i++) {
  116. if (this[i] == '-') {
  117. this[i] = '\0';
  118. second = &this[i + 1];
  119. }
  120. }
  121. listcur->min = strtoull(first, NULL, 0);
  122. if (second != NULL) {
  123. listcur->max = strtoull(second, NULL, 0);
  124. }
  125. else {
  126. listcur->max = listcur->min;
  127. }
  128. }
  129. return 1;
  130. }
  131. /**
  132. * Checks to see if the given integer exists in the LIST.
  133. */
  134. tcpr_dir_t
  135. check_list(tcpr_list_t * list, COUNTER value)
  136. {
  137. tcpr_list_t *current;
  138. current = list;
  139. do {
  140. if ((current->min != 0) && (current->max != 0)) {
  141. if ((value >= current->min) && (value <= current->max))
  142. return TCPR_DIR_C2S;
  143. }
  144. else if (current->min == 0) {
  145. if (value <= current->max)
  146. return TCPR_DIR_C2S;
  147. }
  148. else if (current->max == 0) {
  149. if (value >= current->min)
  150. return TCPR_DIR_C2S;
  151. }
  152. if (current->next != NULL) {
  153. current = current->next;
  154. }
  155. else {
  156. current = NULL;
  157. }
  158. } while (current != NULL);
  159. return TCPR_DIR_S2C;
  160. }
  161. /**
  162. * Free's all the memory associated with the given LIST
  163. */
  164. void
  165. free_list(tcpr_list_t * list)
  166. {
  167. /* recursively go down the list */
  168. if (list->next != NULL)
  169. free_list(list->next);
  170. safe_free(list);
  171. }
  172. /*
  173. Local Variables:
  174. mode:c
  175. indent-tabs-mode:nil
  176. c-basic-offset:4
  177. End:
  178. */