main.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * rpcd - UBUS RPC server
  3. *
  4. * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
  5. * Copyright (C) 2013-2014 Jo-Philipp Wich <jow@openwrt.org>
  6. *
  7. * Permission to use, copy, modify, and/or distribute this software for any
  8. * purpose with or without fee is hereby granted, provided that the above
  9. * copyright notice and this permission notice appear in all copies.
  10. *
  11. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  12. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  13. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  14. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  15. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  16. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  17. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  18. */
  19. #include <unistd.h>
  20. #include <stdlib.h>
  21. #include <libubox/blobmsg_json.h>
  22. #include <libubus.h>
  23. #include <signal.h>
  24. #include <sys/stat.h>
  25. #include <rpcd/exec.h>
  26. #include <rpcd/plugin.h>
  27. #include <rpcd/rc.h>
  28. #include <rpcd/session.h>
  29. #include <rpcd/uci.h>
  30. static struct ubus_context *ctx;
  31. static bool respawn = false;
  32. int rpc_exec_timeout = RPC_EXEC_DEFAULT_TIMEOUT;
  33. static void
  34. handle_signal(int sig)
  35. {
  36. rpc_session_freeze();
  37. uloop_cancelled = true;
  38. respawn = (sig == SIGHUP);
  39. }
  40. static void
  41. exec_self(int argc, char **argv)
  42. {
  43. int i;
  44. const char *cmd;
  45. char **args;
  46. cmd = rpc_exec_lookup(argv[0]);
  47. if (!cmd)
  48. return;
  49. args = calloc(argc + 1, sizeof(char *));
  50. if (!args)
  51. return;
  52. for (i = 0; i < argc; i++)
  53. args[i] = argv[i];
  54. setenv("RPC_HANGUP", "1", 1);
  55. execv(cmd, (char * const *)args);
  56. }
  57. int main(int argc, char **argv)
  58. {
  59. struct stat s;
  60. const char *hangup;
  61. const char *ubus_socket = NULL;
  62. int ch;
  63. while ((ch = getopt(argc, argv, "s:t:")) != -1) {
  64. switch (ch) {
  65. case 's':
  66. ubus_socket = optarg;
  67. break;
  68. case 't':
  69. rpc_exec_timeout = 1000 * strtol(optarg, NULL, 0);
  70. break;
  71. default:
  72. break;
  73. }
  74. }
  75. if (rpc_exec_timeout < 1000 || rpc_exec_timeout > 600000) {
  76. fprintf(stderr, "Invalid execution timeout specified\n");
  77. return -1;
  78. }
  79. if (stat(RPC_UCI_DIR_PREFIX, &s))
  80. mkdir(RPC_UCI_DIR_PREFIX, 0700);
  81. umask(0077);
  82. signal(SIGPIPE, SIG_IGN);
  83. signal(SIGHUP, handle_signal);
  84. signal(SIGUSR1, handle_signal);
  85. uloop_init();
  86. ctx = ubus_connect(ubus_socket);
  87. if (!ctx) {
  88. fprintf(stderr, "Failed to connect to ubus\n");
  89. return -1;
  90. }
  91. ubus_add_uloop(ctx);
  92. rpc_session_api_init(ctx);
  93. rpc_uci_api_init(ctx);
  94. rpc_rc_api_init(ctx);
  95. rpc_plugin_api_init(ctx);
  96. hangup = getenv("RPC_HANGUP");
  97. if (!hangup || strcmp(hangup, "1"))
  98. rpc_uci_purge_savedirs();
  99. else
  100. rpc_session_thaw();
  101. uloop_run();
  102. ubus_free(ctx);
  103. uloop_done();
  104. if (respawn)
  105. exec_self(argc, argv);
  106. return 0;
  107. }