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