fieldset.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. * ZMap Copyright 2013 Regents of the University of Michigan
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy
  6. * of the License at http://www.apache.org/licenses/LICENSE-2.0
  7. */
  8. #include "fieldset.h"
  9. #include <string.h>
  10. #include <stdint.h>
  11. #include <stdlib.h>
  12. #include <assert.h>
  13. #include "../lib/logger.h"
  14. #include "../lib/xalloc.h"
  15. void gen_fielddef_set(fielddefset_t *fds, fielddef_t fs[], int len)
  16. {
  17. if (fds->len + len > MAX_FIELDS) {
  18. log_fatal("fieldset", "out of room in field def set");
  19. }
  20. fielddef_t *open = &(fds->fielddefs[fds->len]);
  21. memcpy(open, fs, len*sizeof(fielddef_t));
  22. fds->len += len;
  23. }
  24. fieldset_t *fs_new_fieldset(void)
  25. {
  26. fieldset_t *f = xcalloc(1, sizeof(fieldset_t));
  27. return f;
  28. }
  29. static inline void fs_add_word(fieldset_t *fs, const char *name, int type,
  30. int free_, size_t len, field_val_t value)
  31. {
  32. if (fs->len + 1 >= MAX_FIELDS) {
  33. log_fatal("fieldset", "out of room in fieldset");
  34. }
  35. field_t *f = &(fs->fields[fs->len]);
  36. fs->len++;
  37. f->type = type;
  38. f->name = name;
  39. f->len = len;
  40. f->value = value;
  41. f->free_ = free_;
  42. }
  43. static void fs_modify_word(fieldset_t *fs, const char *name, int type,
  44. int free_, size_t len, field_val_t value)
  45. {
  46. for (int i=0; i<fs->len; i++) {
  47. if (!strcmp(fs->fields[i].name, name)) {
  48. if (fs->fields[i].free_) {
  49. free(fs->fields[i].value.ptr);
  50. fs->fields[i].value.ptr = NULL;
  51. }
  52. fs->fields[i].type = type;
  53. fs->fields[i].free_ = free_;
  54. fs->fields[i].len = len;
  55. fs->fields[i].value = value;
  56. return;
  57. }
  58. }
  59. fs_add_word(fs, name, type, free_, len, value);
  60. }
  61. void fs_add_null(fieldset_t *fs, const char *name)
  62. {
  63. field_val_t val = { .ptr = NULL };
  64. fs_add_word(fs, name, FS_NULL, 0, 0, val);
  65. }
  66. void fs_add_string(fieldset_t *fs, const char *name, char *value, int free_)
  67. {
  68. field_val_t val = { .ptr = value };
  69. fs_add_word(fs, name, FS_STRING, free_, strlen(value), val);
  70. }
  71. void fs_add_uint64(fieldset_t *fs, const char *name, uint64_t value)
  72. {
  73. field_val_t val = { .num = value };
  74. fs_add_word(fs, name, FS_UINT64, 0, sizeof(uint64_t), val);
  75. }
  76. void fs_add_binary(fieldset_t *fs, const char *name, size_t len,
  77. void *value, int free_)
  78. {
  79. field_val_t val = { .ptr = value };
  80. fs_add_word(fs, name, FS_BINARY, free_, len, val);
  81. }
  82. // Modify
  83. void fs_modify_null(fieldset_t *fs, const char *name)
  84. {
  85. field_val_t val = { .ptr = NULL };
  86. fs_modify_word(fs, name, FS_NULL, 0, 0, val);
  87. }
  88. void fs_modify_string(fieldset_t *fs, const char *name, char *value, int free_)
  89. {
  90. field_val_t val = { .ptr = value };
  91. fs_modify_word(fs, name, FS_STRING, free_, strlen(value), val);
  92. }
  93. void fs_modify_uint64(fieldset_t *fs, const char *name, uint64_t value)
  94. {
  95. field_val_t val = { .num = value };
  96. fs_modify_word(fs, name, FS_UINT64, 0, sizeof(uint64_t), val);
  97. }
  98. void fs_modify_binary(fieldset_t *fs, const char *name, size_t len,
  99. void *value, int free_)
  100. {
  101. field_val_t val = { .ptr = value };
  102. fs_modify_word(fs, name, FS_BINARY, free_, len, val);
  103. }
  104. uint64_t fs_get_uint64_by_index(fieldset_t *fs, int index)
  105. {
  106. return (uint64_t) fs->fields[index].value.num;
  107. }
  108. char* fs_get_string_by_index(fieldset_t *fs, int index)
  109. {
  110. return (char*) fs->fields[index].value.ptr;
  111. }
  112. int fds_get_index_by_name(fielddefset_t *fds, char *name)
  113. {
  114. for (int i=0; i < fds->len; i++) {
  115. if (!strcmp(fds->fielddefs[i].name, name)) {
  116. return i;
  117. }
  118. }
  119. return -1;
  120. }
  121. void fs_free(fieldset_t *fs)
  122. {
  123. if (!fs) {
  124. return;
  125. }
  126. for (int i=0; i < fs->len; i++) {
  127. field_t *f = &(fs->fields[i]);
  128. if (f->free_) {
  129. free(f->value.ptr);
  130. }
  131. }
  132. free(fs);
  133. }
  134. void fs_generate_fieldset_translation(translation_t *t,
  135. fielddefset_t *avail, char** req, int reqlen)
  136. {
  137. memset(t, 0, sizeof(translation_t));
  138. if (!t) {
  139. log_fatal("fieldset", "unable to allocate memory for translation");
  140. }
  141. for (int i=0; i < reqlen; i++) {
  142. int l = fds_get_index_by_name(avail, req[i]);
  143. if (l < 0) {
  144. log_fatal("fieldset", "specified field (%s) not "
  145. "available in selected "
  146. "probe module.", req[i]);
  147. }
  148. t->translation[t->len++] = l;
  149. }
  150. }
  151. void fs_generate_full_fieldset_translation(translation_t *t, fielddefset_t *avail)
  152. {
  153. memset(t, 0, sizeof(translation_t));
  154. if (!t) {
  155. log_fatal("fieldset", "unable to allocate memory for translation");
  156. }
  157. t->len = avail->len;
  158. for (int i=0; i < avail->len; i++) {
  159. t->translation[i] = i;
  160. }
  161. }
  162. fieldset_t *translate_fieldset(fieldset_t *fs, translation_t *t)
  163. {
  164. fieldset_t *retv = fs_new_fieldset();
  165. if (!retv) {
  166. log_fatal("fieldset", "unable to allocate space for translated field set");
  167. }
  168. for (int i=0; i < t->len; i++) {
  169. int o = t->translation[i];
  170. memcpy(&(retv->fields[i]), &(fs->fields[o]), sizeof(field_t));
  171. }
  172. retv->len = t->len;
  173. return retv;
  174. }