summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortruelight <truelight@openttd.org>2007-02-08 12:27:53 +0000
committertruelight <truelight@openttd.org>2007-02-08 12:27:53 +0000
commitbc5d3ef3b0a2cb0d412807bd43fa1a6ec3f0c322 (patch)
tree18108e9e6f3d116f39e99f84eb6540da848e01cf
parent7f589f502900f7a93d379c400b5130301ed96594 (diff)
downloadopenttd-bc5d3ef3b0a2cb0d412807bd43fa1a6ec3f0c322.tar.xz
(svn r8631) -Add: added parameter -l ip[:port] to ./openttd, which redirects DEBUG() to a remote connection over TCP
For example, launch on 192.168.0.1 with, say, netcat a listener: netcat -l -p 3982 Launch OpenTTD on a remote host (say, PSP): ./openttd -l 192.168.0.1 -d9 And you get all debug information on 192.168.0.1. Very useful for debugging Portable systems.
-rw-r--r--src/debug.cpp19
-rw-r--r--src/network/core/config.h1
-rw-r--r--src/network/network.cpp31
-rw-r--r--src/network/network.h1
-rw-r--r--src/openttd.cpp22
5 files changed, 71 insertions, 3 deletions
diff --git a/src/debug.cpp b/src/debug.cpp
index 4040c9cea..d21580665 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -8,6 +8,11 @@
#include "debug.h"
#include "functions.h"
#include "string.h"
+#include "network/core/core.h"
+
+#if defined(ENABLE_NETWORK)
+SOCKET _debug_socket = INVALID_SOCKET;
+#endif /* ENABLE_NETWORK */
int _debug_ai_level;
int _debug_driver_level;
@@ -78,8 +83,18 @@ void CDECL debug(const char *dbg, ...)
s = va_arg(va, const char*);
vsnprintf(buf, lengthof(buf), s, va);
va_end(va);
- fprintf(stderr, "dbg: [%s] %s\n", dbg, buf);
- IConsoleDebug(dbg, buf);
+#if defined(ENABLE_NETWORK)
+ if (_debug_socket != INVALID_SOCKET) {
+ char buf2[lengthof(buf) + 32];
+
+ snprintf(buf2, lengthof(buf2), "dbg: [%s] %s\n", dbg, buf);
+ send(_debug_socket, buf2, strlen(buf2), 0);
+ } else
+#endif /* ENABLE_NETWORK */
+ {
+ fprintf(stderr, "dbg: [%s] %s\n", dbg, buf);
+ IConsoleDebug(dbg, buf);
+ }
}
}
#endif /* NO_DEBUG_MESSAGES */
diff --git a/src/network/core/config.h b/src/network/core/config.h
index 63b54f7ce..93145e426 100644
--- a/src/network/core/config.h
+++ b/src/network/core/config.h
@@ -17,6 +17,7 @@
enum {
NETWORK_MASTER_SERVER_PORT = 3978, ///< The default port of the master server (UDP)
NETWORK_DEFAULT_PORT = 3979, ///< The default port of the game server (TCP & UDP)
+ NETWORK_DEFAULT_DEBUGLOG_PORT = 3982, ///< The default port debug-log is sent too (TCP)
SEND_MTU = 1460, ///< Number of bytes we can pack in a single packet
diff --git a/src/network/network.cpp b/src/network/network.cpp
index 76a29f3af..1ea36b50e 100644
--- a/src/network/network.cpp
+++ b/src/network/network.cpp
@@ -1317,6 +1317,37 @@ static void NetworkGenerateUniqueId(void)
snprintf(_network_unique_id, sizeof(_network_unique_id), "%s", hex_output);
}
+void NetworkStartDebugLog(const char *hostname, uint16 port)
+{
+ extern SOCKET _debug_socket; // Comes from debug.c
+ SOCKET s;
+ struct sockaddr_in sin;
+
+ DEBUG(net, 0, "Redirecting DEBUG() to %s:%d", hostname, port);
+
+ s = socket(AF_INET, SOCK_STREAM, 0);
+ if (s == INVALID_SOCKET) {
+ DEBUG(net, 0, "Failed to open socket for redirection DEBUG()");
+ return;
+ }
+
+ if (!SetNoDelay(s)) DEBUG(net, 1, "Setting TCP_NODELAY failed");
+
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = NetworkResolveHost(hostname);
+ sin.sin_port = htons(port);
+
+ if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) != 0) {
+ DEBUG(net, 0, "Failed to redirection DEBUG() to %s:%d", hostname, port);
+ return;
+ }
+
+ if (!SetNonBlocking(s)) DEBUG(net, 0, "Setting non-blocking mode failed");
+ _debug_socket = s;
+
+ DEBUG(net, 0, "DEBUG() is now redirected");
+}
+
/** This tries to launch the network for a given OS */
void NetworkStartUp(void)
{
diff --git a/src/network/network.h b/src/network/network.h
index 3f4182a92..d5306af30 100644
--- a/src/network/network.h
+++ b/src/network/network.h
@@ -166,6 +166,7 @@ bool NetworkChangeCompanyPassword(byte argc, char *argv[]);
void NetworkPopulateCompanyInfo(void);
void UpdateNetworkGameWindow(bool unselect);
void CheckMinPlayers(void);
+void NetworkStartDebugLog(const char *hostname, uint16 port);
void NetworkStartUp(void);
void NetworkUDPCloseAll();
diff --git a/src/openttd.cpp b/src/openttd.cpp
index d60a63643..b147b994d 100644
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -159,6 +159,7 @@ static void showhelp(void)
#if defined(ENABLE_NETWORK)
" -n [ip:port#player] = Start networkgame\n"
" -D [ip][:port] = Start dedicated server\n"
+ " -l ip[:port] = Redirect DEBUG()\n"
#if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(WIN32)
" -f = Fork into the background (dedicated only)\n"
#endif
@@ -344,6 +345,7 @@ int ttd_main(int argc, char *argv[])
bool dedicated = false;
bool network = false;
char *network_conn = NULL;
+ char *debuglog_conn = NULL;
char *dedicated_host = NULL;
uint16 dedicated_port = 0;
#endif /* ENABLE_NETWORK */
@@ -360,7 +362,7 @@ int ttd_main(int argc, char *argv[])
// a letter means: it accepts that param (e.g.: -h)
// a ':' behind it means: it need a param (e.g.: -m<driver>)
// a '::' behind it means: it can optional have a param (e.g.: -d<debug>)
- optformat = "m:s:v:hD::n::eit:d::r:g::G:c:x"
+ optformat = "m:s:v:hD::n::eit:d::r:g::G:c:xl:"
#if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(WIN32)
"f"
#endif
@@ -394,6 +396,9 @@ int ttd_main(int argc, char *argv[])
network = true;
network_conn = mgo.opt; // optional IP parameter, NULL if unset
break;
+ case 'l':
+ debuglog_conn = mgo.opt;
+ break;
#endif /* ENABLE_NETWORK */
case 'r': ParseResolution(resolution, mgo.opt); break;
case 't': startyear = atoi(mgo.opt); break;
@@ -490,6 +495,21 @@ int ttd_main(int argc, char *argv[])
NetworkStartUp(); // initialize network-core
+#if defined(ENABLE_NETWORK)
+ if (debuglog_conn != NULL && _network_available) {
+ const char *not_used = NULL;
+ const char *port = NULL;
+ uint16 rport;
+
+ rport = NETWORK_DEFAULT_DEBUGLOG_PORT;
+
+ ParseConnectionString(&not_used, &port, debuglog_conn);
+ if (port != NULL) rport = atoi(port);
+
+ NetworkStartDebugLog(debuglog_conn, rport);
+ }
+#endif /* ENABLE_NETWORK */
+
ScanNewGRFFiles();
_opt_ptr = &_opt_newgame;