osxmain.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*
  2. * Copyright (C) 2004-2017 Savoir-faire Linux Inc.
  3. *
  4. * Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>
  5. * Author: Yan Morin <yan.morin@savoirfairelinux.com>
  6. * Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21. */
  22. #include <iostream>
  23. #include <thread>
  24. #include <cstring>
  25. #include <signal.h>
  26. #include <getopt.h>
  27. #include <string>
  28. #include "dring.h"
  29. #include "callmanager_interface.h"
  30. #include "configurationmanager_interface.h"
  31. #include "presencemanager_interface.h"
  32. #ifdef RING_VIDEO
  33. #include "videomanager_interface.h"
  34. #endif
  35. #include "fileutils.h"
  36. static int ringFlags = 0;
  37. static void
  38. print_title()
  39. {
  40. std::cout
  41. << "Ring Daemon " << DRing::version()
  42. << ", by Savoir-faire Linux 2004-2017" << std::endl
  43. << "http://www.ring.cx/" << std::endl
  44. #ifdef RING_VIDEO
  45. << "[Video support enabled]" << std::endl
  46. #endif
  47. << std::endl;
  48. }
  49. static void
  50. print_usage()
  51. {
  52. std::cout << std::endl <<
  53. "-c, --console \t- Log in console (instead of syslog)" << std::endl <<
  54. "-d, --debug \t- Debug mode (more verbose)" << std::endl <<
  55. "-p, --persistent \t- Stay alive after client quits" << std::endl <<
  56. "--auto-answer \t- Force automatic answer to incoming calls" << std::endl <<
  57. "-h, --help \t- Print help" << std::endl;
  58. }
  59. // Parse command line arguments, setting debug options or printing a help
  60. // message accordingly.
  61. // returns true if we should quit (i.e. help was printed), false otherwise
  62. static bool
  63. parse_args(int argc, char *argv[], bool& persistent)
  64. {
  65. int consoleFlag = false;
  66. int debugFlag = false;
  67. int helpFlag = false;
  68. int versionFlag = false;
  69. int autoAnswer = false;
  70. const struct option long_options[] = {
  71. /* These options set a flag. */
  72. {"debug", no_argument, NULL, 'd'},
  73. {"console", no_argument, NULL, 'c'},
  74. {"persistent", no_argument, NULL, 'p'},
  75. {"help", no_argument, NULL, 'h'},
  76. {"version", no_argument, NULL, 'v'},
  77. {"auto-answer", no_argument, &autoAnswer, true},
  78. {0, 0, 0, 0} /* Sentinel */
  79. };
  80. while (true) {
  81. /* getopt_long stores the option index here. */
  82. int option_index = 0;
  83. auto c = getopt_long(argc, argv, "dcphv", long_options, &option_index);
  84. // end of the options
  85. if (c == -1)
  86. break;
  87. switch (c) {
  88. case 'd':
  89. debugFlag = true;
  90. break;
  91. case 'c':
  92. consoleFlag = true;
  93. break;
  94. case 'p':
  95. persistent = true;
  96. break;
  97. case 'h':
  98. case '?':
  99. helpFlag = true;
  100. break;
  101. case 'v':
  102. versionFlag = true;
  103. break;
  104. default:
  105. break;
  106. }
  107. }
  108. if (helpFlag) {
  109. print_usage();
  110. return true;
  111. }
  112. if (versionFlag) {
  113. // We've always print the title/version, so we can just exit
  114. return true;
  115. }
  116. if (consoleFlag)
  117. ringFlags |= DRing::DRING_FLAG_CONSOLE_LOG;
  118. if (debugFlag)
  119. ringFlags |= DRing::DRING_FLAG_DEBUG;
  120. if (autoAnswer)
  121. ringFlags |= DRing::DRING_FLAG_AUTOANSWER;
  122. return false;
  123. }
  124. static int
  125. osxTests()
  126. {
  127. using SharedCallback = std::shared_ptr<DRing::CallbackWrapperBase>;
  128. DRing::init(static_cast<DRing::InitFlag>(ringFlags));
  129. registerCallHandlers(std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>>());
  130. registerConfHandlers(std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>>());
  131. registerPresHandlers(std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>>());
  132. #ifdef RING_VIDEO
  133. registerVideoHandlers(std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>>());
  134. #endif
  135. if (!DRing::start())
  136. return -1;
  137. while (true) {
  138. DRing::pollEvents();
  139. sleep(1);
  140. }
  141. DRing::fini();
  142. }
  143. static int
  144. run()
  145. {
  146. osxTests();
  147. return 0;
  148. }
  149. static void
  150. interrupt()
  151. {}
  152. static void
  153. signal_handler(int code)
  154. {
  155. std::cerr << "Caught signal " << strsignal(code)
  156. << ", terminating..." << std::endl;
  157. // Unset signal handlers
  158. signal(SIGHUP, SIG_DFL);
  159. signal(SIGINT, SIG_DFL);
  160. signal(SIGTERM, SIG_DFL);
  161. interrupt();
  162. }
  163. int
  164. main(int argc, char *argv [])
  165. {
  166. // make a copy as we don't want to modify argv[0], copy it to a vector to
  167. // guarantee that memory is correctly managed/exception safe
  168. std::string programName {argv[0]};
  169. std::vector<char> writable(programName.size() + 1);
  170. std::copy(programName.begin(), programName.end(), writable.begin());
  171. ring::fileutils::set_program_dir(writable.data());
  172. #ifdef TOP_BUILDDIR
  173. if (!getenv("CODECS_PATH"))
  174. setenv("CODECS_PATH", TOP_BUILDDIR "/src/media/audio/codecs", 1);
  175. #endif
  176. print_title();
  177. bool persistent = false;
  178. if (parse_args(argc, argv, persistent))
  179. return 0;
  180. // TODO: Block signals for all threads but the main thread, decide how/if we should
  181. // handle other signals
  182. signal(SIGINT, signal_handler);
  183. signal(SIGHUP, signal_handler);
  184. signal(SIGTERM, signal_handler);
  185. return run();
  186. }