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.
22 #include <Generator/iGenerator>
23 #include <Storage/iStorage>
25 #include <Common/Globals>
26 #include <Common/iLogger>
27 #include <Common/iRegistry>
28 #include <Common/iEventQueue>
29 #include <Common/iApp>
30 #include <Common/Event>
31 #include <Common/Util>
35 #if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
43 VER_EXPORT_VERSION_INFO()
46 //-------------------------------------------------------------------
49 using namespace eVaf::PswGen::CLI
;
51 int const Module::DefaultPasswordLength
= 16;
60 setObjectName(QString("%1-Module").arg(VER_MODULE_NAME_STR
));
61 EVAF_INFO("%s created", qPrintable(objectName()));
66 EVAF_INFO("%s destroyed", qPrintable(objectName()));
69 bool Module::init(QString
const & args
)
73 // Get the iGenerator interface
74 EVAF_TEST_X((mGenerator
= evafQueryInterface
<PswGen::iGenerator
>("iGenerator")), "No iGenerator interface");
76 // Get the optional iStorage interface
77 mStorage
= evafQueryInterface
<PswGen::iStorage
>("iStorage");
79 EVAF_WARNING("No iStorage interface");
81 // Get the iEventQueue interface and subscribe to the 'ready' event
82 Common::iEventQueue
* eventQueue
= evafQueryInterface
<Common::iEventQueue
>("iEventQueue");
83 EVAF_TEST_X(eventQueue
, "No iEventQueue interface");
85 // Subscribe to the 'ready' event
86 EVAF_TEST_X((mEvReady
= eventQueue
->subscribeEvent(eventQueue
->queryEvent(Common::iApp::EV_READY
), this)), "No 'ready' event");
90 EVAF_INFO("%s initialized", qPrintable(objectName()));
99 EVAF_INFO("%s finalized", qPrintable(objectName()));
102 bool Module::event(QEvent
* e
)
104 if (e
->type() == Common::Event::eVafEvent
) {
105 Common::Event
* event
= static_cast<Common::Event
*>(e
);
107 if (event
->id() == mEvReady
) {
109 // Generate the password
112 // Quit the application
113 Common::iApp::instance()->quit();
119 return Plugins::iPlugin::event(e
);
122 QString
Module::readPassword()
125 #if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
127 tcgetattr(STDIN_FILENO
, &oldt
);
129 newt
.c_lflag
&= ~ECHO
;
130 tcsetattr(STDIN_FILENO
, TCSANOW
, &newt
);
132 #elif defined Q_OS_WIN32
133 HANDLE hStdin
= GetStdHandle(STD_INPUT_HANDLE
);
135 GetConsoleMode(hStdin
, &mode
);
136 SetConsoleMode(hStdin
, mode
& (~ENABLE_ECHO_INPUT
));
140 QTextStream
cin(stdin
);
141 QString rval
= cin
.readLine();
144 QTextStream
cout(stdout
);
148 #if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
149 tcsetattr(STDIN_FILENO
, TCSANOW
, &oldt
);
150 #elif defined Q_OS_WIN32
151 SetConsoleMode(hStdin
, mode
);
157 void Module::generatePassword()
159 QString masterPassword
;
162 int passwordLength
= 0;
166 // Process command-line arguments
167 QStringList args
= QCoreApplication::arguments();
168 for (int i
= 0; i
< args
.size(); ++i
) {
169 QStringList arg
= args
.at(i
).simplified().split('=');
171 if (QRegExp("-[-]?p(assword)?").exactMatch(arg
.at(0)) && arg
.size() > 1)
172 masterPassword
= arg
.at(1);
173 else if (QRegExp("-[-]?n(ame)?").exactMatch(arg
.at(0)) && arg
.size() > 1)
175 else if (QRegExp("-[-]?s(uffix)?").exactMatch(arg
.at(0)) && arg
.size() > 1)
177 else if (QRegExp("-[-]?a(lphanumeric)?").exactMatch(arg
.at(0))) {
178 if (arg
.size() > 1) {
179 if (Common::isTrue(arg
.at(1)))
181 else if (Common::isFalse(arg
.at(1)))
187 else if (QRegExp("-[-]?l(ength)?").exactMatch(arg
.at(0)) && arg
.size() > 1) {
189 int t
= arg
.at(1).toInt(&ok
);
191 EVAF_FATAL_ERROR("Invalid argument : %s", qPrintable(args
.at(i
)));
201 flags
|= uint(iGenerator::ALPHANUMERIC
);
203 flags
&= ~uint(iGenerator::ALPHANUMERIC
);
206 QTextStream
cin(stdin
);
207 QTextStream
cout(stdout
);
209 // Get missing arguments
210 while (masterPassword
.isEmpty()) {
211 cout
<< tr("Master password : ") << flush
;
212 masterPassword
= readPassword();
215 while (appName
.isEmpty()) {
216 cout
<< tr("Application name : ") << flush
;
220 // Get more arguments from the storage
221 QExplicitlySharedDataPointer
<PswGen::Storage::Data
> data
;
223 data
= mStorage
->query(appName
);
225 if (passwordLength
== 0)
226 passwordLength
= data
->length();
227 if (suffix
.isEmpty())
228 suffix
= data
->suffix();
230 flags
= data
->flags();
234 // If the length argument is still not initialized, use the default length value
236 passwordLength
= DefaultPasswordLength
;
239 QString password
= mGenerator
->generatePassword(appName
+ suffix
, masterPassword
, passwordLength
);
240 cout
<< "Generated password : " << password
<< endl
;
242 // Store arguments for this password
245 data
= new Storage::Data(appName
, suffix
, passwordLength
);
247 data
->setSuffix(suffix
);
248 data
->setLength(passwordLength
);
250 mStorage
->save(appName
, data
);