moved statistics classes from NetEmu to SENF
[senf.git] / Utils / Console / Config.cc
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 Config non-inline non-template implementation */
25
26 #include "Config.hh"
27 #include "Config.ih"
28
29 // Custom includes
30 #include "../../Utils/membind.hh"
31
32 //#include "Config.mpp"
33 #define prefix_
34 ///////////////////////////////cc.p////////////////////////////////////////
35
36 ///////////////////////////////////////////////////////////////////////////
37 // senf::console::detail::RestrictedExecutor
38
39 prefix_ senf::console::detail::RestrictedExecutor::RestrictedExecutor(DirectoryNode & root)
40 {
41     executor_
42         .chroot(root)
43         .policy(senf::membind(&RestrictedExecutor::policyCallback, this));
44 }
45
46 prefix_ void
47 senf::console::detail::RestrictedExecutor::execute(std::ostream & output,
48                                                    ParseCommandInfo const & command)
49 {
50     executor_.execute(output, command);
51 }
52
53 prefix_ void
54 senf::console::detail::RestrictedExecutor::operator()(std::ostream & output,
55                                                       ParseCommandInfo const & command)
56 {
57     execute(output, command);
58 }
59
60 prefix_ bool senf::console::detail::RestrictedExecutor::parsed(GenericNode & node)
61     const
62 {
63     ParsedNodes::const_iterator i (parsedNodes_.begin());
64     ParsedNodes::const_iterator const i_end (parsedNodes_.end());
65     for (; i != i_end; ++i)
66         if ( ! i->expired() && node.isChildOf(*(i->lock())) )
67             return true;
68     return false;
69 }
70
71 prefix_ void senf::console::detail::RestrictedExecutor::policyCallback(DirectoryNode & dir,
72                                                                        std::string const & name)
73 {
74     if (dir.hasChild(name)) {
75         GenericNode & item (dir.get(name));
76         if (restrict_ && ! item.isChildOf(*restrict_) && ! item.isDirectory())
77             throw Executor::IgnoreCommandException();
78         if (parsed(item))
79             throw Executor::IgnoreCommandException();
80     }
81     else if (restrict_ && ! dir.isChildOf(*restrict_))
82         throw Executor::IgnoreCommandException();
83 }
84
85 namespace {
86     struct RemoveNodesFn
87     {
88         RemoveNodesFn(senf::console::DirectoryNode::ptr newNode) : newNode_ (newNode) {}
89
90         bool operator()(senf::console::DirectoryNode::weak_ptr node) const
91             { return node.expired() || node.lock()->isChildOf(*newNode_); }
92
93         senf::console::DirectoryNode::ptr newNode_;
94     };
95 }
96
97 prefix_ void
98 senf::console::detail::RestrictedExecutor::insertParsedNode(DirectoryNode & node)
99 {
100     parsedNodes_.erase(
101         std::remove_if(parsedNodes_.begin(), parsedNodes_.end(), RemoveNodesFn(node.thisptr())),
102         parsedNodes_.end());
103     parsedNodes_.push_back(node.thisptr());
104 }
105
106 ///////////////////////////////////////////////////////////////////////////
107 // senf::console::ConfigBundle
108
109 prefix_ void senf::console::ConfigBundle::parse()
110 {
111     detail::RestrictedExecutor::RestrictGuard guard (executor_);
112     parseInternal();
113 }
114
115 prefix_ void senf::console::ConfigBundle::parse(DirectoryNode & restrict)
116 {
117     detail::RestrictedExecutor::RestrictGuard guard (executor_, restrict);
118     parseInternal();
119 }
120
121 prefix_ void senf::console::ConfigBundle::parseInternal()
122 {
123     // It is valid to add additional sources at the end while parsing ...
124     for (Sources::const_iterator i (sources_.begin()); i != sources_.end(); ++i)
125         (*i)->parse(executor_);
126 }
127
128 ///////////////////////////////////////////////////////////////////////////
129 // senf::console::detail::RestrictedExecutor::RestrictGuard
130
131 prefix_ senf::console::detail::RestrictedExecutor::RestrictGuard::
132 RestrictGuard(RestrictedExecutor & executor)
133     : executor_ (executor)
134 {
135     // This MUST BE root() not chroot() since restriction does NOT follow symlinks.
136     // Therefore, if chroot() is a directory of symlinks, restricting to it will
137     // execute NOTHING.
138     executor_.restrict_ = senf::console::root().thisptr();
139 }
140
141 prefix_ senf::console::detail::RestrictedExecutor::RestrictGuard::
142 RestrictGuard(RestrictedExecutor & executor, DirectoryNode & restrict)
143     : executor_ (executor)
144 {
145     executor_.restrict_ = restrict.thisptr();
146 }
147
148 prefix_ senf::console::detail::RestrictedExecutor::RestrictGuard::~RestrictGuard()
149 {
150     if (! std::uncaught_exception())
151         executor_.insertParsedNode( *executor_.restrict_ );
152     executor_.restrict_ = senf::console::root().thisptr();
153 }
154
155 ///////////////////////////////////////////////////////////////////////////
156 // senf::console::detail::ConfigSource
157
158 prefix_ senf::console::detail::ConfigSource::~ConfigSource()
159 {}
160
161 ///////////////////////////////cc.e////////////////////////////////////////
162 #undef prefix_
163 //#include "Config.mpp"
164
165 \f
166 // Local Variables:
167 // mode: c++
168 // fill-column: 100
169 // comment-column: 40
170 // c-file-style: "senf"
171 // indent-tabs-mode: nil
172 // ispell-local-dictionary: "american"
173 // compile-command: "scons -u test"
174 // End: