]> git.mxchange.org Git - flightgear.git/commitdiff
Bernie Bright:
authorcurt <curt>
Fri, 2 Aug 2002 22:49:34 +0000 (22:49 +0000)
committercurt <curt>
Fri, 2 Aug 2002 22:49:34 +0000 (22:49 +0000)
I've merged FGProps and FGTelnet so there is just a single property server.
I've left in the --telnet=port# command line option but it could be removed
if we wanted to.  The command line accepts two forms of the --props option.
The original (--props=medium,dir,hz,host,port#,style) and the shorter
--props=port#.  If you accept this change then src/Network/telnet.[ch]xx
can be removed from the cvs repository.

src/Main/fg_io.cxx
src/Network/Makefile.am
src/Network/atc610x.cxx
src/Network/props.cxx
src/Network/props.hxx
src/Network/telnet.cxx [deleted file]
src/Network/telnet.hxx [deleted file]

index e6352f0c581638e6f4c4395df7f885e629d10f15..db276d884c73ddf93874ae51dccda10ff22cedc6 100644 (file)
 #include <Network/opengc.hxx>
 #include <Network/nmea.hxx>
 #include <Network/props.hxx>
-#include <Network/telnet.hxx>
 #include <Network/pve.hxx>
 #include <Network/ray.hxx>
 #include <Network/rul.hxx>
 
 #include "globals.hxx"
+#include "fg_io.hxx"
 
-SG_USING_NAMESPACE(std);
 SG_USING_STD(string);
 
 
@@ -125,10 +124,8 @@ static FGProtocol *parse_port_config( const string& config )
        } else if ( protocol == "nmea" ) {
            FGNMEA *nmea = new FGNMEA;
            io = nmea;
-       } else if ( protocol == "props" ) {
-           io = new FGProps();
-       } else if ( protocol == "telnet" ) {
-           io = new FGTelnet( tokens );
+       } else if ( protocol == "props" || protocol == "telnet" ) {
+           io = new FGProps( tokens );
            return io;
        } else if ( protocol == "pve" ) {
            FGPVE *pve = new FGPVE;
index de3c00fde4ba4297ae4d6aa4973efc3ab4dc9c41..7766c0977e1b7f4799f1d64d07ec7f34749504f2 100644 (file)
@@ -24,8 +24,7 @@ libNetwork_a_SOURCES = \
        pve.cxx pve.hxx \
        raw_ctrls.hxx \
        ray.cxx ray.hxx \
-       rul.cxx rul.hxx \
-       telnet.cxx telnet.hxx
+       rul.cxx rul.hxx
 
 if OLD_AUTOMAKE
 INCLUDES += -I$(top_srcdir) -I$(top_srcdir)/src
index ba6064157245023b08da97e004373dd60f697e56..fef95670fe4ca8cde3dbce1e2f43498e5a515468 100644 (file)
@@ -1402,8 +1402,8 @@ bool FGATC610x::do_switches() {
     fuel2 = fuel1;
     fuel1 = fuel;
     if ( fuel1 == fuel2 && fuel2 == fuel3 ) {
-        fgSetBool( "/controls/fuel-selector[0]", fuel & 0x01 );
-        fgSetBool( "/controls/fuel-selector[1]", fuel & 0x02 );
+        fgSetBool( "/controls/fuel-selector[0]", (fuel & 0x01) > 0 );
+        fgSetBool( "/controls/fuel-selector[1]", (fuel & 0x02) > 0 );
     }
 
     return true;
index 3692a5cfe6ec49fed2c8197df9d5c780b1b61c99..8752da41b927eb48ec5d9c2cd96ec6813d22443f 100644 (file)
@@ -1,6 +1,8 @@
-// props.hxx -- FGFS property manager interaction class
+// \file props.cxx
+// Property server class.
 //
 // Written by Curtis Olson, started September 2000.
+// Modified by Bernie Bright, May 2002.
 //
 // Copyright (C) 2000  Curtis L. Olson - curt@flightgear.org
 //
 // $Id$
 
 
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
 
 #include <simgear/compiler.h>
 #include <simgear/debug/logstream.hxx>
-#include <simgear/io/iochannel.hxx>
-#include <simgear/math/sg_types.hxx>
+#include <simgear/misc/strutils.hxx>
 #include <simgear/misc/props.hxx>
 #include <simgear/misc/props_io.hxx>
 
-#include <Main/globals.hxx>
+#include STL_STRSTREAM
 
-#include <stdlib.h>            // atoi() atof()
+#include <Main/globals.hxx>
+#include <Main/viewmgr.hxx>
 
-#include STL_STRSTREAM
+#include <plib/netChat.h>
 
 #include "props.hxx"
 
 #if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
-SG_USING_STD(cout);
-SG_USING_STD(istrstream);
 SG_USING_STD(strstream);
+SG_USING_STD(ends);
 #endif
 
-FGProps::FGProps() {
-}
-
-FGProps::~FGProps() {
+/**
+ * Props connection class.
+ * This class represents a connection to props client.
+ */
+class PropsChannel : public netChat
+{
+    netBuffer buffer;
+
+    /**
+     * Current property node name.
+     */
+    string path;
+
+    enum Mode {
+       PROMPT,
+       DATA
+    };
+    Mode mode;
+
+public:
+    /**
+     * Constructor.
+     */
+    PropsChannel();
+    
+    /**
+     * Append incoming data to our request buffer.
+     *
+     * @param s Character string to append to buffer
+     * @param n Number of characters to append.
+     */
+    void collectIncomingData( const char* s, int n );
+
+    /**
+     * Process a complete request from the props client.
+     */
+    void foundTerminator();
+
+private:
+    /**
+     * Return a "Node no found" error message to the client.
+     */
+    void node_not_found_error( const string& node_name );
+};
+
+/**
+ * 
+ */
+PropsChannel::PropsChannel()
+    : buffer(512),
+      path("/"),
+      mode(PROMPT)
+{
+    setTerminator( "\r\n" );
 }
 
-
-// open hailing frequencies
-bool FGProps::open() {
-    reset();
-
-    if ( is_enabled() ) {
-       SG_LOG( SG_IO, SG_ALERT, "This shouldn't happen, but the channel " 
-               << "is already in use, ignoring" );
-       return false;
-    }
-
-    SGIOChannel *io = get_io_channel();
-
-    if ( ! io->open( get_direction() ) ) {
-       SG_LOG( SG_IO, SG_ALERT, "Error opening channel communication layer." );
-       return false;
-    }
-
-    set_enabled( true );
-    SG_LOG( SG_IO, SG_INFO, "Opening properties channel communication layer." );
-
-    return true;
+/**
+ * 
+ */
+void
+PropsChannel::collectIncomingData( const char* s, int n )
+{
+    buffer.append( s, n );
 }
 
-
-// prepare for new connection
-bool FGProps::reset() {
-    path = "/";
-    mode = PROMPT;
-    return true;
+/**
+ * 
+ */
+void
+PropsChannel::node_not_found_error( const string& node_name )
+{
+    string error = "ERR Node \"";
+    error += node_name;
+    error += "\" not found.";
+    push( error.c_str() );
+    push( getTerminator() );
 }
 
-
 // return a human readable form of the value "type"
-static string getValueTypeString( const SGPropertyNode *node ) {
+static string
+getValueTypeString( const SGPropertyNode *node )
+{
     string result;
 
-    if ( node == NULL ) {
+    if ( node == NULL )
+    {
        return "unknown";
     }
 
@@ -112,207 +158,308 @@ static string getValueTypeString( const SGPropertyNode *node ) {
     return result;
 }
 
+/**
+ * We have a command.
+ * 
+ */
+void
+PropsChannel::foundTerminator()
+{
+    const char* cmd = buffer.getData();
+    SG_LOG( SG_IO, SG_INFO, "processing command = \"" << cmd << "\"" );
+
+    vector<string> tokens = simgear::strutils::split( cmd );
+
+    SGPropertyNode* node = globals->get_props()->getNode( path.c_str() );
+
+    if (!tokens.empty())
+    {
+       string command = tokens[0];
+
+       if (command == "ls")
+       {
+           SGPropertyNode* dir = node;
+           if (tokens.size() == 2)
+           {
+               if (tokens[1][0] == '/')
+               {
+                   dir = globals->get_props()->getNode( tokens[1].c_str() );
+               }
+               else
+               {
+                   string s = path;
+                   s += "/";
+                   s += tokens[1];
+                   dir = globals->get_props()->getNode( s.c_str() );
+               }
 
-bool FGProps::process_command( const char *cmd ) {
-    SGIOChannel *io = get_io_channel();
-
-    cout << "processing command = " << cmd;
-    string_list tokens;
-    tokens.clear();
-
-    istrstream in(cmd);
-    
-    while ( !in.eof() ) {
-       string token;
-       in >> token;
-       tokens.push_back( token );
-    }
+               if (dir == 0)
+               {
+                   node_not_found_error( tokens[1] );
+                   goto prompt;
+               }
+           }
 
-    string command = tokens[0];
+           for (int i = 0; i < dir->nChildren(); i++)
+           {
+               SGPropertyNode * child = dir->getChild(i);
+               string name = child->getName();
+               string line = name;
+
+               if (dir->getChild( name.c_str(), 1 ))
+               {
+                   char buf[16];
+                   sprintf(buf, "[%d]", child->getIndex());
+                   line += buf;
+               }
 
-    SGPropertyNode * node = globals->get_props()->getNode(path.c_str());
+               if ( child->nChildren() > 0 )
+               {
+                   line += "/";
+               }
+               else
+               {
+                   if (mode == PROMPT)
+                   {
+                       string value = dir->getStringValue( name.c_str(), "" );
+                       line += " =\t'" + value + "'\t(";
+                       line += getValueTypeString(
+                                       dir->getNode( name.c_str() ) );
+                       line += ")";
+                   }
+               }
 
-    if ( command == "ls" ) {
-       SGPropertyNode * dir = node;
-       if ( tokens.size() > 2 ) {
-           if ( tokens[1][0] == '/' ) {
-               dir = globals->get_props()->getNode(tokens[1].c_str());
-           } else {
-               dir = globals->get_props()->getNode((path + "/" + tokens[1]).c_str());
-           }
-           if ( dir == 0 ) {
-               tokens[1] = "ERR Node \"" + tokens[1] + "\" not found.\n";
-               io->writestring( tokens[1].c_str() );
-               return true;
+               line += getTerminator();
+               push( line.c_str() );
            }
        }
-       
-       for (int i = 0; i < (int)dir->nChildren(); i++) {
-           SGPropertyNode * child = dir->getChild(i);
-           string name = child->getName();
-           string line = name;
-           if ( dir->getChild(name.c_str(), 1) ) {
-               char buf[16];
-               sprintf(buf, "[%d]", child->getIndex());
-               line += buf;
+       else if ( command == "dump" )
+       {
+           strstream buf;
+           if ( tokens.size() <= 1 )
+           {
+               writeProperties( buf, node );
+               buf << ends; // null terminate the string
+               push( buf.str() );
+               push( getTerminator() );
            }
-           if ( child->nChildren() > 0 ) {
-               line += "/";
-           } else {
-               if ( mode == PROMPT ) {
-                   string value = dir->getStringValue ( name.c_str(), "" );
-                   line += " =\t'" + value + "'\t(";
-                   line += getValueTypeString( dir->getNode( name.c_str() ) );
-                   line += ")";
+           else
+           {
+               SGPropertyNode *child = node->getNode( tokens[1].c_str() );
+               if ( child )
+               {
+                   writeProperties ( buf, child );
+                   buf << ends; // null terminate the string
+                   push( buf.str() );
+                   push( getTerminator() );
+               }
+               else
+               {
+                   node_not_found_error( tokens[1] );
                }
            }
-           line += "\n";
-           io->writestring( line.c_str() );
        }
-    } else if ( command == "dump" ) {
-       strstream buf;
-       if ( tokens.size() <= 1 ) {
-           writeProperties ( buf, node);
-           io->writestring( buf.str() );
-       }
-       else {
-           SGPropertyNode *child = node->getNode(tokens[1].c_str());
-           if ( child ) {
-               writeProperties ( buf, child );
-               io->writestring( buf.str() );
-           } else {
-               tokens[1] = "ERR Node \"" + tokens[1] + "\" not found.\n";
-               io->writestring( tokens[1].c_str() );
+       else if ( command == "cd" )
+       {
+           if (tokens.size() == 2)
+           {
+               try
+               {
+                   SGPropertyNode* child = node->getNode( tokens[1].c_str() );
+                   if ( child )
+                   {
+                       node = child;
+                       path = node->getPath();
+                   }
+                   else
+                   {
+                       node_not_found_error( tokens[1] );
+                   }
+               }
+               catch (...)
+               {
+                   // Ignore attempt to move past root node with ".."
+               }
            }
        }
-    } else if ( command == "cd" ) {
-       // string tmp = "current path = " + node.getPath() + "\n";
-       // io->writestring( tmp.c_str() );
-
-        if ( tokens.size() <= 1 ) {
-           // do nothing
-       } else {
-           SGPropertyNode *child = node->getNode(tokens[1].c_str());
-           if ( child ) {
-               node = child;
-               path = node->getPath();
-           } else {
-               tokens[1] = "ERR Node \"" + tokens[1] + "\" not found.\n";
-               io->writestring( tokens[1].c_str() );
+       else if ( command == "pwd" )
+       {
+           string ttt = node->getPath();
+           if (ttt.empty())
+           {
+               ttt = "/";
            }
+
+           push( ttt.c_str() );
+           push( getTerminator() );
        }
-    } else if ( command == "pwd" ) {
-       string ttt = node->getPath();
-       if ( ttt.empty() ) {
-           ttt = "/";
-       }
-       ttt += "\n";
-       io->writestring( ttt.c_str() );
-    } else if ( command == "get" || command == "show" ) {
-       if ( tokens.size() <= 1 ) {
-           // do nothing
-       } else {
-           string tmp; 
-           string value = node->getStringValue ( tokens[1].c_str(), "" );
-           if ( mode == PROMPT ) {
-               tmp = tokens[1] + " = '" + value + "' (";
-               tmp += getValueTypeString( node->getNode( tokens[1].c_str() ) );
-               tmp += ")\n";
-           } else {
-               tmp = value + "\n";
+       else if ( command == "get" || command == "show" )
+       {
+           if ( tokens.size() == 2 )
+           {
+               string tmp;     
+               string value = node->getStringValue ( tokens[1].c_str(), "" );
+               if ( mode == PROMPT )
+               {
+                   tmp = tokens[1];
+                   tmp += " = '";
+                   tmp += value;
+                   tmp += "' (";
+                   tmp += getValueTypeString(
+                                    node->getNode( tokens[1].c_str() ) );
+                   tmp += ")";
+               }
+               else
+               {
+                   tmp = value;
+               }
+               push( tmp.c_str() );
+               push( getTerminator() );
            }
-           io->writestring( tmp.c_str() );
        }
-    } else if ( command == "set" ) {
-        if ( tokens.size() <= 2 ) {
-           // do nothing
-       } else {
-           string tmp = tokens[2];
-           for ( unsigned int i = 3; i < tokens.size() - 1; i++ ) {
-               tmp += " " + tokens[i];
-           }
-           node->getNode( tokens[1].c_str(), true )->setStringValue(tmp.c_str());
-
-           if ( mode == PROMPT ) {
-               // now fetch and write out the new value as confirmation
-               // of the change
-               string value = node->getStringValue ( tokens[1].c_str(), "" );
-               string tmp = tokens[1] + " = '" + value + "' (";
-               tmp += getValueTypeString( node->getNode( tokens[1].c_str() ) );
-               tmp += ")\n";
-
-               io->writestring( tmp.c_str() );
+       else if ( command == "set" )
+       {
+           if ( tokens.size() == 3 )
+           {
+               node->getNode( tokens[1].c_str(), true )->setStringValue(tokens[2].c_str());
+
+               if ( mode == PROMPT )
+               {
+                   // now fetch and write out the new value as confirmation
+                   // of the change
+                   string value = node->getStringValue ( tokens[1].c_str(), "" );
+                   string tmp = tokens[1] + " = '" + value + "' (";
+                   tmp += getValueTypeString( node->getNode( tokens[1].c_str() ) );
+                   tmp += ")";
+                   push( tmp.c_str() );
+                   push( getTerminator() );
+               }
            }
        }
-    } else if ( command == "quit" ) {
-       close();
-       reset();
-       return true;
-    } else if ( command == "data" ) {
-       mode = DATA;
-    } else if ( command == "prompt" ) {
-       mode = PROMPT;
-    } else {
-       io->writestring( "\n" );
-       io->writestring( "Valid commands are:\n" );
-       io->writestring( "\n" );
-       io->writestring( "help             show help message\n" );
-       io->writestring( "ls [<dir>]       list directory\n" );
-       io->writestring( "dump             dump current state (in xml)\n" );
-       io->writestring( "cd <dir>         cd to a directory, '..' to move back\n" );
-       io->writestring( "pwd              display your current path\n" );
-       io->writestring( "get <var>        show the value of a parameter\n" );
-       io->writestring( "show <var>       synonym for get\n" );
-       io->writestring( "set <var> <val>  set <var> to a new <val>\n" );
-       io->writestring( "data             switch to raw data mode\n" );
-       io->writestring( "prompt           switch to interactive mode (default)\n" );
-       io->writestring( "quit             terminate connection\n" );
-       io->writestring( "\n" );
+       else if (command == "quit")
+       {
+           close();
+           shouldDelete();
+           return;
+       }
+       else if ( command == "data" )
+       {
+           mode = DATA;
+       }
+       else if ( command == "prompt" )
+       {
+           mode = PROMPT;
+       }
+       else
+       {
+           const char* msg = "\
+Valid commands are:\r\n\
+\r\n\
+cd <dir>           cd to a directory, '..' to move back\r\n\
+data               switch to raw data mode\r\n\
+dump               dump current state (in xml)\r\n\
+get <var>          show the value of a parameter\r\n\
+help               show this help message\r\n\
+ls [<dir>]         list directory\r\n\
+prompt             switch to interactive mode (default)\r\n\
+pwd                display your current path\r\n\
+quit               terminate connection\r\n\
+set <var> <val>    set <var> to a new <val>\r\n\
+show <var>         synonym for get\r\n";
+           push( msg );
+       }
     }
 
-    if ( mode == PROMPT ) {
+ prompt:
+    if (mode == PROMPT)
+    {
        string prompt = node->getPath();
-       if ( prompt.empty() ) {
+       if (prompt.empty())
+       {
            prompt = "/";
        }
        prompt += "> ";
-       io->writestring( prompt.c_str() );
+       push( prompt.c_str() );
     }
-    return true;
-}
 
+    buffer.remove();
+}
 
-// process work for this port
-bool FGProps::process() {
-    SGIOChannel *io = get_io_channel();
-    char buf[max_cmd_len];
+/**
+ * 
+ */
+FGProps::FGProps( const vector<string>& tokens )
+{
+    // tokens:
+    //   props,port#
+    //   props,medium,direction,hz,hostname,port#,style
+    if (tokens.size() == 2)
+       port = atoi( tokens[1].c_str() );
+    else if (tokens.size() == 7)
+       port = atoi( tokens[5].c_str() );
+    else
+       throw FGProtocolConfigError( "FGProps: incorrect number of configuration arguments" );
+}
 
-    // cout << "processing incoming props command" << endl;
+/**
+ * 
+ */
+FGProps::~FGProps()
+{
+}
 
-    if ( get_direction() == SG_IO_BI ) {
-       // cout << "  (bi directional)" << endl;
-       while ( io->readline( buf, max_cmd_len ) > 0 ) {
-           SG_LOG( SG_IO, SG_ALERT, "Success reading data." );
-           process_command( buf );
-       }
-    } else {
-       SG_LOG( SG_IO, SG_ALERT, 
-               "in or out direction not supported for FGProps." );
+/**
+ * 
+ */
+bool
+FGProps::open()
+{
+    if ( is_enabled() )
+    {
+       SG_LOG( SG_IO, SG_ALERT, "This shouldn't happen, but the channel " 
+               << "is already in use, ignoring" );
+       return false;
     }
 
+    netChannel::open();
+    netChannel::bind( "", port );
+    netChannel::listen( 5 );
+    SG_LOG( SG_IO, SG_INFO, "Props server started on port " << port );
+
+    set_hz( 5 );                // default to processing requests @ 5Hz
+    set_enabled( true );
     return true;
 }
 
+/**
+ * 
+ */
+bool
+FGProps::close()
+{
+    return true;
+}
 
-// close the channel
-bool FGProps::close() {
-    SGIOChannel *io = get_io_channel();
-
-    if ( ! io->close() ) {
-       return false;
-    }
-
-    cout << "successfully closed channel\n";
-
+/**
+ * 
+ */
+bool
+FGProps::process()
+{
+    netChannel::poll();
     return true;
 }
+
+/**
+ * 
+ */
+void
+FGProps::handleAccept()
+{
+    netAddress addr;
+    int handle = accept( &addr );
+    SG_LOG( SG_IO, SG_INFO, "Props server accepted connection from "
+           << addr.getHost() << ":" << addr.getPort() );
+    PropsChannel* channel = new PropsChannel();
+    channel->setHandle( handle );
+}
index 5c26bd2ca3e597966b9cccdaa2b318663c60efdf..866baefbd19ae75fb2aa4b9c62cea315d5b59d97 100644 (file)
@@ -1,6 +1,8 @@
-// props.hxx -- FGFS property manager interaction class
+// \file props.hxx
+// Property server class.
 //
 // Written by Curtis Olson, started September 2000.
+// Modified by Bernie Bright, May 2002.
 //
 // Copyright (C) 2000  Curtis L. Olson - curt@flightgear.org
 //
 #ifndef _FG_PROPS_HXX
 #define _FG_PROPS_HXX
 
-
 #include <simgear/compiler.h>
-#include <simgear/misc/props.hxx>
-
 #include STL_STRING
-
-#include "protocol.hxx"
+#include <vector>
 
 SG_USING_STD(string);
+SG_USING_STD(vector);
 
+#include <plib/netChannel.h>
 
-const static int max_cmd_len = 256;
-
-class FGProps : public FGProtocol {
-
-    enum Mode {
-       PROMPT,
-       DATA
-    };
-    Mode mode;
+#include "protocol.hxx"
 
-    // tree view of property list
-    string path;
+/**
+ * Property server class.
+ * This class provides a telnet-like server for remote access to
+ * FlightGear properties.
+ */
+class FGProps : public FGProtocol,
+               public netChannel
+{
+private:
+
+    /**
+     * Server port to listen on.
+     */
+    int port;
 
-    bool reset();
-    bool process_command( const char *cmd );
-    
 public:
-
-    FGProps();
+    /**
+     * Create a new TCP server.
+     * 
+     * @param tokens Tokenized configuration parameters
+     */
+    FGProps( const vector<string>& tokens );
+
+    /**
+     * Destructor.
+     */
     ~FGProps();
 
-    // open hailing frequencies
+    /**
+     * Start the telnet server.
+     */
     bool open();
 
-    // process work for this port
+    /**
+     * Process network activity.
+     */
     bool process();
 
-    // close the channel
+    /**
+     * 
+     */
     bool close();
 
-};
+    /**
+     * Accept a new client connection.
+     */
+    void handleAccept();
 
+};
 
 #endif // _FG_PROPS_HXX
+
diff --git a/src/Network/telnet.cxx b/src/Network/telnet.cxx
deleted file mode 100644 (file)
index 158a659..0000000
+++ /dev/null
@@ -1,454 +0,0 @@
-// \file telnet.cx
-// Property telnet server class.
-//
-// Written by Bernie Bright, started May 2002.
-//
-// Copyright (C) 2002  Bernie Bright - bbright@bigpond.net.au
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-//
-// $Id$
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include <simgear/compiler.h>
-#include <simgear/debug/logstream.hxx>
-#include <simgear/misc/strutils.hxx>
-#include <simgear/misc/props.hxx>
-#include <simgear/misc/props_io.hxx>
-
-#include STL_STRSTREAM
-
-#include <Main/globals.hxx>
-#include <Main/viewmgr.hxx>
-
-#include <plib/netChat.h>
-
-#include "telnet.hxx"
-
-#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
-SG_USING_STD(strstream);
-SG_USING_STD(ends);
-#endif
-
-/**
- * Telnet connection class.
- * This class represents a connection to a telnet-style client.
- */
-class TelnetChannel : public netChat
-{
-    netBuffer buffer;
-
-    /**
-     * Current property node name.
-     */
-    string path;
-
-    enum Mode {
-       PROMPT,
-       DATA
-    };
-    Mode mode;
-
-public:
-    /**
-     * Constructor.
-     */
-    TelnetChannel();
-    
-    /**
-     * Append incoming data to our request buffer.
-     *
-     * @param s Character string to append to buffer
-     * @param n Number of characters to append.
-     */
-    void collectIncomingData( const char* s, int n );
-
-    /**
-     * Process a complete request from the telnet client.
-     */
-    void foundTerminator();
-
-private:
-    /**
-     * Return a "Node no found" error message to the client.
-     */
-    void node_not_found_error( const string& node_name );
-};
-
-/**
- * 
- */
-TelnetChannel::TelnetChannel()
-    : buffer(512),
-      path("/"),
-      mode(PROMPT)
-{
-    setTerminator( "\r\n" );
-}
-
-/**
- * 
- */
-void
-TelnetChannel::collectIncomingData( const char* s, int n )
-{
-    buffer.append( s, n );
-}
-
-/**
- * 
- */
-void
-TelnetChannel::node_not_found_error( const string& node_name )
-{
-    string error = "ERR Node \"";
-    error += node_name;
-    error += "\" not found.";
-    push( error.c_str() );
-    push( getTerminator() );
-}
-
-// return a human readable form of the value "type"
-static string
-getValueTypeString( const SGPropertyNode *node )
-{
-    string result;
-
-    if ( node == NULL )
-    {
-       return "unknown";
-    }
-
-    SGPropertyNode::Type type = node->getType();
-    if ( type == SGPropertyNode::UNSPECIFIED ) {
-       result = "unspecified";
-    } else if ( type == SGPropertyNode::NONE ) {
-        result = "none";
-    } else if ( type == SGPropertyNode::BOOL ) {
-       result = "bool";
-    } else if ( type == SGPropertyNode::INT ) {
-       result = "int";
-    } else if ( type == SGPropertyNode::LONG ) {
-       result = "long";
-    } else if ( type == SGPropertyNode::FLOAT ) {
-       result = "float";
-    } else if ( type == SGPropertyNode::DOUBLE ) {
-       result = "double";
-    } else if ( type == SGPropertyNode::STRING ) {
-       result = "string";
-    }
-
-    return result;
-}
-
-/**
- * We have a command.
- * 
- */
-void
-TelnetChannel::foundTerminator()
-{
-    const char* cmd = buffer.getData();
-    SG_LOG( SG_IO, SG_INFO, "processing command = \"" << cmd << "\"" );
-
-    vector<string> tokens = simgear::strutils::split( cmd );
-
-    SGPropertyNode* node = globals->get_props()->getNode( path.c_str() );
-
-    if (!tokens.empty())
-    {
-       string command = tokens[0];
-
-       if (command == "ls")
-       {
-           SGPropertyNode* dir = node;
-           if (tokens.size() == 2)
-           {
-               if (tokens[1][0] == '/')
-               {
-                   dir = globals->get_props()->getNode( tokens[1].c_str() );
-               }
-               else
-               {
-                   string s = path;
-                   s += "/";
-                   s += tokens[1];
-                   dir = globals->get_props()->getNode( s.c_str() );
-               }
-
-               if (dir == 0)
-               {
-                   node_not_found_error( tokens[1] );
-                   goto prompt;
-               }
-           }
-
-           for (int i = 0; i < dir->nChildren(); i++)
-           {
-               SGPropertyNode * child = dir->getChild(i);
-               string line = child->getDisplayName(true);
-
-               if ( child->nChildren() > 0 )
-               {
-                   line += "/";
-               }
-               else
-               {
-                   if (mode == PROMPT)
-                   {
-                       string value = child->getStringValue();
-                       line += " =\t'" + value + "'\t(";
-                       line += getValueTypeString( child );
-                       line += ")";
-                   }
-               }
-
-               line += getTerminator();
-               push( line.c_str() );
-           }
-       }
-       else if ( command == "dump" )
-       {
-           strstream buf;
-           if ( tokens.size() <= 1 )
-           {
-               writeProperties( buf, node );
-               buf << ends; // null terminate the string
-               push( buf.str() );
-               push( getTerminator() );
-           }
-           else
-           {
-               SGPropertyNode *child = node->getNode( tokens[1].c_str() );
-               if ( child )
-               {
-                   writeProperties ( buf, child );
-                   buf << ends; // null terminate the string
-                   push( buf.str() );
-                   push( getTerminator() );
-               }
-               else
-               {
-                   node_not_found_error( tokens[1] );
-               }
-           }
-       }
-       else if ( command == "cd" )
-       {
-           if (tokens.size() == 2)
-           {
-               try
-               {
-                   SGPropertyNode* child = node->getNode( tokens[1].c_str() );
-                   if ( child )
-                   {
-                       node = child;
-                       path = node->getPath();
-                   }
-                   else
-                   {
-                       node_not_found_error( tokens[1] );
-                   }
-               }
-               catch (...)
-               {
-                   // Ignore attempt to move past root node with ".."
-               }
-           }
-       }
-       else if ( command == "pwd" )
-       {
-           string ttt = node->getPath();
-           if (ttt.empty())
-           {
-               ttt = "/";
-           }
-
-           push( ttt.c_str() );
-           push( getTerminator() );
-       }
-       else if ( command == "get" || command == "show" )
-       {
-           if ( tokens.size() == 2 )
-           {
-               string tmp;     
-               string value = node->getStringValue ( tokens[1].c_str(), "" );
-               if ( mode == PROMPT )
-               {
-                   tmp = tokens[1];
-                   tmp += " = '";
-                   tmp += value;
-                   tmp += "' (";
-                   tmp += getValueTypeString(
-                                    node->getNode( tokens[1].c_str() ) );
-                   tmp += ")";
-               }
-               else
-               {
-                   tmp = value;
-               }
-               push( tmp.c_str() );
-               push( getTerminator() );
-           }
-       }
-       else if ( command == "set" )
-       {
-           if ( tokens.size() == 3 )
-           {
-               node->getNode( tokens[1].c_str(), true )->setStringValue(tokens[2].c_str());
-
-               if ( mode == PROMPT )
-               {
-                   // now fetch and write out the new value as confirmation
-                   // of the change
-                   string value = node->getStringValue ( tokens[1].c_str(), "" );
-                   string tmp = tokens[1] + " = '" + value + "' (";
-                   tmp += getValueTypeString( node->getNode( tokens[1].c_str() ) );
-                   tmp += ")";
-                   push( tmp.c_str() );
-                   push( getTerminator() );
-               }
-           }
-       }
-       else if (command == "quit")
-       {
-           close();
-           shouldDelete();
-           return;
-       }
-       else if ( command == "data" )
-       {
-           mode = DATA;
-       }
-       else if ( command == "prompt" )
-       {
-           mode = PROMPT;
-       }
-       else
-       {
-           const char* msg = "\
-Valid commands are:\r\n\
-\r\n\
-cd <dir>           cd to a directory, '..' to move back\r\n\
-data               switch to raw data mode\r\n\
-dump               dump current state (in xml)\r\n\
-get <var>          show the value of a parameter\r\n\
-help               show this help message\r\n\
-ls [<dir>]         list directory\r\n\
-prompt             switch to interactive mode (default)\r\n\
-pwd                display your current path\r\n\
-quit               terminate connection\r\n\
-set <var> <val>    set <var> to a new <val>\r\n\
-show <var>         synonym for get\r\n";
-           push( msg );
-       }
-    }
-
- prompt:
-    if (mode == PROMPT)
-    {
-       string prompt = node->getPath();
-       if (prompt.empty())
-       {
-           prompt = "/";
-       }
-       prompt += "> ";
-       push( prompt.c_str() );
-    }
-
-    buffer.remove();
-}
-
-/**
- * 
- */
-FGTelnet::FGTelnet( const vector<string>& tokens )
-{
-    // tokens:
-    //   telnet,port#
-    //   props,medium,direction,hz,hostname,port#,style
-    if (tokens.size() == 2)
-       port = atoi( tokens[1].c_str() );
-    else if (tokens.size() == 7)
-       port = atoi( tokens[5].c_str() );
-    else
-       throw FGProtocolConfigError( "FGTelnet: incorrect number of configuration arguments" );
-}
-
-/**
- * 
- */
-FGTelnet::~FGTelnet()
-{
-}
-
-/**
- * 
- */
-bool
-FGTelnet::open()
-{
-    if ( is_enabled() )
-    {
-       SG_LOG( SG_IO, SG_ALERT, "This shouldn't happen, but the channel " 
-               << "is already in use, ignoring" );
-       return false;
-    }
-
-    netChannel::open();
-    netChannel::bind( "", port );
-    netChannel::listen( 5 );
-    SG_LOG( SG_IO, SG_INFO, "Telnet server started on port " << port );
-
-    set_hz( 5 );                // default to processing requests @ 5Hz
-    set_enabled( true );
-    return true;
-}
-
-/**
- * 
- */
-bool
-FGTelnet::close()
-{
-    return true;
-}
-
-/**
- * 
- */
-bool
-FGTelnet::process()
-{
-    netChannel::poll();
-    return true;
-}
-
-/**
- * 
- */
-void
-FGTelnet::handleAccept()
-{
-    netAddress addr;
-    int handle = accept( &addr );
-    SG_LOG( SG_IO, SG_INFO, "Telnet server accepted connection from "
-           << addr.getHost() << ":" << addr.getPort() );
-    TelnetChannel* channel = new TelnetChannel();
-    channel->setHandle( handle );
-}
diff --git a/src/Network/telnet.hxx b/src/Network/telnet.hxx
deleted file mode 100644 (file)
index 3d7bf2f..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-// \file telnet.hxx
-// Property server class.
-//
-// Written by Bernie Bright, started May 2002.
-//
-// Copyright (C) 2002  Bernie Bright - bbright@bigpond.net.au
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-//
-// $Id$
-
-#ifndef TELNET_HXX_INCLUDED
-#define TELNET_HXX_INCLUDED 1
-
-#include <simgear/compiler.h>
-#include STL_STRING
-#include <vector>
-
-SG_USING_STD(string);
-SG_USING_STD(vector);
-
-#include <plib/netChannel.h>
-
-#include "protocol.hxx"
-
-/**
- * Property server class.
- * This class provides a telnet-like server for remote access to
- * FlightGear properties.
- */
-class FGTelnet : public FGProtocol,
-                public netChannel
-{
-private:
-
-    /**
-     * Server port to listen on.
-     */
-    int port;
-
-public:
-    /**
-     * Create a new TCP server.
-     * 
-     * @param tokens Tokenized configuration parameters
-     */
-    FGTelnet( const vector<string>& tokens );
-
-    /**
-     * Destructor.
-     */
-    ~FGTelnet();
-
-    /**
-     * Start the telnet server.
-     */
-    bool open();
-
-    /**
-     * Process network activity.
-     */
-    bool process();
-
-    /**
-     * 
-     */
-    bool close();
-
-    /**
-     * Accept a new client connection.
-     */
-    void handleAccept();
-
-};
-
-#endif //TELNET_HXX_INCLUDED
-