PTLib  Version 2.10.4
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: 24931 $
00032  * $Author: csoutheren $
00033  * $Date: 2010-12-07 20:01:15 -0600 (Tue, 07 Dec 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         virtual bool ProcessInput(const PString & line);
00142 
00149         virtual void OnCompletedLine();
00151 
00156         PCLI & GetCLI() const { return m_cli; }
00157 
00160         bool IsProcessingCommand() const { return m_state == e_ProcessingCommand; }
00162 
00163       protected:
00164         PDECLARE_NOTIFIER(PThread, Context, ThreadMain);
00165 
00166         PCLI      & m_cli;
00167         PString     m_commandLine;
00168         bool        m_ignoreNextEOL;
00169         PStringList m_commandHistory;
00170         PThread   * m_thread;
00171 
00172         enum State {
00173           e_Username,
00174           e_Password,
00175           e_CommandEntry,
00176           e_ProcessingCommand
00177         } m_state;
00178         PString m_enteredUsername;
00179     };
00180 
00183     class Arguments : public PArgList
00184     {
00185       public:
00188         Arguments(
00189           Context & context,
00190           const PString & rawLine
00191         );
00193 
00198         Context & WriteUsage();
00199 
00202         Context & WriteError(
00203           const PString & error = PString::Empty()  
00204         );
00206 
00211         Context & GetContext() const { return m_context; }
00213 
00214       protected:
00215         Context & m_context;
00216         PString   m_command;
00217         PString   m_usage;
00218 
00219       friend class PCLI;
00220     };
00221 
00222 
00227     PCLI(
00228       const char * prompt = NULL
00229     );
00230 
00234     virtual ~PCLI();
00236 
00247     virtual bool Start(
00248       bool runInBackground = true   
00249     );
00250 
00255     virtual void Stop();
00256 
00259     bool StartContext(
00260       PChannel * channel,           
00261       bool autoDelete = true,       
00262       bool runInBackground = true   
00263     );
00264     bool StartContext(
00265       PChannel * readChannel,      
00266       PChannel * writeChannel,     
00267       bool autoDeleteRead = true,  
00268       bool autoDeleteWrite = true, 
00269       bool runInBackground = true   
00270     );
00271 
00275     virtual Context * CreateContext();
00276 
00280     virtual Context * AddContext(
00281       Context * context = NULL    
00282     );
00283 
00287     virtual void RemoveContext(
00288       Context * context   
00289     );
00290 
00293     virtual void GarbageCollection();
00294 
00302     virtual void OnReceivedLine(
00303       Arguments & line
00304     );
00305 
00318     virtual bool OnLogIn(
00319       const PString & username,
00320       const PString & password
00321     );
00322 
00325     void Broadcast(
00326       const PString & message   
00327     ) const;
00328 
00339     bool SetCommand(
00340       const char * command,       
00341       const PNotifier & notifier, 
00342       const char * help = NULL,   
00343       const char * usage = NULL   
00344     );
00345 
00348     void ShowHelp(
00349       Context & context   
00350     );
00352 
00358     const PString & GetNewLine() const { return m_newLine; }
00359 
00363     void SetNewLine(const PString & newLine) { m_newLine = newLine; }
00364 
00368     bool GetRequireEcho() const { return m_requireEcho; }
00369 
00373     void SetRequireEcho(bool requireEcho) { m_requireEcho = requireEcho; }
00374 
00378     const PString & GetEditCharacters() const { return m_editCharacters; }
00379 
00383     void SetEditCharacters(const PString & editCharacters) { m_editCharacters = editCharacters; }
00384 
00388     const PString & GetPrompt() const { return m_prompt; }
00389 
00393     void SetPrompt(const PString & prompt) { m_prompt = prompt; }
00394 
00398     const PString & GetUsernamePrompt() const { return m_usernamePrompt; }
00399 
00403     void SetUsernamePrompt(const PString & prompt) { m_usernamePrompt = prompt; }
00404 
00408     const PString & GetPasswordPrompt() const { return m_passwordPrompt; }
00409 
00413     void SetPasswordPrompt(const PString & prompt) { m_passwordPrompt = prompt; }
00414 
00418     const PString & GetUsername() const { return m_username; }
00419 
00423     void SetUsername(const PString & username) { m_username = username; }
00424 
00428     const PString & GetPassword() const { return m_password; }
00429 
00433     void SetPassword(const PString & password) { m_password = password; }
00434 
00438     const PCaselessString & GetExitCommand() const { return m_exitCommand; }
00439 
00443     void SetExitCommand(const PCaselessString & exitCommand) { m_exitCommand = exitCommand; }
00444 
00448     const PCaselessString & GetHelpCommand() const { return m_helpCommand; }
00449 
00453     void SetHelpCommand(const PCaselessString & helpCommand) { m_helpCommand = helpCommand; }
00454 
00459     const PString & GetHelpOnHelp() const { return m_helpOnHelp; }
00460 
00465     void SetHelpOnHelp(const PCaselessString & helpOnHelp) { m_helpOnHelp = helpOnHelp; }
00466 
00470     const PCaselessString & GetRepeatCommand() const { return m_repeatCommand; }
00471 
00475     void SetRepeatCommand(const PCaselessString & repeatCommand) { m_repeatCommand = repeatCommand; }
00476 
00480     const PCaselessString & GetHistoryCommand() const { return m_historyCommand; }
00481 
00485     void SetHistoryCommand(const PCaselessString & historyCommand) { m_historyCommand = historyCommand; }
00486 
00490     const PString & GetNoHistoryError() const { return m_noHistoryError; }
00491 
00495     void SetNoHistoryError(const PString & noHistoryError) { m_noHistoryError = noHistoryError; }
00496 
00500     const PString & GetCommandUsagePrefix() const { return m_commandUsagePrefix; }
00501 
00505     void SetCommandUsagePrefix(const PString & commandUsagePrefix) { m_commandUsagePrefix = commandUsagePrefix; }
00506 
00510     const PString & GetCommandErrorPrefix() const { return m_commandErrorPrefix; }
00511 
00515     void SetCommandErrorPrefix(const PString & commandErrorPrefix) { m_commandErrorPrefix = commandErrorPrefix; }
00516 
00520     const PString & GetUnknownCommandError() const { return m_unknownCommandError; }
00521 
00525     void SetUnknownCommandError(const PString & unknownCommandError) { m_unknownCommandError = unknownCommandError; }
00527 
00530     virtual Context * StartForeground();
00531 
00534     virtual bool RunContext(Context * context);
00535 
00536 
00537   protected:
00538     PString         m_newLine;
00539     bool            m_requireEcho;
00540     PString         m_editCharacters;
00541     PString         m_prompt;
00542     PString         m_usernamePrompt;
00543     PString         m_passwordPrompt;
00544     PString         m_username;
00545     PString         m_password;
00546     PCaselessString m_exitCommand;
00547     PCaselessString m_helpCommand;
00548     PString         m_helpOnHelp;
00549     PCaselessString m_repeatCommand;
00550     PCaselessString m_historyCommand;
00551     PString         m_noHistoryError;
00552     PString         m_commandUsagePrefix;
00553     PString         m_commandErrorPrefix;
00554     PString         m_unknownCommandError;
00555 
00556     struct InternalCommand {
00557       PNotifier m_notifier;
00558       PString   m_help;
00559       PString   m_usage;
00560     };
00561     typedef std::map<PString, InternalCommand> CommandMap_t;
00562     CommandMap_t m_commands;
00563 
00564     typedef std::list<Context *> ContextList_t;
00565     ContextList_t m_contextList;
00566     PMutex        m_contextMutex;
00567 };
00568 
00569 
00572 class PCLIStandard : public PCLI
00573 {
00574   public:
00579     PCLIStandard(
00580       const char * prompt = NULL
00581     );
00583 
00590     virtual bool Start(
00591       bool runInBackground = true   
00592     );
00594 
00595     PCLI::Context * StartForeground();
00596 };
00597 
00598 
00603 class PCLISocket : public PCLI
00604 {
00605   public:
00608     PCLISocket(
00609       WORD port = 0,
00610       const char * prompt = NULL,
00611       bool singleThreadForAll = false
00612     );
00613     ~PCLISocket();
00615 
00622     virtual bool Start(
00623       bool runInBackground = true   
00624     );
00625 
00633     virtual void Stop();
00634 
00638     virtual Context * AddContext(
00639       Context * context = NULL
00640     );
00641 
00645     virtual void RemoveContext(
00646       Context * context
00647     );
00649 
00654     bool Listen(
00655       WORD port = 0
00656     );
00657 
00660     WORD GetPort() const { return m_listenSocket.GetPort(); }
00662 
00663   protected:
00664     PDECLARE_NOTIFIER(PThread, PCLISocket, ThreadMain);
00665     bool HandleSingleThreadForAll();
00666     bool HandleIncoming();
00667     virtual PTCPSocket * CreateSocket();
00668 
00669     bool m_singleThreadForAll;
00670 
00671     PTCPSocket m_listenSocket;
00672     PThread  * m_thread;
00673 
00674     typedef std::map<PSocket *, Context *> ContextMap_t;
00675     ContextMap_t m_contextBySocket;
00676 };
00677 
00678 
00683 class PCLITelnet : public PCLISocket
00684 {
00685   public:
00688     PCLITelnet(
00689       WORD port = 0,
00690       const char * prompt = NULL,
00691       bool singleThreadForAll = false
00692     );
00694 
00695   protected:
00696     virtual PTCPSocket * CreateSocket();
00697 };
00698 
00699 
00700 #endif // PTLIB_CLI_H
00701 
00702 
00703 // End Of File ///////////////////////////////////////////////////////////////
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines