ubus.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * Copyright (C) 2014 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 <sys/types.h>
  14. #include <arpa/inet.h>
  15. #include <stdio.h>
  16. #include <libubus.h>
  17. #include <libubox/avl.h>
  18. #include <libubox/uloop.h>
  19. #include "ubus.h"
  20. #include "cache.h"
  21. #include "service.h"
  22. static struct ubus_auto_conn conn;
  23. static struct blob_buf b;
  24. static int
  25. mdns_reload(struct ubus_context *ctx, struct ubus_object *obj,
  26. struct ubus_request_data *req, const char *method,
  27. struct blob_attr *msg)
  28. {
  29. service_init();
  30. return 0;
  31. }
  32. static int
  33. mdns_scan(struct ubus_context *ctx, struct ubus_object *obj,
  34. struct ubus_request_data *req, const char *method,
  35. struct blob_attr *msg)
  36. {
  37. cache_scan();
  38. return 0;
  39. }
  40. static int
  41. mdns_browse(struct ubus_context *ctx, struct ubus_object *obj,
  42. struct ubus_request_data *req, const char *method,
  43. struct blob_attr *msg)
  44. {
  45. struct cache_entry *s, *q;
  46. char buffer[MAX_NAME_LEN];
  47. void *c1 = NULL, *c2;
  48. blob_buf_init(&b, 0);
  49. avl_for_each_element(&entries, s, avl) {
  50. char *local;
  51. if (*((char *) s->avl.key) != '_')
  52. continue;
  53. snprintf(buffer, MAX_NAME_LEN, "%s", (const char *) s->avl.key);
  54. local = strstr(buffer, ".local");
  55. if (local)
  56. *local = '\0';
  57. if (!strcmp(buffer, "_tcp") || !strcmp(buffer, "_udp"))
  58. continue;
  59. if (!c1) {
  60. c1 = blobmsg_open_table(&b, buffer);
  61. }
  62. snprintf(buffer, MAX_NAME_LEN, "%s", (const char *) s->entry);
  63. local = strstr(buffer, "._");
  64. if (local)
  65. *local = '\0';
  66. c2 = blobmsg_open_table(&b, buffer);
  67. strncat(buffer, ".local", MAX_NAME_LEN);
  68. cache_dump_records(&b, buffer);
  69. cache_dump_records(&b, s->entry);
  70. blobmsg_close_table(&b, c2);
  71. q = avl_next_element(s, avl);
  72. if (!q || avl_is_last(&entries, &s->avl) || strcmp(s->avl.key, q->avl.key)) {
  73. blobmsg_close_table(&b, c1);
  74. c1 = NULL;
  75. }
  76. }
  77. ubus_send_reply(ctx, req, b.head);
  78. return UBUS_STATUS_OK;
  79. }
  80. static int
  81. mdns_hosts(struct ubus_context *ctx, struct ubus_object *obj,
  82. struct ubus_request_data *req, const char *method,
  83. struct blob_attr *msg)
  84. {
  85. struct cache_entry *s;
  86. char buffer[MAX_NAME_LEN];
  87. void *c;
  88. blob_buf_init(&b, 0);
  89. avl_for_each_element(&entries, s, avl) {
  90. char *local;
  91. if (*((char *) s->avl.key) == '_')
  92. continue;
  93. snprintf(buffer, MAX_NAME_LEN, "%s", (const char *) s->entry);
  94. local = strstr(buffer, "._");
  95. if (local)
  96. *local = '\0';
  97. c = blobmsg_open_table(&b, buffer);
  98. strncat(buffer, ".local", MAX_NAME_LEN);
  99. cache_dump_records(&b, buffer);
  100. cache_dump_records(&b, s->entry);
  101. blobmsg_close_table(&b, c);
  102. }
  103. ubus_send_reply(ctx, req, b.head);
  104. return UBUS_STATUS_OK;
  105. }
  106. static const struct ubus_method mdns_methods[] = {
  107. UBUS_METHOD_NOARG("scan", mdns_scan),
  108. UBUS_METHOD_NOARG("browse", mdns_browse),
  109. UBUS_METHOD_NOARG("hosts", mdns_hosts),
  110. UBUS_METHOD_NOARG("reload", mdns_reload),
  111. };
  112. static struct ubus_object_type mdns_object_type =
  113. UBUS_OBJECT_TYPE("mdns", mdns_methods);
  114. static struct ubus_object mdns_object = {
  115. .name = "mdns",
  116. .type = &mdns_object_type,
  117. .methods = mdns_methods,
  118. .n_methods = ARRAY_SIZE(mdns_methods),
  119. };
  120. static void
  121. ubus_connect_handler(struct ubus_context *ctx)
  122. {
  123. int ret;
  124. ret = ubus_add_object(ctx, &mdns_object);
  125. if (ret)
  126. fprintf(stderr, "Failed to add object: %s\n", ubus_strerror(ret));
  127. }
  128. void
  129. ubus_startup(void)
  130. {
  131. conn.cb = ubus_connect_handler;
  132. ubus_auto_connect(&conn);
  133. }