cli.h

Go to the documentation of this file.
00001 /*
00002  * cli.h
00003  *
00004  * Command line interpreter
00005  *
00006  * Copyright (C) 2006-2008 Post Increment
00007  *
00008  * The contents of this file are subject to the Mozilla Public License
00009  * Version 1.0 (the "License"); you may not use this file except in
00010  * compliance with the License. You may obtain a copy of the License at
00011  * http://www.mozilla.org/MPL/
00012  *
00013  * Software distributed under the License is distributed on an "AS IS"
00014  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
00015  * the License for the specific language governing rights and limitations
00016  * under the License.
00017  *
00018  * The Original Code is WOpenMCU
00019  *
00020  * The Initial Developer of the Original Code is Post Increment
00021  *
00022  * Contributor(s): Craig Southeren (craigs@postincrement.com)
00023  *                 Robert Jongbloed (robertj@voxlucida.com.au)
00024  *
00025  * Portions of this code were written by Post Increment (http://www.postincrement.com)
00026  * with the assistance of funding from US Joint Forces Command Joint Concept Development &
00027  * Experimentation (J9) http://www.jfcom.mil/about/abt_j9.htm
00028  *
00029  * Further assistance for enhancements from Imagicle spa
00030  *
00031  * $Revision: 24177 $
00032  * $Author: rjongbloed $
00033  * $Date: 2010-04-05 06:52:04 -0500 (Mon, 05 Apr 2010) $
00034  */
00035 
00036 #ifndef PTLIB_CLI_H
00037 #define PTLIB_CLI_H
00038 
00039 #include <ptlib.h>
00040 #include <ptlib/sockets.h>
00041 
00042 #include <list>
00043 
00044 
00056 class PCLI : public PObject
00057 {
00058     PCLASSINFO(PCLI, PObject);
00059   public:
00060     class Context;
00061 
00064     class Context : public PIndirectChannel
00065     {
00066       public:
00071         Context(
00072           PCLI & cli
00073         );
00074 
00078         virtual ~Context();
00080 
00097         virtual PBoolean Write(
00098           const void * buf, 
00099           PINDEX len        
00100         );
00102 
00107         bool Start();
00108 
00112         void Stop();
00113 
00119         virtual void OnStart();
00120 
00126         virtual void OnStop();
00127 
00130         virtual bool WritePrompt();
00131 
00135         virtual bool ReadAndProcessInput();
00136 
00140         virtual bool ProcessInput(int ch);
00141 
00148         virtual void OnCompletedLine();
00150 
00155         PCLI & GetCLI() const { return m_cli; }
00156 
00159         bool IsProcessingCommand() const { return m_state == e_ProcessingCommand; }
00161 
00162       protected:
00163         PDECLARE_NOTIFIER(PThread, Context, ThreadMain);
00164 
00165         PCLI      & m_cli;
00166         PString     m_commandLine;
00167         bool        m_ignoreNextEOL;
00168         PStringList m_commandHistory;
00169         PThread   * m_thread;
00170 
00171         enum State {
00172           e_Username,
00173           e_Password,
00174           e_CommandEntry,
00175           e_ProcessingCommand
00176         } m_state;
00177         PString m_enteredUsername;
00178     };
00179 
00182     class Arguments : public PArgList
00183     {
00184       public:
00187         Arguments(
00188           Context & context,
00189           const PString & rawLine
00190         );
00192 
00197         Context & WriteUsage();
00198 
00201         Context & WriteError(
00202           const PString & error = PString::Empty()  
00203         );
00205 
00210         Context & GetContext() const { return m_context; }
00212 
00213       protected:
00214         Context & m_context;
00215         PString   m_command;
00216         PString   m_usage;
00217 
00218       friend class PCLI;
00219     };
00220 
00221 
00226     PCLI(
00227       const char * prompt = NULL
00228     );
00229 
00233     virtual ~PCLI();
00235 
00246     virtual bool Start(
00247       bool runInBackground = true   
00248     );
00249 
00254     virtual void Stop();
00255 
00258     bool StartContext(
00259       PChannel * channel,           
00260       bool autoDelete = true,       
00261       bool runInBackground = true   
00262     );
00263     bool StartContext(
00264       PChannel * readChannel,      
00265       PChannel * writeChannel,     
00266       bool autoDeleteRead = true,  
00267       bool autoDeleteWrite = true, 
00268       bool runInBackground = true   
00269     );
00270 
00274     virtual Context * CreateContext();
00275 
00279     virtual Context * AddContext(
00280       Context * context = NULL    
00281     );
00282 
00286     virtual void RemoveContext(
00287       Context * context   
00288     );
00289 
00292     virtual void GarbageCollection();
00293 
00301     virtual void OnReceivedLine(
00302       Arguments & line
00303     );
00304 
00317     virtual bool OnLogIn(
00318       const PString & username,
00319       const PString & password
00320     );
00321 
00324     void Broadcast(
00325       const PString & message   
00326     ) const;
00327 
00338     bool SetCommand(
00339       const char * command,       
00340       const PNotifier & notifier, 
00341       const char * help = NULL,   
00342       const char * usage = NULL   
00343     );
00344 
00347     void ShowHelp(
00348       Context & context   
00349     );
00351 
00357     const PString & GetNewLine() const { return m_newLine; }
00358 
00362     void SetNewLine(const PString & newLine) { m_newLine = newLine; }
00363 
00367     bool GetRequireEcho() const { return m_requireEcho; }
00368 
00372     void SetRequireEcho(bool requireEcho) { m_requireEcho = requireEcho; }
00373 
00377     const PString & GetEditCharacters() const { return m_editCharacters; }
00378 
00382     void SetEditCharacters(const PString & editCharacters) { m_editCharacters = editCharacters; }
00383 
00387     const PString & GetPrompt() const { return m_prompt; }
00388 
00392     void SetPrompt(const PString & prompt) { m_prompt = prompt; }
00393 
00397     const PString & GetUsernamePrompt() const { return m_usernamePrompt; }
00398 
00402     void SetUsernamePrompt(const PString & prompt) { m_usernamePrompt = prompt; }
00403 
00407     const PString & GetPasswordPrompt() const { return m_passwordPrompt; }
00408 
00412     void SetPasswordPrompt(const PString & prompt) { m_passwordPrompt = prompt; }
00413 
00417     const PString & GetUsername() const { return m_username; }
00418 
00422     void SetUsername(const PString & username) { m_username = username; }
00423 
00427     const PString & GetPassword() const { return m_password; }
00428 
00432     void SetPassword(const PString & password) { m_password = password; }
00433 
00437     const PCaselessString & GetExitCommand() const { return m_exitCommand; }
00438 
00442     void SetExitCommand(const PCaselessString & exitCommand) { m_exitCommand = exitCommand; }
00443 
00447     const PCaselessString & GetHelpCommand() const { return m_helpCommand; }
00448 
00452     void SetHelpCommand(const PCaselessString & helpCommand) { m_helpCommand = helpCommand; }
00453 
00458     const PString & GetHelpOnHelp() const { return m_helpOnHelp; }
00459 
00464     void SetHelpOnHelp(const PCaselessString & helpOnHelp) { m_helpOnHelp = helpOnHelp; }
00465 
00469     const PCaselessString & GetRepeatCommand() const { return m_repeatCommand; }
00470 
00474     void SetRepeatCommand(const PCaselessString & repeatCommand) { m_repeatCommand = repeatCommand; }
00475 
00479     const PCaselessString & GetHistoryCommand() const { return m_historyCommand; }
00480 
00484     void SetHistoryCommand(const PCaselessString & historyCommand) { m_historyCommand = historyCommand; }
00485 
00489     const PString & GetNoHistoryError() const { return m_noHistoryError; }
00490 
00494     void SetNoHistoryError(const PString & noHistoryError) { m_noHistoryError = noHistoryError; }
00495 
00499     const PString & GetCommandUsagePrefix() const { return m_commandUsagePrefix; }
00500 
00504     void SetCommandUsagePrefix(const PString & commandUsagePrefix) { m_commandUsagePrefix = commandUsagePrefix; }
00505 
00509     const PString & GetCommandErrorPrefix() const { return m_commandErrorPrefix; }
00510 
00514     void SetCommandErrorPrefix(const PString & commandErrorPrefix) { m_commandErrorPrefix = commandErrorPrefix; }
00515 
00519     const PString & GetUnknownCommandError() const { return m_unknownCommandError; }
00520 
00524     void SetUnknownCommandError(const PString & unknownCommandError) { m_unknownCommandError = unknownCommandError; }
00526 
00527   protected:
00528     PString         m_newLine;
00529     bool            m_requireEcho;
00530     PString         m_editCharacters;
00531     PString         m_prompt;
00532     PString         m_usernamePrompt;
00533     PString         m_passwordPrompt;
00534     PString         m_username;
00535     PString         m_password;
00536     PCaselessString m_exitCommand;
00537     PCaselessString m_helpCommand;
00538     PString         m_helpOnHelp;
00539     PCaselessString m_repeatCommand;
00540     PCaselessString m_historyCommand;
00541     PString         m_noHistoryError;
00542     PString         m_commandUsagePrefix;
00543     PString         m_commandErrorPrefix;
00544     PString         m_unknownCommandError;
00545 
00546     struct InternalCommand {
00547       PNotifier m_notifier;
00548       PString   m_help;
00549       PString   m_usage;
00550     };
00551     typedef std::map<PString, InternalCommand> CommandMap_t;
00552     CommandMap_t m_commands;
00553 
00554     typedef std::list<Context *> ContextList_t;
00555     ContextList_t m_contextList;
00556     PMutex        m_contextMutex;
00557 };
00558 
00559 
00562 class PCLIStandard : public PCLI
00563 {
00564   public:
00569     PCLIStandard(
00570       const char * prompt = NULL
00571     );
00573 
00580     virtual bool Start(
00581       bool runInBackground = true   
00582     );
00584 };
00585 
00586 
00591 class PCLISocket : public PCLI
00592 {
00593   public:
00596     PCLISocket(
00597       WORD port = 0,
00598       const char * prompt = NULL,
00599       bool singleThreadForAll = false
00600     );
00601     ~PCLISocket();
00603 
00610     virtual bool Start(
00611       bool runInBackground = true   
00612     );
00613 
00621     virtual void Stop();
00622 
00626     virtual Context * AddContext(
00627       Context * context = NULL
00628     );
00629 
00633     virtual void RemoveContext(
00634       Context * context
00635     );
00637 
00642     bool Listen(
00643       WORD port = 0
00644     );
00645 
00648     WORD GetPort() const { return m_listenSocket.GetPort(); }
00650 
00651   protected:
00652     PDECLARE_NOTIFIER(PThread, PCLISocket, ThreadMain);
00653     bool HandleSingleThreadForAll();
00654     bool HandleIncoming();
00655     virtual PTCPSocket * CreateSocket();
00656 
00657     bool m_singleThreadForAll;
00658 
00659     PTCPSocket m_listenSocket;
00660     PThread  * m_thread;
00661 
00662     typedef std::map<PSocket *, Context *> ContextMap_t;
00663     ContextMap_t m_contextBySocket;
00664 };
00665 
00666 
00671 class PCLITelnet : public PCLISocket
00672 {
00673   public:
00676     PCLITelnet(
00677       WORD port = 0,
00678       const char * prompt = NULL,
00679       bool singleThreadForAll = false
00680     );
00682 
00683   protected:
00684     virtual PTCPSocket * CreateSocket();
00685 };
00686 
00687 
00688 #endif // PTLIB_CLI_H
00689 
00690 
00691 // End Of File ///////////////////////////////////////////////////////////////

Generated on Fri Oct 14 01:44:09 2011 for PTLib by  doxygen 1.4.7