Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : */
8 :
9 : #include <backends.hpp>
10 :
11 : #include <algorithm>
12 : #include <iostream>
13 :
14 : namespace kdb
15 : {
16 :
17 : namespace tools
18 : {
19 :
20 : /**
21 : * @brief give info about current mounted backends
22 : *
23 : * @param mountConf a keyset that contains everything below
24 : * Backends::mountpointsPath
25 : *
26 : * @return an vector of information about mounted backends
27 : */
28 1658 : Backends::BackendInfoVector Backends::getBackendInfo (KeySet mountConf)
29 : {
30 1658 : std::vector<BackendInfo> ret;
31 3316 : Key rootKey (Backends::mountpointsPath, KEY_END);
32 3316 : Key cur;
33 :
34 : mountConf.rewind ();
35 35764 : while ((cur = mountConf.next ()))
36 : {
37 7283 : if (cur.isDirectBelow (rootKey))
38 : {
39 1994 : BackendInfo bi;
40 :
41 4985 : Key path = mountConf.lookup (cur.getName () + "/config/path");
42 997 : if (path)
43 : {
44 1962 : bi.path = path.getString ();
45 : }
46 4985 : Key mp = mountConf.lookup (cur.getName () + "/mountpoint");
47 997 : if (mp)
48 : {
49 1994 : bi.mountpoint = mp.getString ();
50 : }
51 1994 : bi.name = cur.getBaseName ();
52 :
53 997 : ret.push_back (bi);
54 : }
55 : }
56 1658 : return ret;
57 : }
58 :
59 : /**
60 : * @brief Find a backend in the given name
61 : *
62 : * @param mountPath the given backend name to find
63 : *
64 : * For backwards compatibility old-style names containing _ instead of escaped /
65 : * are accepted if no modern-style mountpoint is found.
66 : *
67 : * @param mountConf the configuration to search (should contain keys
68 : * below mountpointsPath to find something)
69 : *
70 : * @return the found backend or an empty BackendInfo if nothing found
71 : * (with empty strings)
72 : */
73 548 : BackendInfo Backends::findBackend (std::string const & mountPath, KeySet mountConf, bool verbose)
74 : {
75 1096 : BackendInfo ret;
76 548 : if (mountPath.empty ()) return ret;
77 :
78 1644 : Backends::BackendInfoVector mtab = Backends::getBackendInfo (mountConf);
79 :
80 2192 : Key kmp (Backends::getBasePath (mountPath), KEY_END);
81 :
82 : // search for proper mountname:
83 2620 : for (Backends::BackendInfoVector::const_iterator it = mtab.begin (); it != mtab.end (); ++it)
84 : {
85 739 : if (verbose) std::cout << "compare: " << it->mountpoint << " with " << kmp.getBaseName () << std::endl;
86 1478 : if (it->mountpoint == kmp.getBaseName ())
87 : {
88 525 : return *it;
89 : }
90 : };
91 :
92 : // fall back to compatibility pre 0.8.11 mountnames
93 : // May umount wrong things, so its done as extra step so that
94 : // it will never happen if something desired is present.
95 23 : std::string soldMountpoint = mountPath;
96 92 : std::replace (soldMountpoint.begin (), soldMountpoint.end (), '_', '/');
97 69 : Key koldMountpoint ("user/" + soldMountpoint, KEY_END);
98 46 : std::string omp = koldMountpoint.getName ();
99 184 : std::string oldMountpoint (omp.begin () + 4, omp.end ());
100 23 : if (soldMountpoint.at (0) != '/') oldMountpoint.erase (0, 1); // fix non-cascading
101 69 : if (koldMountpoint.getName () == "user") oldMountpoint = "/"; // fix root
102 130 : for (Backends::BackendInfoVector::const_iterator it = mtab.begin (); it != mtab.end (); ++it)
103 : {
104 31 : if (verbose) std::cout << "fallback compare: " << it->mountpoint << " with " << oldMountpoint << std::endl;
105 31 : if (it->mountpoint == oldMountpoint)
106 : {
107 12 : return *it;
108 : }
109 : }
110 11 : return ret;
111 : }
112 :
113 : /**
114 : * @brief Unmount a backend by given mountPath
115 : *
116 : * @param mountPath the given mountpoint
117 : *
118 : * Uses findBackend() to locate the backend.
119 : *
120 : * @retval true if something was done
121 : * @retval false if nothing was done (but also no error)
122 : */
123 547 : bool Backends::umount (std::string const & mountPath, KeySet & mountConf)
124 : {
125 1641 : BackendInfo bi = Backends::findBackend (mountPath, mountConf);
126 547 : if (!bi.name.empty ())
127 : {
128 1072 : Key x (Backends::mountpointsPath, KEY_END);
129 : ;
130 536 : x.addBaseName (bi.name);
131 2144 : mountConf.cut (x);
132 536 : return true;
133 : }
134 :
135 : return false;
136 : }
137 :
138 : /**
139 : * @brief returns the base path of a mounted backend
140 : * below system/elektra/mountpoints
141 : *
142 : * @param mp the mountpoint (name will be derived from it)
143 : *
144 : * @return the properly prefixed and escaped name
145 : */
146 1149 : std::string Backends::getBasePath (std::string mp)
147 : {
148 2298 : Key k (Backends::mountpointsPath, KEY_END);
149 3447 : Key kmp (mp, KEY_CASCADING_NAME, KEY_END); // canonify name
150 2298 : k.addBaseName (kmp.getName ()); // escape name
151 2298 : return k.getName ();
152 : }
153 :
154 : /**
155 : * @brief Below this path is the mountConf
156 : */
157 : const char * Backends::mountpointsPath = "system/elektra/mountpoints";
158 : } // namespace tools
159 7272 : } // namespace kdb
|