Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief source file of spec mount command
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : *
8 : */
9 :
10 :
11 : #include <cmdline.hpp>
12 : #include <globalmount.hpp>
13 : #include <specreader.hpp>
14 :
15 : #include <fstream>
16 : #include <iostream>
17 : #include <iterator>
18 : #include <string>
19 : #include <vector>
20 :
21 : using namespace std;
22 : using namespace kdb;
23 : using namespace kdb::tools;
24 :
25 161 : GlobalMountCommand::GlobalMountCommand ()
26 : {
27 161 : }
28 :
29 5 : std::vector<std::string> GlobalMountCommand::getMtab ()
30 : {
31 5 : std::vector<std::string> ret;
32 10 : Key globalPluginsKey ("system/elektra/globalplugins/postcommit/user/plugins", KEY_END);
33 :
34 10 : mountConf.rewind ();
35 10 : Key currentPluginConfig ("proc/notbelow", KEY_END);
36 285 : for (auto const & key : mountConf)
37 : {
38 90 : if (key.isDirectBelow (globalPluginsKey))
39 : {
40 9 : ret.push_back (key.getString ());
41 6 : currentPluginConfig = key.dup ();
42 12 : currentPluginConfig.addBaseName ("config");
43 : }
44 87 : else if (key.isBelow (currentPluginConfig))
45 : {
46 0 : ret.push_back (key.getName ().substr (currentPluginConfig.getName ().size () + 1) + "=" + key.getString ());
47 : }
48 : }
49 5 : return ret;
50 : }
51 :
52 :
53 3 : void GlobalMountCommand::outputMtab (Cmdline const &)
54 : {
55 3 : bool first = true;
56 6 : auto const & mtab = getMtab ();
57 15 : for (auto const & mtabEntry : mtab)
58 : {
59 3 : if (mtabEntry.find ('=') != std::string::npos)
60 : {
61 0 : std::cout << " ";
62 : }
63 3 : else if (!first)
64 : {
65 1 : std::cout << "\n";
66 : }
67 3 : std::cout << mtabEntry;
68 3 : first = false;
69 : }
70 3 : if (!first) std::cout << endl;
71 3 : }
72 :
73 : namespace
74 : {
75 2 : void removePlugins (std::vector<std::string> & plugins, std::string globalPlugins)
76 : {
77 4 : std::istringstream iss (globalPlugins);
78 2 : std::string plugin;
79 8 : while (iss >> plugin)
80 : {
81 4 : auto const & it = std::find (plugins.begin (), plugins.end (), plugin);
82 4 : if (it != plugins.end ())
83 : {
84 0 : plugins.erase (it); // remove plugin
85 : // and remove its config:
86 0 : while (it != plugins.end () && it->find ("=") != std::string::npos)
87 : {
88 0 : std::cout << "configs " << *it << std::endl;
89 0 : plugins.erase (it);
90 : }
91 : }
92 : }
93 2 : }
94 : } // namespace
95 :
96 2 : void GlobalMountCommand::buildBackend (Cmdline const & cl)
97 : {
98 4 : GlobalPluginsBuilder backend;
99 :
100 : // TODO: not yet implemented:
101 : // backend.setBackendConfig(cl.getPluginsConfig("system/"));
102 4 : backend.addPlugins (parseArguments (cl.globalPlugins));
103 8 : backend.addPlugins (parseArguments (cl.arguments.begin (), cl.arguments.end ()));
104 :
105 4 : auto mtab = getMtab ();
106 6 : removePlugins (mtab, cl.globalPlugins); // do not readd again
107 6 : backend.addPlugins (parseArguments (mtab.begin (), mtab.end ()));
108 :
109 : // Call it a day
110 2 : outputMissingRecommends (backend.resolveNeeds (cl.withRecommends));
111 8 : mountConf.cut (Key (GlobalPluginsBuilder::globalPluginsPath, KEY_END));
112 2 : backend.serialize (mountConf);
113 2 : }
114 :
115 : /**
116 : * @brief Its quite linear whats going on, but there are many steps involved
117 : *
118 : * @param cl the commandline
119 : *
120 : * @retval 0 on success (otherwise exception)
121 : */
122 5 : int GlobalMountCommand::execute (Cmdline const & cl)
123 : {
124 10 : mountpointsPath = GlobalPluginsBuilder::globalPluginsPath;
125 5 : readMountConf (cl);
126 :
127 10 : if (!cl.interactive && cl.arguments.empty ())
128 : {
129 : // no interactive mode, so lets output the mtab
130 3 : outputMtab (cl);
131 3 : return 0;
132 : }
133 :
134 :
135 2 : buildBackend (cl);
136 2 : doIt ();
137 :
138 2 : return 0;
139 : }
140 :
141 161 : GlobalMountCommand::~GlobalMountCommand ()
142 : {
143 7325 : }
|