JLANServerService.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. /*
  2. * Copyright (C) 2006-2010 Alfresco Software Limited.
  3. *
  4. * This file is part of Alfresco
  5. *
  6. * Alfresco is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Alfresco is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package org.alfresco.jlan.app;
  20. import java.io.File;
  21. import java.io.PrintStream;
  22. import java.lang.reflect.Constructor;
  23. import java.net.InetAddress;
  24. import java.net.UnknownHostException;
  25. import org.alfresco.jlan.debug.Debug;
  26. import org.alfresco.jlan.debug.DebugConfigSection;
  27. import org.alfresco.jlan.ftp.FTPConfigSection;
  28. import org.alfresco.jlan.netbios.server.NetBIOSNameServer;
  29. import org.alfresco.jlan.netbios.win32.Win32NetBIOS;
  30. import org.alfresco.jlan.oncrpc.nfs.NFSConfigSection;
  31. import org.alfresco.jlan.server.NetworkServer;
  32. import org.alfresco.jlan.server.config.ServerConfiguration;
  33. import org.alfresco.jlan.smb.server.CIFSConfigSection;
  34. import org.alfresco.jlan.smb.server.SMBServer;
  35. import org.tanukisoftware.wrapper.WrapperListener;
  36. import org.tanukisoftware.wrapper.WrapperManager;
  37. /**
  38. * JLAN Server Service Class
  39. *
  40. * @author gkspencer
  41. */
  42. public class JLANServerService implements WrapperListener, Runnable {
  43. // Default configuration file name
  44. private static final String DEFAULT_CONFIGFILENAME = "jlanserver.xml";
  45. // Server shutdown flag
  46. private boolean m_shutdown;
  47. // Server configuration
  48. private ServerConfiguration m_config;
  49. // Thread used to start the various servers
  50. private Thread m_serverThread;
  51. /**
  52. * Service start requested
  53. *
  54. * @param args String[]
  55. * @return Integer
  56. */
  57. public Integer start(String[] args) {
  58. // Command line parameter should specify the configuration file
  59. PrintStream out = System.out;
  60. String fileName = null;
  61. if (args.length < 1) {
  62. // Search for a default configuration file in the users home directory
  63. fileName = System.getProperty("user.home") + File.separator + DEFAULT_CONFIGFILENAME;
  64. }
  65. else
  66. fileName = args[0];
  67. // Load the configuration
  68. m_config = null;
  69. try {
  70. // Create an XML configuration
  71. m_config = new XMLServerConfiguration();
  72. m_config.loadConfiguration(fileName);
  73. }
  74. catch (Exception ex) {
  75. // Failed to load server configuration
  76. out.println("%% Failed to load server configuration");
  77. ex.printStackTrace(out);
  78. return new Integer(2);
  79. }
  80. // Check if the local IP address returns a valid value, '127.0.0.1' indicates a mis-configuration in the hosts file
  81. try {
  82. // Get the local address
  83. String localAddr = InetAddress.getLocalHost().getHostAddress();
  84. if ( localAddr.equals("127.0.0.1")) {
  85. out.println("%% Local IP address resolves to 127.0.0.1, this may be caused by a mis-configured hosts file");
  86. return new Integer(3);
  87. }
  88. }
  89. catch (UnknownHostException ex) {
  90. // Failed to get local host IP address details
  91. out.println("%% Failed to get local IP address details");
  92. ex.printStackTrace(out);
  93. return new Integer(4);
  94. }
  95. // NetBIOS name server, SMB, FTP and NFS servers
  96. try {
  97. // Create the SMB server and NetBIOS name server, if enabled
  98. if ( m_config.hasConfigSection( CIFSConfigSection.SectionName)) {
  99. // Get the CIFS server configuration
  100. CIFSConfigSection cifsConfig = (CIFSConfigSection) m_config.getConfigSection( CIFSConfigSection.SectionName);
  101. // Load the Win32 NetBIOS library
  102. //
  103. // For some strange reason the native code loadLibrary() call hangs if done later by the SMBServer.
  104. // Forcing the Win32NetBIOS class to load here and run the static initializer fixes the problem.
  105. if ( cifsConfig.hasWin32NetBIOS())
  106. Win32NetBIOS.LanaEnumerate();
  107. // Create the NetBIOS name server if NetBIOS SMB is enabled
  108. if (cifsConfig.hasNetBIOSSMB())
  109. m_config.addServer( createNetBIOSServer(m_config));
  110. // Create the SMB server
  111. m_config.addServer( createSMBServer(m_config));
  112. }
  113. // Create the FTP server, if enabled
  114. if ( m_config.hasConfigSection( FTPConfigSection.SectionName)) {
  115. // Create the FTP server
  116. m_config.addServer( createFTPServer( m_config));
  117. }
  118. // Create the NFS server and mount server, if enabled
  119. if ( m_config.hasConfigSection( NFSConfigSection.SectionName)) {
  120. // Get the NFS server configuration
  121. NFSConfigSection nfsConfig = (NFSConfigSection) m_config.getConfigSection( NFSConfigSection.SectionName);
  122. // Check if the port mapper is enabled
  123. if ( nfsConfig.hasNFSPortMapper())
  124. m_config.addServer( createNFSPortMapper( m_config));
  125. // Create the mount server
  126. m_config.addServer( createNFSMountServer( m_config));
  127. // Create the NFS server
  128. m_config.addServer( createNFSServer( m_config));
  129. }
  130. // Start the configured servers in a seperate thread
  131. m_serverThread = new Thread(this);
  132. m_serverThread.start();
  133. }
  134. catch (Exception ex) {
  135. out.println("%% Server error");
  136. ex.printStackTrace(out);
  137. return new Integer(5);
  138. }
  139. // Indicate that the service started
  140. return null;
  141. }
  142. /**
  143. * Service stop requested
  144. *
  145. * @param exitCode int
  146. * @return int
  147. */
  148. public int stop(int exitCode) {
  149. // Set the shutdown flag
  150. m_shutdown = true;
  151. // Get the debug configuration
  152. DebugConfigSection dbgConfig = (DebugConfigSection) m_config.getConfigSection( DebugConfigSection.SectionName);
  153. // Check if the server list is valid
  154. if ( m_config.numberOfServers() > 0) {
  155. // Shutdown the servers
  156. for ( int i = 0; i < m_config.numberOfServers(); i++) {
  157. // Indicate that the service is stopping
  158. WrapperManager.signalStopping(5000);
  159. // Get the current server
  160. NetworkServer server = m_config.getServer(i);
  161. // DEBUG
  162. if ( Debug.EnableInfo && dbgConfig != null && dbgConfig.hasDebug())
  163. Debug.println("Shutting server " + server.getProtocolName() + " ...");
  164. // Start the server
  165. m_config.getServer(i).shutdownServer(false);
  166. }
  167. }
  168. // Indicate that the service is stopped
  169. WrapperManager.signalStopped(5000);
  170. // Return the status code
  171. return exitCode;
  172. }
  173. /**
  174. * Handle control events
  175. *
  176. * @param event int
  177. */
  178. public void controlEvent(int event) {
  179. // Check if the wrapper manager is handling events
  180. if ( WrapperManager.isControlledByNativeWrapper() == false) {
  181. // The wrapper manager is not handling events, handle it here
  182. if ( event == WrapperManager.WRAPPER_CTRL_C_EVENT ||
  183. event == WrapperManager.WRAPPER_CTRL_CLOSE_EVENT ||
  184. event == WrapperManager.WRAPPER_CTRL_SHUTDOWN_EVENT) {
  185. // Stop the service
  186. WrapperManager.stop(0);
  187. }
  188. }
  189. }
  190. /**
  191. * Main application startup
  192. *
  193. * @param args String[]
  194. */
  195. public static void main(String[] args) {
  196. // Start the main JLAN Server application via the service wrapper
  197. WrapperManager.start( new JLANServerService(), args);
  198. }
  199. /**
  200. * Create the SMB server
  201. *
  202. * @param config ServerConfiguration
  203. * @return NetworkServer
  204. * @exception Exception
  205. */
  206. protected final static NetworkServer createSMBServer(ServerConfiguration config)
  207. throws Exception {
  208. // Create an SMB server
  209. return new SMBServer(config);
  210. }
  211. /**
  212. * Create the NetBIOS name server
  213. *
  214. * @param config ServerConfiguration
  215. * @return NetworkServer
  216. * @exception Exception
  217. */
  218. protected final static NetworkServer createNetBIOSServer(ServerConfiguration config)
  219. throws Exception {
  220. // Create a NetBIOS name server
  221. return new NetBIOSNameServer(config);
  222. }
  223. /**
  224. * Create the FTP server
  225. *
  226. * @param config ServerConfiguration
  227. * @return NetworkServer
  228. * @exception Exception
  229. */
  230. protected final static NetworkServer createFTPServer(ServerConfiguration config)
  231. throws Exception {
  232. // Create an FTP server
  233. return createServer( "org.alfresco.jlan.ftp.FTPServer", config);
  234. }
  235. /**
  236. * Create the NFS server
  237. *
  238. * @param config ServerConfiguration
  239. * @return NetworkServer
  240. * @exception Exception
  241. */
  242. protected final static NetworkServer createNFSServer(ServerConfiguration config)
  243. throws Exception {
  244. // Create the NFS server instance
  245. return createServer( "org.alfresco.jlan.oncrpc.nfs.NFSServer", config);
  246. }
  247. /**
  248. * Create the NFS mount server
  249. *
  250. * @param config ServerConfiguration
  251. * @return NetworkServer
  252. * @exception Exception
  253. */
  254. protected final static NetworkServer createNFSMountServer(ServerConfiguration config)
  255. throws Exception {
  256. // Create the mount server instance
  257. return createServer( "org.alfresco.jlan.oncrpc.mount.MountServer", config);
  258. }
  259. /**
  260. * Create the NFS port mapper server
  261. *
  262. * @param config ServerConfiguration
  263. * @return NetworkServer
  264. */
  265. protected final static NetworkServer createNFSPortMapper(ServerConfiguration config)
  266. throws Exception {
  267. // Create the port mapper server instance
  268. return createServer( "org.alfresco.jlan.oncprc.portmap.PortMapperServer", config);
  269. }
  270. /**
  271. * Create a network server using reflection
  272. *
  273. * @param className String
  274. * @param config ServerConfiguration
  275. * @return NetworkServer
  276. * @exception Exception
  277. */
  278. protected final static NetworkServer createServer(String className, ServerConfiguration config)
  279. throws Exception {
  280. // Create the server instance using reflection
  281. NetworkServer srv = null;
  282. // Find the server constructor
  283. Class<?>[] classes = new Class[1];
  284. classes[0] = ServerConfiguration.class;
  285. Constructor<?> srvConstructor = Class.forName(className).getConstructor(classes);
  286. // Create the network server
  287. Object[] args = new Object[1];
  288. args[0] = config;
  289. srv = (NetworkServer) srvConstructor.newInstance(args);
  290. // Return the network server instance
  291. return srv;
  292. }
  293. /**
  294. * Thread method
  295. */
  296. public void run() {
  297. // Check if there are any servers configured
  298. if ( m_config.numberOfServers() > 0) {
  299. // Clear the shutdown flag
  300. m_shutdown = false;
  301. // Get the debug configuration
  302. DebugConfigSection dbgConfig = (DebugConfigSection) m_config.getConfigSection( DebugConfigSection.SectionName);
  303. // Start the servers
  304. for ( int i = 0; i < m_config.numberOfServers(); i++) {
  305. // Indicate that the servers are starting
  306. WrapperManager.signalStarting(10000);
  307. // Get the current server
  308. NetworkServer server = m_config.getServer(i);
  309. // DEBUG
  310. if ( Debug.EnableInfo && dbgConfig != null && dbgConfig.hasDebug())
  311. Debug.println("Starting server " + server.getProtocolName() + " ...");
  312. // Start the server
  313. m_config.getServer(i).startServer();
  314. }
  315. // Wait for shutdown request
  316. while ( m_shutdown == false) {
  317. try {
  318. Thread.sleep(250);
  319. }
  320. catch (Exception ex) {
  321. }
  322. }
  323. }
  324. }
  325. }