validate.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser General Public License version 2.1
  6. * as published by the Free Software Foundation
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <libubox/blobmsg_json.h>
  14. #include <libubox/avl-cmp.h>
  15. #include <json-c/json.h>
  16. #include "../procd.h"
  17. #include "service.h"
  18. enum {
  19. SERVICE_VAL_PACKAGE,
  20. SERVICE_VAL_TYPE,
  21. SERVICE_VAL_DATA,
  22. __SERVICE_VAL_MAX
  23. };
  24. static const struct blobmsg_policy service_validate_attrs[__SERVICE_VAL_MAX] = {
  25. [SERVICE_VAL_PACKAGE] = { "package", BLOBMSG_TYPE_STRING },
  26. [SERVICE_VAL_TYPE] = { "type", BLOBMSG_TYPE_STRING },
  27. [SERVICE_VAL_DATA] = { "data", BLOBMSG_TYPE_TABLE },
  28. };
  29. static AVL_TREE(validators, avl_strcmp, true, NULL);
  30. void
  31. service_validate_dump_all(struct blob_buf *b, char *p, char *s)
  32. {
  33. struct json_object *r = json_object_new_object();
  34. struct validate *v;
  35. if (!r)
  36. return;
  37. avl_for_each_element(&validators, v, avl) {
  38. struct json_object *o, *t;
  39. struct vrule *vr;
  40. if (p && strcmp(p, v->package))
  41. continue;
  42. if (s && strcmp(s, v->type))
  43. continue;
  44. json_object_object_get_ex(r, v->package, &o);
  45. if (!o) {
  46. o = json_object_new_object();
  47. json_object_object_add(r, v->package, o);
  48. }
  49. json_object_object_get_ex(o, v->type, &t);
  50. if (!t) {
  51. t = json_object_new_object();
  52. json_object_object_add(o, v->type, t);
  53. }
  54. avl_for_each_element(&v->rules, vr, avl)
  55. json_object_object_add(t, vr->option, json_object_new_string(vr->rule));
  56. }
  57. blobmsg_add_object(b, r);
  58. json_object_put(r);
  59. }
  60. void
  61. service_validate_dump(struct blob_buf *b, struct service *s)
  62. {
  63. struct validate *v;
  64. void *i = blobmsg_open_array(b, "validate");
  65. list_for_each_entry(v, &s->validators, list) {
  66. struct vrule *vr;
  67. void *k, *j = blobmsg_open_table(b, "validate");
  68. blobmsg_add_string(b, "package", v->package);
  69. blobmsg_add_string(b, "type", v->type);
  70. k = blobmsg_open_table(b, "rules");
  71. avl_for_each_element(&v->rules, vr, avl)
  72. blobmsg_add_string(b, vr->option, vr->rule);
  73. blobmsg_close_table(b, k);
  74. blobmsg_close_table(b, j);
  75. }
  76. blobmsg_close_array(b, i);
  77. }
  78. void
  79. service_validate_del(struct service *s)
  80. {
  81. struct validate *v, *n;
  82. if (list_empty(&s->validators))
  83. return;
  84. list_for_each_entry_safe(v, n, &s->validators, list) {
  85. struct vrule *vr, *a;
  86. avl_remove_all_elements(&v->rules, vr, avl, a)
  87. free(vr);
  88. avl_delete(&validators, &v->avl);
  89. list_del(&v->list);
  90. free(v);
  91. }
  92. }
  93. void
  94. service_validate_add(struct service *s, struct blob_attr *msg)
  95. {
  96. struct blob_attr *tb[__SERVICE_VAL_MAX];
  97. struct validate *v;
  98. char *type, *package;
  99. struct blob_attr *cur;
  100. int rem;
  101. blobmsg_parse(service_validate_attrs, __SERVICE_VAL_MAX, tb, blobmsg_data(msg), blobmsg_data_len(msg));
  102. if (!tb[SERVICE_VAL_PACKAGE] || !tb[SERVICE_VAL_TYPE] || !tb[SERVICE_VAL_DATA])
  103. return;
  104. v = calloc_a(sizeof(*v), &package, blobmsg_data_len(tb[SERVICE_VAL_PACKAGE]) + 1,
  105. &type, blobmsg_data_len(tb[SERVICE_VAL_TYPE]) + 1);
  106. if (!v)
  107. return;
  108. v->type = type;
  109. v->avl.key = v->package = package;
  110. strcpy(v->package, blobmsg_get_string(tb[SERVICE_VAL_PACKAGE]));
  111. strcpy(v->type, blobmsg_get_string(tb[SERVICE_VAL_TYPE]));
  112. list_add(&v->list, &s->validators);
  113. if (avl_insert(&validators, &v->avl)) {
  114. free(v);
  115. return;
  116. }
  117. avl_init(&v->rules, avl_strcmp, false, NULL);
  118. blobmsg_for_each_attr(cur, tb[SERVICE_VAL_DATA], rem) {
  119. char *option;
  120. char *rule;
  121. struct vrule *vr = calloc_a(sizeof(*vr), &option, strlen(blobmsg_name(cur)) + 1,
  122. &rule, strlen(blobmsg_get_string(cur)) + 1);
  123. vr->avl.key = vr->option = option;
  124. vr->rule = rule;
  125. strcpy(vr->option, blobmsg_name(cur));
  126. strcpy(vr->rule, blobmsg_get_string(cur));
  127. if (avl_insert(&v->rules, &vr->avl))
  128. free(vr);
  129. }
  130. }