]> vaikene.ee Git - evaf/blob - src/apps/PswGen/CLI/cli.cpp
Fixed small mistakes detected with clang++
[evaf] / src / apps / PswGen / CLI / cli.cpp
1 /**
2 * @file PswGen/CLI/cli.cpp
3 * @brief Command line interface for the PswGen application
4 * @author Enar Vaikene
5 *
6 * Copyright (c) 2011 Enar Vaikene
7 *
8 * This file is part of the eVaf C++ cross-platform application development framework.
9 *
10 * This file can be used under the terms of the GNU General Public License
11 * version 3.0 as published by the Free Software Foundation and appearing in
12 * the file LICENSE included in the packaging of this file. Please review the
13 * the following information to ensure the GNU General Public License version
14 * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
15 *
16 * Alternatively, this file may be used in accordance with the Commercial License
17 * Agreement provided with the Software.
18 */
19
20 #include "cli.h"
21 #include "version.h"
22
23 #include <Generator/iGenerator>
24 #include <Storage/iStorage>
25
26 #include <Common/Globals>
27 #include <Common/iLogger>
28 #include <Common/iRegistry>
29 #include <Common/iEventQueue>
30 #include <Common/iApp>
31 #include <Common/Event>
32
33 #include <QtCore>
34
35 #ifdef Q_OS_LINUX
36 # include <termios.h>
37 # include <unistd.h>
38 #endif
39 #ifdef Q_OS_WIN32
40 # include <windows.h>
41 #endif
42
43 VER_EXPORT_VERSION_INFO()
44 Q_EXPORT_PLUGIN2(VER_MODULE_NAME_STR, eVaf::PswGen::CLI::Module)
45
46
47 //-------------------------------------------------------------------
48
49 using namespace eVaf;
50 using namespace eVaf::PswGen::CLI;
51
52 int const Module::DefaultPasswordLength = 16;
53
54 Module::Module()
55 : Plugins::iPlugin()
56 , mReady(false)
57 , mGenerator(0)
58 , mStorage(0)
59 , mEvReady(0)
60 {
61 setObjectName(QString("%1-Module").arg(VER_MODULE_NAME_STR));
62 EVAF_INFO("%s created", qPrintable(objectName()));
63 }
64
65 Module::~Module()
66 {
67 EVAF_INFO("%s destroyed", qPrintable(objectName()));
68 }
69
70 bool Module::init(QString const & args)
71 {
72 Q_UNUSED(args);
73
74 // Get the iGenerator interface
75 EVAF_TEST_X((mGenerator = evafQueryInterface<PswGen::iGenerator>("iGenerator")), "No iGenerator interface");
76
77 // Get the optional iStorage interface
78 mStorage = evafQueryInterface<PswGen::iStorage>("iStorage");
79 if (!mStorage)
80 EVAF_WARNING("No iStorage interface");
81
82 // Get the iEventQueue interface and subscribe to the 'ready' event
83 Common::iEventQueue * eventQueue = evafQueryInterface<Common::iEventQueue>("iEventQueue");
84 EVAF_TEST_X(eventQueue, "No iEventQueue interface");
85
86 // Subscribe to the 'ready' event
87 EVAF_TEST_X((mEvReady = eventQueue->subscribeEvent(eventQueue->queryEvent(Common::iApp::EV_READY), this)), "No 'ready' event");
88
89 mReady = true;
90
91 EVAF_INFO("%s initialized", qPrintable(objectName()));
92
93 return true;
94 }
95
96 void Module::done()
97 {
98 mReady = false;
99
100 EVAF_INFO("%s finalized", qPrintable(objectName()));
101 }
102
103 bool Module::event(QEvent * e)
104 {
105 if (e->type() == Common::Event::eVafEvent) {
106 Common::Event * event = static_cast<Common::Event *>(e);
107
108 if (event->id() == mEvReady) {
109
110 // Generate the password
111 generatePassword();
112
113 // Quit the application
114 Common::iApp::instance()->quit();
115 }
116
117 return false;
118 }
119 else
120 return Plugins::iPlugin::event(e);
121 }
122
123 QString Module::readPassword()
124 {
125 bool noEcho = false;
126 #ifdef Q_OS_LINUX
127 termios oldt;
128 tcgetattr(STDIN_FILENO, &oldt);
129 termios newt = oldt;
130 newt.c_lflag &= ~ECHO;
131 tcsetattr(STDIN_FILENO, TCSANOW, &newt);
132 noEcho = true;
133 #elif defined Q_OS_WIN32
134 HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
135 DWORD mode = 0;
136 GetConsoleMode(hStdin, &mode);
137 SetConsoleMode(hStdin, mode & (~ENABLE_ECHO_INPUT));
138 noEcho = true;
139 #endif
140
141 QTextStream cin(stdin);
142 QString rval = cin.readLine();
143
144 if (noEcho) {
145 QTextStream cout(stdout);
146 cout << endl;
147 }
148
149 #ifdef Q_OS_LINUX
150 tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
151 #elif defined Q_OS_WIN32
152 SetConsoleMode(hStdin, mode);
153 #endif
154
155 return rval;
156 }
157
158 void Module::generatePassword()
159 {
160 QString masterPassword;
161 QString appName;
162 int passwordLength = 0;
163
164 // Process command-line arguments
165 QStringList args = QCoreApplication::arguments();
166 for (int i = 0; i < args.size(); ++i) {
167 QStringList arg = args.at(i).simplified().split('=');
168
169 if (QRegExp("-[-]?p(assword)?").exactMatch(arg.at(0)) && arg.size() > 1)
170 masterPassword = arg.at(1);
171 else if (QRegExp("-[-]?n(ame)?").exactMatch(arg.at(0)) && arg.size() > 1)
172 appName = arg.at(1);
173 else if (QRegExp("-[-]?l(ength)?").exactMatch(arg.at(0)) && arg.size() > 1) {
174 bool ok;
175 int t = arg.at(1).toInt(&ok);
176 if (!ok) {
177 EVAF_FATAL_ERROR("Invalid argument : %s", qPrintable(args.at(i)));
178 return;
179 }
180 passwordLength = t;
181 }
182 }
183
184 QTextStream cin(stdin);
185 QTextStream cout(stdout);
186
187 // Get missing arguments
188 while (masterPassword.isEmpty()) {
189 cout << tr("Master password : ") << flush;
190 masterPassword = readPassword();
191 }
192
193 while (appName.isEmpty()) {
194 cout << tr("Application name : ") << flush;
195 cin >> appName;
196 }
197
198 // Get more arguments from the storage
199 QExplicitlySharedDataPointer<PswGen::Storage::Data> data;
200 if (mStorage) {
201 data = mStorage->query(appName);
202 if (data && passwordLength == 0)
203 passwordLength = data->length();
204 }
205
206 // If the length argument is still not initialized, use the default length value
207 if (!passwordLength)
208 passwordLength = DefaultPasswordLength;
209
210 // Generate password
211 QString password = mGenerator->generatePassword(appName, masterPassword, passwordLength);
212 cout << "Generated password : " << password << endl;
213
214 // Store arguments for this password
215 if (mStorage) {
216 if (!data)
217 data = new Storage::Data(appName, passwordLength);
218 else
219 data->setLength(passwordLength);
220 mStorage->save(appName, data);
221 }
222 }