PTLib
Version 2.10.4
|
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 ///////////////////////////////////////////////////////////////