Socket: fixed bug in readfrom where socklen was not set
[senf.git] / Utils / Console / Mainpage.dox
index b46ce64..4d43cfc 100644 (file)
     \subsection console_noninteractive Non-interactive network console
 
     After a new connection is established, the console server waits a short time for data to arrive.
-    arrive. Only if nothing happens in the first 500ms, an interactive session is initialized.
+    Only if nothing happens in the first 500ms, an interactive session is initialized.
 
     By sending data immediately after opening the connection, the console is switched into
     non-interactive mode. In this mode, no prompt is displayed. In this mode, commands are \e not
 
     Commands are executed as soon as the terminating character (';', '{' or '}') is received or when
     the sending end of the connection is closed.    
+
+    \section console_udp Non-interactive UDP console
+
+    The UDP console allows to script the console tree via UDP packets. Every UDP packet must be a
+    complete command (or sequence of commands). The combined reply of all these commands will be
+    returned in a single UDP packet. This reply can be disabled or directed to a different address. 
+
+    To start a UDP server, just create an instance of the senf::console::UDPServer class
+    \code
+    senf::console::UDPServer server (senf::INet4SocketAddress("127.0.0.1:23232"));
+    \endcode
+    (Remember to enter the scheduler main-loop for processing)
+
+    Commands may then be sent to this UDP console e.g. using netcat
+    <pre>
+    $ echo "cd sys; ls" | nc6 -u --half-close localhost 23232 2>/dev/null
+    </pre>
+
+    \see senf::console::UDPServer
  */
 
 /** \defgroup console_commands Supported command types
             // do not parse all arguments.
             senf::console::CheckedArgumentIteratorWrapper args (command.arguments());
 
-            senf::console::ParseCommandInfo::TokensRange argTokens ( *(args++) );
+            // Extract the first argument. This is again a token range.
+            senf::console::ParseCommandInfo::TokensRange arg1Tokens ( *(args++) );
             if (arg1Tokens.size() != 1)
                 raise senf::console::SyntaxErrorException("argument syntax error");
-            value = arg1Tokens[0];
+            value = arg1Tokens[0].value();
         }
 
         os << value << std::endl;
     One note: When taking the address of an overloaded function (member or non-member), the C++
     language forces you to cast that address to one of the possible types so the compiler knows,
     which overload is requested. So to add a function which is overloaded in C++, each overload
-    needs to be added explicitly, casting to the correct type:
+    needs to be added explicitly, casting to the correct type. There are some macros in
+    Utils/membind.hh to simplify this:
+
     \code
     void over(int);
     void over(int,int);
 
     senf::console::root()
-        .add("over", static_cast<void (*)(int)>(&over));
+        .add("over", SENF_FNP(void, over, (int)));
     senf::console::root()
-        .add("over", static_cast<void (*)(int,int)>(&over));
+        .add("over", SENF_FNP(void, over, (int,int));
         
     class SomeModule {
       senf::console::ScopedDirectory<SomeModule> dir;
       void overlodedMethod(unsigned int)   {....};
         
       void addConsoleCommands() {
-        dir.node().add("overlodedMethod", senf::membind(
-            static_cast<unsigned int (SomeModule::*)() const>(&SomeModule::overlodedMethod), this));
-        dir.node().add("overlodedMethod", senf::membind(
-            static_cast<void (SomeModule::*)(unsigned int)>(&SomeModule::overlodedMethod), this));
+        dir.node().add("overlodedMethod", 
+                       SENF_MEMBINDFNP(unsigned int, SomeModule, overlodedMethod, () const));
+        dir.node().add("overlodedMethod", 
+                       SENF_MEMBINDFNP(unsigned int, SomeModule, overlodedMethod, (unsigned int));
       }
     }
     \endcode
     public:
         enum Color { Red, Green, Blue };
     
-        senf::console::ScopedDirectory<MyClass> dir;
+        senf::console::ScopedDirectory<Test3> dir;
 
         Test3();
 
     SENF_CONSOLE_REGISTER_ENUM_MEMBER( Test3, Color, (Red)(Green)(Blue) );
 
     Test3::Test3() : dir(this)
-        { dir.add("test", &MyClass::mem3); }
+        { dir.add("test", &Test3::mem3); }
     
     Test3 test3ob;
     senf::console::root().add("test3ob", test3ob.dir);