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 <cp.hpp>
10 :
11 : #include <cmdline.hpp>
12 : #include <kdb.hpp>
13 : #include <keysetio.hpp>
14 : #include <rename.hpp>
15 :
16 : #include <iostream>
17 :
18 : using namespace std;
19 : using namespace kdb;
20 :
21 87 : CpCommand::CpCommand ()
22 : {
23 87 : }
24 :
25 : namespace
26 : {
27 17 : void copySingleKey (Cmdline const & cl, Key const & rk, KeySet & tmpConf, KeySet & newConf)
28 : {
29 17 : if (cl.force)
30 : {
31 6 : tmpConf.lookup (rk, KDB_O_POP);
32 : }
33 : else
34 : {
35 28 : Key key = tmpConf.lookup (rk);
36 42 : if (key != nullptr)
37 : {
38 16 : if (key.getString () != rk.getString ())
39 : {
40 4 : throw CommandAbortException (std::string ("Copy will not be done, because " + rk.getName () +
41 : " already exists and has a different value"
42 : ", use -f to force copy"),
43 3 : 11);
44 : }
45 : }
46 : }
47 16 : newConf.append (rk);
48 16 : }
49 : } // namespace
50 :
51 9 : int CpCommand::execute (Cmdline const & cl)
52 : {
53 18 : if (cl.arguments.size () != 2)
54 : {
55 0 : throw invalid_argument ("wrong number of arguments, 2 needed");
56 : }
57 :
58 18 : KeySet conf;
59 18 : Key sourceKey = cl.createKey (0, false);
60 :
61 18 : Key destKey = cl.createKey (1, false);
62 :
63 18 : string newDirName = destKey.getName ();
64 :
65 9 : kdb.get (conf, sourceKey);
66 9 : kdb.get (conf, destKey);
67 18 : KeySet tmpConf = conf;
68 18 : KeySet oldConf;
69 :
70 18 : std::string sourceName = sourceKey.getName ();
71 45 : oldConf.append (tmpConf.cut (sourceKey));
72 :
73 9 : if (!oldConf.size ())
74 : {
75 0 : std::cerr << "No key to copy found below '" << sourceName << "'" << std::endl;
76 : return 11;
77 : }
78 :
79 11 : KeySet newConf;
80 :
81 9 : oldConf.rewind ();
82 9 : if (cl.verbose) cout << "common name: " << sourceName << endl;
83 9 : if (cl.recursive)
84 : {
85 : // copy all keys with new name
86 5 : Key k;
87 80 : while ((k = oldConf.next ()))
88 : {
89 26 : Key rk = rename_key (k, sourceName, newDirName, cl.verbose);
90 13 : copySingleKey (cl, rk, tmpConf, newConf);
91 : }
92 : }
93 : else
94 : {
95 : // just copy one key
96 8 : Key k = oldConf.next ();
97 4 : if (k != sourceKey)
98 : {
99 0 : cerr << "First key found " << k.getName () << " does not exactly match given key " << sourceKey.getName ()
100 0 : << ", aborting (use -r to move hierarchy)\n";
101 0 : return 11;
102 : }
103 8 : Key rk = rename_key (k, sourceName, newDirName, cl.verbose);
104 4 : copySingleKey (cl, rk, tmpConf, newConf);
105 : }
106 :
107 8 : newConf.append (tmpConf); // these are unrelated keys
108 8 : newConf.append (oldConf); // these are the original keys
109 :
110 8 : newConf.rewind ();
111 8 : kdb.set (newConf, destKey);
112 :
113 : return 0;
114 : }
115 :
116 174 : CpCommand::~CpCommand ()
117 : {
118 7251 : }
|