awlsim-server 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. #
  4. # AWL simulator - Server interface
  5. #
  6. # Copyright 2013-2019 Michael Buesch <m@bues.ch>
  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 2 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 along
  19. # with this program; if not, write to the Free Software Foundation, Inc.,
  20. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21. #
  22. from __future__ import division, absolute_import, print_function, unicode_literals
  23. import sys
  24. import getopt
  25. from socket import AF_INET, AF_INET6
  26. from awlsim_loader.common import *
  27. from awlsim_loader.core import *
  28. from awlsim_loader.coreclient import *
  29. from awlsim_loader.coreserver import *
  30. import awlsim_loader.cython_helper as cython_helper
  31. def usage():
  32. print("awlsim-server version %s" % VERSION_STRING)
  33. print("")
  34. print("Usage: awlsim-server [OPTIONS] <project.awlpro>")
  35. print("")
  36. print("<project.awlpro> is an optional project file that will be loaded.")
  37. print("If -w is also given, all project changes are written back to that file.")
  38. print("")
  39. print("Options:")
  40. print(" -l|--listen HOST[:PORT] Listen on the specified HOST:PORT")
  41. print(" Defaults to %s:%d" %\
  42. (AwlSimServer.DEFAULT_HOST, AwlSimServer.DEFAULT_PORT))
  43. print(" The special values 'all', 'any' or an empty host")
  44. print(" can be used to listen on any interface.")
  45. print(" -4|--force-ipv4 Force the use of IPv4.")
  46. print(" -6|--force-ipv6 Force the use of IPv6.")
  47. print(" -B|--background Fork a background process")
  48. print(" -w|--rw-project Enable project file writing")
  49. print(" -S|--allow-shutdown Allow remote system shutdown")
  50. print(" -L|--loglevel LVL Set the log level:")
  51. print(" 0: Log nothing")
  52. print(" 1: Log errors")
  53. print(" 2: Log errors and warnings")
  54. print(" 3: Log errors, warnings and info messages (default)")
  55. print(" 4: Verbose logging")
  56. print(" 5: Extremely verbose logging")
  57. def main():
  58. global opt_listen
  59. global opt_background
  60. opt_project = None
  61. opt_rwProject = False
  62. opt_listen = (AwlSimServer.DEFAULT_HOST, AwlSimServer.DEFAULT_PORT)
  63. opt_family = None
  64. opt_background = False
  65. opt_allowShutdown = False
  66. opt_loglevel = Logging.LOG_INFO
  67. try:
  68. (opts, args) = getopt.getopt(sys.argv[1:],
  69. "hl:46BwSL:",
  70. [ "help", "listen=", "force-ipv4", "force-ipv6",
  71. "background", "rw-project", "allow-shutdown",
  72. "loglevel=", ])
  73. except getopt.GetoptError as e:
  74. printError(str(e))
  75. usage()
  76. return ExitCodes.EXIT_ERR_CMDLINE
  77. for (o, v) in opts:
  78. if o in ("-h", "--help"):
  79. usage()
  80. return ExitCodes.EXIT_OK
  81. if o in ("-l", "--listen"):
  82. try:
  83. host, port = parseNetAddress(v)
  84. if not host.strip() or\
  85. host in {"any", "all"}:
  86. host = ""
  87. if port is None:
  88. port = AwlSimServer.DEFAULT_PORT
  89. opt_listen = (host, port)
  90. except AwlSimError as e:
  91. printError("-l|--listen: %s" % e.message)
  92. sys.exit(1)
  93. if o in ("-4", "--force-ipv4"):
  94. opt_family = AF_INET
  95. if o in ("-6", "--force-ipv6"):
  96. opt_family = AF_INET6
  97. if o in ("-B", "--background"):
  98. opt_background = True
  99. if o in ("-w", "--rw-project"):
  100. opt_rwProject = True
  101. if o in ("-S", "--allow-shutdown"):
  102. opt_allowShutdown = True
  103. if o in ("-L", "--loglevel"):
  104. try:
  105. opt_loglevel = int(v)
  106. except ValueError:
  107. printError("-L|--loglevel: Invalid log level")
  108. sys.exit(1)
  109. if len(args) not in (0, 1):
  110. usage()
  111. return ExitCodes.EXIT_ERR_CMDLINE
  112. if args:
  113. opt_project = args[0]
  114. exitCode = ExitCodes.EXIT_OK
  115. try:
  116. Logging.setLoglevel(opt_loglevel)
  117. commandMask = 0
  118. if opt_allowShutdown:
  119. commandMask |= AwlSimServer.CMDMSK_SHUTDOWN
  120. if opt_background:
  121. interpreter = sys.executable
  122. assert(interpreter)
  123. serverProcess = AwlSimServer.start(listenHost=opt_listen[0],
  124. listenPort=opt_listen[1],
  125. listenFamily=opt_family,
  126. forkInterpreter=interpreter,
  127. commandMask=commandMask,
  128. projectFile=opt_project,
  129. projectWriteBack=opt_rwProject)
  130. printInfo("Started awlsim server process (PID: %d)" %\
  131. serverProcess.pid)
  132. else:
  133. if cython_helper.shouldUseCython():
  134. printInfo("*** Using accelerated CYTHON core "
  135. "(AWLSIM_CYTHON environment variable is set)")
  136. exitCode = AwlSimServer.start(listenHost=opt_listen[0],
  137. listenPort=opt_listen[1],
  138. listenFamily=opt_family,
  139. forkInterpreter=None,
  140. commandMask=commandMask,
  141. projectFile=opt_project,
  142. projectWriteBack=opt_rwProject)
  143. except AwlSimError as e:
  144. printError(e.getReport())
  145. return ExitCodes.EXIT_ERR_SIM
  146. return exitCode
  147. if __name__ == "__main__":
  148. sys.exit(main())