PTLib Version 2.12.9

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
cli.h
Go to the documentation of this file.
1 /*
2 * cli.h
3 *
4 * Command line interpreter
5 *
6 * Copyright (C) 2006-2008 Post Increment
7 *
8 * The contents of this file are subject to the Mozilla Public License
9 * Version 1.0 (the "License"); you may not use this file except in
10 * compliance with the License. You may obtain a copy of the License at
11 * http://www.mozilla.org/MPL/
12 *
13 * Software distributed under the License is distributed on an "AS IS"
14 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
15 * the License for the specific language governing rights and limitations
16 * under the License.
17 *
18 * The Original Code is WOpenMCU
19 *
20 * The Initial Developer of the Original Code is Post Increment
21 *
22 * Contributor(s): Craig Southeren (craigs@postincrement.com)
23 * Robert Jongbloed (robertj@voxlucida.com.au)
24 *
25 * Portions of this code were written by Post Increment (http://www.postincrement.com)
26 * with the assistance of funding from US Joint Forces Command Joint Concept Development &
27 * Experimentation (J9) http://www.jfcom.mil/about/abt_j9.htm
28 *
29 * Further assistance for enhancements from Imagicle spa
30 *
31 * $Revision: 28621 $
32 * $Author: rjongbloed $
33 * $Date: 2012-12-03 13:33:10 +1100 (Mon, 03 Dec 2012) $
34 */
35
36 #ifndef PTLIB_CLI_H
37 #define PTLIB_CLI_H
38
39 #include <ptbuildopts.h>
40
41 #if P_CLI
42
43 #include <ptlib/sockets.h>
44
45 #include <list>
46
47
59 class PCLI : public PObject
60 {
61 PCLASSINFO(PCLI, PObject);
62 public:
63 class Context;
64
67 class Context : public PIndirectChannel
68 {
69 public:
74 Context(
75 PCLI & cli
76 );
77
81 virtual ~Context();
83
100 virtual PBoolean Write(
101 const void * buf,
102 PINDEX len
103 );
105
110 bool Start();
111
115 void Stop();
116
121 bool Run();
122
128 virtual void OnStart();
129
135 virtual void OnStop();
136
139 virtual bool WritePrompt();
140
144 virtual bool ReadAndProcessInput();
145
149 virtual bool ProcessInput(int ch);
150 virtual bool ProcessInput(const PString & line);
151
158 virtual void OnCompletedLine();
160
165 PCLI & GetCLI() const { return m_cli; }
166
169 bool IsProcessingCommand() const { return m_state == e_ProcessingCommand; }
171
172 protected:
173 PDECLARE_NOTIFIER(PThread, Context, ThreadMain);
174
175 PCLI & m_cli;
176 PString m_commandLine;
177 bool m_ignoreNextEOL;
178 PStringList m_commandHistory;
179 PThread * m_thread;
180
181 enum State {
182 e_Username,
183 e_Password,
184 e_CommandEntry,
185 e_ProcessingCommand
186 } m_state;
187 PString m_enteredUsername;
188 };
189
192 class Arguments : public PArgList
193 {
194 public:
197 Arguments(
198 Context & context,
199 const PString & rawLine
200 );
202
207 Context & WriteUsage();
208
211 Context & WriteError(
212 const PString & error = PString::Empty()
213 );
215
220 Context & GetContext() const { return m_context; }
222
223 protected:
224 Context & m_context;
225 PString m_usage;
226
227 friend class PCLI;
228 };
229
230
235 PCLI(
236 const char * prompt = NULL
237 );
238
242 virtual ~PCLI();
244
255 virtual bool Start(
256 bool runInBackground = true
257 );
258
263 virtual void Stop();
264
270 Context * StartContext(
271 PChannel * channel,
272 bool autoDelete = true,
273 bool runInBackground = true
274 ) { return StartContext(channel, channel, autoDelete, autoDelete, runInBackground); }
275 Context * StartContext(
276 PChannel * readChannel,
277 PChannel * writeChannel,
278 bool autoDeleteRead = true,
279 bool autoDeleteWrite = true,
280 bool runInBackground = true
281 );
282
286 virtual Context * StartForeground();
287
293 bool Run(
294 PChannel & channel
295 ) { return Run(&channel, &channel, false, false); }
296 bool Run(
297 PChannel * channel,
298 bool autoDelete = true
299 ) { return Run(channel, channel, autoDelete, autoDelete); }
300 bool Run(
301 PChannel * readChannel,
302 PChannel * writeChannel,
303 bool autoDeleteRead = true,
304 bool autoDeleteWrite = true
305 );
306
312 bool RunContext(
313 Context * context
314 ) { return context != NULL && context->Run(); }
315
319 virtual Context * CreateContext();
320
324 virtual Context * AddContext(
325 Context * context = NULL
326 );
327
331 virtual void RemoveContext(
332 Context * context
333 );
334
337 virtual void GarbageCollection();
338
346 virtual void OnReceivedLine(
347 Arguments & line
348 );
349
362 virtual bool OnLogIn(
363 const PString & username,
364 const PString & password
365 );
366
369 void Broadcast(
370 const PString & message
371 ) const;
372
383 bool SetCommand(
384 const char * command,
385 const PNotifier & notifier,
386 const char * help = NULL,
387 const char * usage = NULL,
388 const char * argSpec = NULL
389 );
390
393 void ShowHelp(
394 Context & context
395 );
397
403 const PString & GetNewLine() const { return m_newLine; }
404
408 void SetNewLine(const PString & newLine) { m_newLine = newLine; }
409
413 bool GetRequireEcho() const { return m_requireEcho; }
414
418 void SetRequireEcho(bool requireEcho) { m_requireEcho = requireEcho; }
419
423 const PString & GetEditCharacters() const { return m_editCharacters; }
424
428 void SetEditCharacters(const PString & editCharacters) { m_editCharacters = editCharacters; }
429
433 const PString & GetPrompt() const { return m_prompt; }
434
438 void SetPrompt(const PString & prompt) { m_prompt = prompt; }
439
443 const PString & GetUsernamePrompt() const { return m_usernamePrompt; }
444
448 void SetUsernamePrompt(const PString & prompt) { m_usernamePrompt = prompt; }
449
453 const PString & GetPasswordPrompt() const { return m_passwordPrompt; }
454
458 void SetPasswordPrompt(const PString & prompt) { m_passwordPrompt = prompt; }
459
463 const PString & GetUsername() const { return m_username; }
464
468 void SetUsername(const PString & username) { m_username = username; }
469
473 const PString & GetPassword() const { return m_password; }
474
478 void SetPassword(const PString & password) { m_password = password; }
479
483 const PCaselessString & GetCommentCommand() const { return m_commentCommand; }
484
488 void SetCommentCommand(const PCaselessString & commentCommand) { m_commentCommand = commentCommand; }
489
493 const PCaselessString & GetExitCommand() const { return m_exitCommand; }
494
498 void SetExitCommand(const PCaselessString & exitCommand) { m_exitCommand = exitCommand; }
499
503 const PCaselessString & GetHelpCommand() const { return m_helpCommand; }
504
508 void SetHelpCommand(const PCaselessString & helpCommand) { m_helpCommand = helpCommand; }
509
514 const PString & GetHelpOnHelp() const { return m_helpOnHelp; }
515
520 void SetHelpOnHelp(const PCaselessString & helpOnHelp) { m_helpOnHelp = helpOnHelp; }
521
525 const PCaselessString & GetRepeatCommand() const { return m_repeatCommand; }
526
530 void SetRepeatCommand(const PCaselessString & repeatCommand) { m_repeatCommand = repeatCommand; }
531
535 const PCaselessString & GetHistoryCommand() const { return m_historyCommand; }
536
540 void SetHistoryCommand(const PCaselessString & historyCommand) { m_historyCommand = historyCommand; }
541
545 const PString & GetNoHistoryError() const { return m_noHistoryError; }
546
550 void SetNoHistoryError(const PString & noHistoryError) { m_noHistoryError = noHistoryError; }
551
555 const PString & GetCommandUsagePrefix() const { return m_commandUsagePrefix; }
556
560 void SetCommandUsagePrefix(const PString & commandUsagePrefix) { m_commandUsagePrefix = commandUsagePrefix; }
561
565 const PString & GetCommandErrorPrefix() const { return m_commandErrorPrefix; }
566
570 void SetCommandErrorPrefix(const PString & commandErrorPrefix) { m_commandErrorPrefix = commandErrorPrefix; }
571
575 const PString & GetUnknownCommandError() const { return m_unknownCommandError; }
576
580 void SetUnknownCommandError(const PString & unknownCommandError) { m_unknownCommandError = unknownCommandError; }
582
583
584 protected:
585 PString m_newLine;
586 bool m_requireEcho;
587 PString m_editCharacters;
588 PString m_prompt;
589 PString m_usernamePrompt;
590 PString m_passwordPrompt;
591 PString m_username;
592 PString m_password;
593 PCaselessString m_commentCommand;
594 PCaselessString m_exitCommand;
595 PCaselessString m_helpCommand;
596 PString m_helpOnHelp;
597 PCaselessString m_repeatCommand;
598 PCaselessString m_historyCommand;
599 PString m_noHistoryError;
600 PString m_commandUsagePrefix;
601 PString m_commandErrorPrefix;
602 PString m_unknownCommandError;
603
604 struct InternalCommand {
605 PNotifier m_notifier;
606 PString m_help;
607 PString m_usage;
608 PString m_argSpec;
609 };
610 typedef std::map<PString, InternalCommand> CommandMap_t;
611 CommandMap_t m_commands;
612
613 typedef std::list<Context *> ContextList_t;
614 ContextList_t m_contextList;
615 PMutex m_contextMutex;
616 };
617
618
621 class PCLIStandard : public PCLI
622 {
623 public:
628 PCLIStandard(
629 const char * prompt = NULL
630 );
632
638 virtual Context * StartForeground();
640
646 bool RunScript(
647 PChannel & channel
648 ) { return RunScript(&channel, false); }
649 bool RunScript(
650 PChannel * channel,
651 bool autoDelete = true
652 );
654 };
655
656
661 class PCLISocket : public PCLI
662 {
663 public:
666 PCLISocket(
667 WORD port = 0,
668 const char * prompt = NULL,
669 bool singleThreadForAll = false
670 );
671 ~PCLISocket();
673
680 virtual bool Start(
681 bool runInBackground = true
682 );
683
691 virtual void Stop();
692
696 virtual Context * AddContext(
697 Context * context = NULL
698 );
699
703 virtual void RemoveContext(
704 Context * context
705 );
707
712 bool Listen(
713 WORD port = 0
714 );
715
718 WORD GetPort() const { return m_listenSocket.GetPort(); }
720
721 protected:
722 PDECLARE_NOTIFIER(PThread, PCLISocket, ThreadMain);
723 bool HandleSingleThreadForAll();
724 bool HandleIncoming();
725 virtual PTCPSocket * CreateSocket();
726
727 bool m_singleThreadForAll;
728
729 PTCPSocket m_listenSocket;
730 PThread * m_thread;
731
732 typedef std::map<PSocket *, Context *> ContextMap_t;
733 ContextMap_t m_contextBySocket;
734 };
735
736
737 #if P_TELNET
738
742 class PCLITelnet : public PCLISocket
743 {
744 public:
747 PCLITelnet(
748 WORD port = 0,
749 const char * prompt = NULL,
750 bool singleThreadForAll = false
751 );
753
754 protected:
755 virtual PTCPSocket * CreateSocket();
756 };
757 #endif // P_TELNET
758
759 #endif // P_CLI
760
761 #endif // PTLIB_CLI_H
762
763
764 // End Of File ///////////////////////////////////////////////////////////////