2 * @file PswGen/CLI/cli.cpp
3 * @brief Command line interface for the PswGen application
6 * Copyright (c) 2011-2012 Enar Vaikene
8 * This file is part of the eVaf C++ cross-platform application development framework.
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.
16 * Alternatively, this file may be used in accordance with the Commercial License
17 * Agreement provided with the Software.
23 #include <Generator/iGenerator>
24 #include <Storage/iStorage>
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 #include <Common/Util>
44 VER_EXPORT_VERSION_INFO()
45 Q_EXPORT_PLUGIN2(VER_MODULE_NAME_STR
, eVaf::PswGen::CLI::Module
)
48 //-------------------------------------------------------------------
51 using namespace eVaf::PswGen::CLI
;
53 int const Module::DefaultPasswordLength
= 16;
62 setObjectName(QString("%1-Module").arg(VER_MODULE_NAME_STR
));
63 EVAF_INFO("%s created", qPrintable(objectName()));
68 EVAF_INFO("%s destroyed", qPrintable(objectName()));
71 bool Module::init(QString
const & args
)
75 // Get the iGenerator interface
76 EVAF_TEST_X((mGenerator
= evafQueryInterface
<PswGen::iGenerator
>("iGenerator")), "No iGenerator interface");
78 // Get the optional iStorage interface
79 mStorage
= evafQueryInterface
<PswGen::iStorage
>("iStorage");
81 EVAF_WARNING("No iStorage interface");
83 // Get the iEventQueue interface and subscribe to the 'ready' event
84 Common::iEventQueue
* eventQueue
= evafQueryInterface
<Common::iEventQueue
>("iEventQueue");
85 EVAF_TEST_X(eventQueue
, "No iEventQueue interface");
87 // Subscribe to the 'ready' event
88 EVAF_TEST_X((mEvReady
= eventQueue
->subscribeEvent(eventQueue
->queryEvent(Common::iApp::EV_READY
), this)), "No 'ready' event");
92 EVAF_INFO("%s initialized", qPrintable(objectName()));
101 EVAF_INFO("%s finalized", qPrintable(objectName()));
104 bool Module::event(QEvent
* e
)
106 if (e
->type() == Common::Event::eVafEvent
) {
107 Common::Event
* event
= static_cast<Common::Event
*>(e
);
109 if (event
->id() == mEvReady
) {
111 // Generate the password
114 // Quit the application
115 Common::iApp::instance()->quit();
121 return Plugins::iPlugin::event(e
);
124 QString
Module::readPassword()
129 tcgetattr(STDIN_FILENO
, &oldt
);
131 newt
.c_lflag
&= ~ECHO
;
132 tcsetattr(STDIN_FILENO
, TCSANOW
, &newt
);
134 #elif defined Q_OS_WIN32
135 HANDLE hStdin
= GetStdHandle(STD_INPUT_HANDLE
);
137 GetConsoleMode(hStdin
, &mode
);
138 SetConsoleMode(hStdin
, mode
& (~ENABLE_ECHO_INPUT
));
142 QTextStream
cin(stdin
);
143 QString rval
= cin
.readLine();
146 QTextStream
cout(stdout
);
151 tcsetattr(STDIN_FILENO
, TCSANOW
, &oldt
);
152 #elif defined Q_OS_WIN32
153 SetConsoleMode(hStdin
, mode
);
159 void Module::generatePassword()
161 QString masterPassword
;
164 int passwordLength
= 0;
168 // Process command-line arguments
169 QStringList args
= QCoreApplication::arguments();
170 for (int i
= 0; i
< args
.size(); ++i
) {
171 QStringList arg
= args
.at(i
).simplified().split('=');
173 if (QRegExp("-[-]?p(assword)?").exactMatch(arg
.at(0)) && arg
.size() > 1)
174 masterPassword
= arg
.at(1);
175 else if (QRegExp("-[-]?n(ame)?").exactMatch(arg
.at(0)) && arg
.size() > 1)
177 else if (QRegExp("-[-]?s(uffix)?").exactMatch(arg
.at(0)) && arg
.size() > 1)
179 else if (QRegExp("-[-]?a(lphanumeric)?").exactMatch(arg
.at(0))) {
180 if (arg
.size() > 1) {
181 if (Common::isTrue(arg
.at(1)))
183 else if (Common::isFalse(arg
.at(1)))
189 else if (QRegExp("-[-]?l(ength)?").exactMatch(arg
.at(0)) && arg
.size() > 1) {
191 int t
= arg
.at(1).toInt(&ok
);
193 EVAF_FATAL_ERROR("Invalid argument : %s", qPrintable(args
.at(i
)));
203 flags
|= uint(iGenerator::ALPHANUMERIC
);
205 flags
&= ~uint(iGenerator::ALPHANUMERIC
);
208 QTextStream
cin(stdin
);
209 QTextStream
cout(stdout
);
211 // Get missing arguments
212 while (masterPassword
.isEmpty()) {
213 cout
<< tr("Master password : ") << flush
;
214 masterPassword
= readPassword();
217 while (appName
.isEmpty()) {
218 cout
<< tr("Application name : ") << flush
;
222 // Get more arguments from the storage
223 QExplicitlySharedDataPointer
<PswGen::Storage::Data
> data
;
225 data
= mStorage
->query(appName
);
227 if (passwordLength
== 0)
228 passwordLength
= data
->length();
229 if (suffix
.isEmpty())
230 suffix
= data
->suffix();
232 flags
= data
->flags();
236 // If the length argument is still not initialized, use the default length value
238 passwordLength
= DefaultPasswordLength
;
241 QString password
= mGenerator
->generatePassword(appName
+ suffix
, masterPassword
, passwordLength
);
242 cout
<< "Generated password : " << password
<< endl
;
244 // Store arguments for this password
247 data
= new Storage::Data(appName
, suffix
, passwordLength
);
249 data
->setSuffix(suffix
);
250 data
->setLength(passwordLength
);
252 mStorage
->save(appName
, data
);