e5d7136a0177f56aa52deb2f3750c1d16b300db3
[senf.git] / senf / Utils / Console / Executor.hh
1 // $Id$
2 //
3 // Copyright (C) 2008
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \file
24     \brief Executor public header */
25
26 #ifndef HH_SENF_Scheduler_Console_Executor_
27 #define HH_SENF_Scheduler_Console_Executor_ 1
28
29 // Custom includes
30 #include <boost/utility.hpp>
31 #include "Parse.hh"
32 #include <senf/Utils/Logger/SenfLog.hh>
33 #include "Node.hh"
34
35 //#include "Executor.mpp"
36 ///////////////////////////////hh.p////////////////////////////////////////
37
38 namespace senf {
39 namespace console {
40
41     /** \brief Execute config/console commands
42
43         The Executor interprets parsed config/console commands and executes them. It manages the
44         current execution context (current directory, directory stack and so on).
45
46         The executor is normally called directly by the parser callback for each command.
47
48         Executing the built-in 'exit' command will throw Executor::ExitException. This exception
49         (which is not derived from std::exception since it's not a real exception) must be handled
50         by the caller.
51
52         All directories are managed using weak pointers. If any of the directories expires (current
53         directory, directory stack, last directory) it will be replaced with the root
54         directory. Directories expire when they are destructed or when they are detached from the
55         config tree root node.
56       */
57     class Executor
58         : boost::noncopyable
59     {
60         SENF_LOG_CLASS_AREA();
61         SENF_LOG_DEFAULT_LEVEL( senf::log::VERBOSE );
62     public:
63         ///////////////////////////////////////////////////////////////////////////
64         // Types
65
66         /// Thrown by built-in 'exit' command
67         struct ExitException {};
68
69         /// Executor policy function
70         typedef boost::function<void (DirectoryNode &,std::string const &)> SecurityPolicy;
71
72         /// Thrown by the SecurityPolicy to silently ignore a command
73         struct IgnoreCommandException {};
74
75         typedef void result_type;
76
77         ///////////////////////////////////////////////////////////////////////////
78         //\/name Structors and default members
79         ///\{
80
81         Executor();
82
83         ///\}
84         ///////////////////////////////////////////////////////////////////////////
85
86         void execute(std::ostream & output, ParseCommandInfo const & command);
87                                         ///< Execute command
88                                         /**< Output will be written to \a output.
89                                              Same as operator()(). */
90
91         void operator()(std::ostream & output, ParseCommandInfo const & command);
92                                         ///< Execute command
93                                         /**< Output will be written to \a output.
94                                              Same as execute(). */
95         GenericNode & getNode(ParseCommandInfo const & command);
96         DirectoryNode & cwd() const;    ///< Current working directory
97         void cwd(DirectoryNode & dir);  ///< Change current directory
98         std::string cwdPath() const;    ///< Return pathname of current directory
99         bool skipping() const;          ///< \c true, if currently skipping a directory group
100
101         bool autocd() const;            ///< Get current autocd status
102                                         /**< if autocd is enabled, specifying a directory name as
103                                              command will cd to that directory. Disabled by
104                                              default (but enabled automatically by the interactive
105                                              console). */
106         Executor & autocd(bool v);      ///< Set autocd status
107                                         /**< \see autocd() */
108
109         bool autocomplete() const;      ///< Get current autocomplete status
110                                         /**< if autocomplete is enabled, path components which can
111                                              be uniquely completed will be completed
112                                              automatically. Disabled by default (but enabled
113                                              automatically by the interactive console). */
114
115         Executor & autocomplete(bool v); ///< Set autocomplete status
116                                         /**< \see autocomplete() */
117
118
119         DirectoryNode & chroot() const; ///< Get root node
120                                         /**< The root node defaults to senf::console::root(). If
121                                              changed, all path references are relative to this node
122                                              and objects outside that tree cannot be accessed. */
123
124         Executor & chroot(DirectoryNode & node); ///< chroot into given directory
125                                         /**< After this call, all path's are interpreted relative to
126                                              \a node and only nodes in the tree rooted at \a node
127                                              are accessible via the executor. This value defaults to
128                                              senf::console::root(). */
129
130         Executor & policy(SecurityPolicy policy = SecurityPolicy()); ///< Set security policy
131                                         /**< The security policy is called before traversing a node
132                                              to validate that access. */
133
134     protected:
135
136     private:
137         typedef std::vector<DirectoryNode::weak_ptr> Path;
138
139         void exec(std::ostream & output, ParseCommandInfo const & command);
140
141         void cd(ParseCommandInfo::TokensRange dir);
142         void ls(std::ostream & output, ParseCommandInfo::TokensRange dir);
143         void ll(std::ostream & output, ParseCommandInfo::TokensRange dir);
144         void lr(std::ostream & output, ParseCommandInfo::TokensRange dir);
145         void pushd(ParseCommandInfo::TokensRange dir);
146         void popd();
147         void exit();
148         void help(std::ostream & output, ParseCommandInfo::TokensRange path);
149
150         GenericNode & traverseNode(ParseCommandInfo::TokensRange const & path);
151         void traverseDirectory(ParseCommandInfo::TokensRange const & path,
152                                Path & dir);
153         std::string complete(DirectoryNode & dir, std::string const & name);
154
155         struct InvalidPathException {
156             std::string path;
157             InvalidPathException() : path() {}
158             InvalidPathException(std::string path_) : path(path_) {}
159
160         };
161         struct InvalidDirectoryException {
162             std::string path;
163             InvalidDirectoryException() : path() {}
164             InvalidDirectoryException(std::string path_) : path(path_) {}
165         };
166         struct InvalidCommandException {};
167
168         DirectoryNode::ptr root_;
169         SecurityPolicy policy_;
170         mutable Path cwd_;
171         Path oldCwd_;
172
173         typedef std::vector<Path> DirStack;
174         DirStack dirstack_;
175
176         bool autocd_;
177         bool autocomplete_;
178     };
179
180     void senf_console_format_value(DirectoryNode::ptr value, std::ostream & os);
181
182 }}
183
184 ///////////////////////////////hh.e////////////////////////////////////////
185 #include "Executor.cci"
186 //#include "Executor.ct"
187 //#include "Executor.cti"
188 #endif
189
190 \f
191 // Local Variables:
192 // mode: c++
193 // fill-column: 100
194 // comment-column: 40
195 // c-file-style: "senf"
196 // indent-tabs-mode: nil
197 // ispell-local-dictionary: "american"
198 // compile-command: "scons -u test"
199 // End: