3 * This class contains static helper functions for console applications
5 * @author Roland Haeder <webmaster@ship-simu.org>
7 * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2011 Core Developer Team
8 * @license GNU GPL 3.0 or any newer version
9 * @link http://www.ship-simu.org
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 class ConsoleTools extends BaseFrameworkSystem {
26 const HTTP_EOL = "\r\n";
27 const HTTP_USER_AGENT = 'ConsoleTools/1.0';
30 * Protected constructor
34 protected function __construct () {
35 // Call parent constructor
36 parent::__construct(__CLASS__);
40 * Tries to resolve an IP address from given hostname. Currently only IPv
41 * addresses are resolved.
43 * @param $hostname Host name we shall resolve
44 * @return $ip IP address resolved from host name
45 * @todo We should connect this to a caching class to cache DNS requests
47 protected function resolveIpAddress ($hostname) {
49 $this->debugOutput(sprintf("[%s:] Our host name is: <span class=\"data\">%s</span>",
54 // Default is an invalid one
58 // @TODO Here should the cacher be implemented
59 $ipResolved = gethostbyname($hostname);
62 if (($ipResolved !== false) && ($ipResolved != $hostname)) {
67 $this->debugOutput(sprintf("[%s:] Resolved IP address is: <span class=\"data\">%s</span>\n",
72 // Problem while resolving IP address
73 $this->debugOutput(sprintf("[%s:] Problem resolving IP address for host <span class=\"data\">%s</span>. Please check your /etc/hosts file.",
84 * Aquires the IP address of this host by reading the /etc/hostname file
85 * and solving it. It is now stored in configuration
89 public static function acquireSelfIPAddress () {
90 // Local IP by default
94 $helperInstance = new ConsoleTools();
98 $io = FrameworkFileInputPointer::createFrameworkFileInputPointer('/etc/hostname');
101 $hostname = trim($io->readFromFile());
106 // Resolve the IP number
107 $ip = $helperInstance->resolveIpAddress($hostname);
108 } catch (FileIoException $e) {
109 // Fall-back to 'SESSION_SVR' which found on my Sun Station
110 if (isset($_SERVER['SESSION_SVR'])) {
112 $ip = $helperInstance->resolveIpAddress($_SERVER['SESSION_SVR']);
113 } elseif (isset($_SERVER['COMPUTERNAME'])) {
114 // May happen on some XP systems, so also try this
115 $ip = $helperInstance->resolveIpAddress($_SERVER['COMPUTERNAME']);
117 // Could not find our hostname
118 $helperInstance->debugOutput(sprintf("[%s:] WARNING: Cannot resolve my own IP address.",
119 $helperInstance->__toString()
122 } catch (FrameworkException $e) {
123 // Output debug message
124 $helperInstance->debugOutput(sprintf("[%s:] Problem while resolving own IP address: [%s|%s]:%s",
125 $helperInstance->__toString(),
132 // Set it in configuration
133 FrameworkConfiguration::getSelfInstance()->setServerAddress($ip);
137 * Determines own remote IP address (e.g. can be used to probe if we are
138 * reachable from outside by determining external IP and then connect to it.
139 * This is accomblished by connecting to the IP of www.ship-simu.org which
140 * should default to 188.138.90.169 and requesting /ip.php which does only
141 * return the content of $_SERVER['REMOTE_ADDR']. Of course, this method
142 * requires a working Internet connection.
144 * This method is taken from a user comment on php.net and heavily rewritten.
145 * Compare to following link:
146 * http://de.php.net/manual/en/function.socket-create.php#49368
148 * @return $externalAddress The determined external IP address
149 * @throws InvalidSocketException If socket initialization wents wrong or if an errors occurs
150 * @todo This should be moved out to an external class, e.g. HttpClient
151 * @todo Make IP, host name, port and script name configurable
153 public static function determineExternalIp () {
154 // Get helper instance
155 $helperInstance = new ConsoleTools();
157 // First get a socket
158 // @TODO Add some DNS caching here
159 $socketResource = fsockopen('188.138.90.169', 80, $errorNo, $errorStr, 5);
161 // Check if there was an error else
164 throw new InvalidSocketException(array($helperInstance, $socketResource, $errorNo, $errorStr), BaseListener::EXCEPTION_INVALID_SOCKET);
167 // Prepare the GET request
168 $request = 'GET /ip.php HTTP/1.0' . self::HTTP_EOL;
169 $request .= 'Host: ship-simu.org' . self::HTTP_EOL;
170 $request .= 'User-Agent: ' . self::HTTP_USER_AGENT . self::HTTP_EOL;
171 $request .= 'Connection: close' . self::HTTP_EOL;
172 $request .= self::HTTP_EOL;
174 // Send it to the socket
175 fwrite($socketResource, $request);
177 // Init IP (this will always be the last line)
178 $externalAddress = 'invalid';
180 // And read the reply
181 while (!feof($socketResource)) {
182 $externalAddress = fgets($socketResource, 128);
186 fclose($socketResource);
188 // Return determined external IP
189 return $externalAddress;
193 * Analyzes the 'environment', mostly $_SERVER, for presence of elements
194 * which indicates clearly that e.g. this script has been executed from
197 * @return $type The analyzed type, can be 'http' or 'console'
199 public static function analyzeEnvironmentForType () {
200 // Default is the console
203 // Now, do we have a request method, or query string set?
204 if ((isset($_SERVER['REQUEST_METHOD'])) || (isset($_SERVER['QUERY_STRING']))) {
205 // Possibly HTTP request
214 * Analyzes the 'environment', mostly $_SERVER, for presence of elements
215 * which indicates clearly that e.g. this script has been executed from
216 * console or web. This method should be used for class names, they
217 * currently are named differently. Here is a list to clarify this:
219 * Request type | Class type
220 * -----------------------------
224 * @return $type The analyzed type, can be 'http' or 'console'
226 public static function analyzeEnvironmentForClassType () {
227 // Default is the console
230 // Now, do we have a request method, or query string set?
231 if ((isset($_SERVER['REQUEST_METHOD'])) || (isset($_SERVER['QUERY_STRING']))) {
232 // Possibly HTTP request