]> vaikene.ee Git - evaf/blobdiff - src/apps/PswGen/CLI/cli.cpp
Added command-line interface module to the PswGen application.
[evaf] / src / apps / PswGen / CLI / cli.cpp
diff --git a/src/apps/PswGen/CLI/cli.cpp b/src/apps/PswGen/CLI/cli.cpp
new file mode 100644 (file)
index 0000000..fbc8450
--- /dev/null
@@ -0,0 +1,216 @@
+/**
+ * @file PswGen/CLI/cli.cpp
+ * @brief Command line interface for the PswGen application
+ * @author Enar Vaikene
+ *
+ * Copyright (c) 2011 Enar Vaikene
+ *
+ * This file is part of the eVaf C++ cross-platform application development framework.
+ *
+ * This file can be used under the terms of the GNU General Public License
+ * version 3.0 as published by the Free Software Foundation and appearing in
+ * the file LICENSE included in the packaging of this file. Please review the
+ * the following information to ensure the GNU General Public License version
+ * 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+ *
+ * Alternatively, this file may be used in accordance with the Commercial License
+ * Agreement provided with the Software.
+ */
+
+#include "cli.h"
+#include "version.h"
+
+#include <Generator/iGenerator>
+#include <Storage/iStorage>
+
+#include <Common/Globals>
+#include <Common/iLogger>
+#include <Common/iRegistry>
+#include <Common/iEventQueue>
+#include <Common/iApp>
+#include <Common/Event>
+
+#include <QtCore>
+
+#ifdef Q_OS_LINUX
+#  include <termios.h>
+#  include <unistd.h>
+#endif
+#ifdef Q_OS_WIN32
+#  include <windows.h>
+#endif
+
+VER_EXPORT_VERSION_INFO()
+Q_EXPORT_PLUGIN2(VER_MODULE_NAME_STR, eVaf::PswGen::CLI::Module)
+
+
+//-------------------------------------------------------------------
+
+using namespace eVaf;
+using namespace eVaf::PswGen::CLI;
+
+int const Module::DefaultPasswordLength = 16;
+
+Module::Module()
+    : Plugins::iPlugin()
+    , mReady(false)
+    , mGenerator(false)
+    , mStorage(false)
+    , mEvReady(0)
+{
+    setObjectName(QString("%1-Module").arg(VER_MODULE_NAME_STR));
+    EVAF_INFO("%s created", qPrintable(objectName()));
+}
+
+Module::~Module()
+{
+    EVAF_INFO("%s destroyed", qPrintable(objectName()));
+}
+
+bool Module::init(QString const & args)
+{
+    Q_UNUSED(args);
+
+    // Get the iGenerator interface
+    EVAF_TEST_X((mGenerator = evafQueryInterface<PswGen::iGenerator>("iGenerator")), "No iGenerator interface");
+
+    // Get the optional iStorage interface
+    mStorage = evafQueryInterface<PswGen::iStorage>("iStorage");
+    if (!mStorage)
+        EVAF_WARNING("No iStorage interface");
+
+    // Get the iEventQueue interface and subscribe to the 'ready' event
+    Common::iEventQueue * eventQueue = evafQueryInterface<Common::iEventQueue>("iEventQueue");
+    EVAF_TEST_X(eventQueue, "No iEventQueue interface");
+
+    // Subscribe to the 'ready' event
+    EVAF_TEST_X((mEvReady = eventQueue->subscribeEvent(eventQueue->queryEvent(Common::iApp::EV_READY), this)), "No 'ready' event");
+
+    mReady = true;
+
+    EVAF_INFO("%s initialized", qPrintable(objectName()));
+
+    return true;
+}
+
+void Module::done()
+{
+    mReady = false;
+
+    EVAF_INFO("%s finalized", qPrintable(objectName()));
+}
+
+bool Module::event(QEvent * e)
+{
+    if (e->type() == Common::Event::eVafEvent) {
+        Common::Event * event = static_cast<Common::Event *>(e);
+
+        if (event->id() == mEvReady) {
+
+            // Generate the password
+            generatePassword();
+
+            // Quit the application
+            Common::iApp::instance()->quit();
+        }
+
+        return false;
+    }
+    else
+        return Plugins::iPlugin::event(e);
+}
+
+QString Module::readPassword()
+{
+    bool noEcho = false;
+#ifdef Q_OS_LINUX
+    termios oldt;
+    tcgetattr(STDIN_FILENO, &oldt);
+    termios newt = oldt;
+    newt.c_lflag &= ~ECHO;
+    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
+    noEcho = true;
+#elif defined Q_OS_WIN32
+    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
+    DWORD mode = 0;
+    GetConsoleMode(hStdin, &mode);
+    SetConsoleMode(hStdin, mode & (~ENABLE_ECHO_INPUT));
+    noEcho = true;
+#endif
+
+    QTextStream cin(stdin);
+    QString rval = cin.readLine();
+
+    if (noEcho) {
+        QTextStream cout(stdout);
+        cout << endl;
+    }
+
+#ifdef Q_OS_LINUX
+    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
+#elif defined Q_OS_WIN32
+    SetConsoleMode(hStdin, mode);
+#endif
+
+    return rval;
+}
+
+void Module::generatePassword()
+{
+    QString masterPassword;
+    QString appName;
+    int passwordLength = DefaultPasswordLength;
+
+    // Process command-line arguments
+    QStringList args = QCoreApplication::arguments();
+    for (int i = 0; i < args.size(); ++i) {
+        QStringList arg = args.at(i).simplified().split('=');
+
+        if (QRegExp("-[-]?p(assword)?").exactMatch(arg.at(0)) && arg.size() > 1)
+            masterPassword = arg.at(1);
+        else if (QRegExp("-[-]?n(ame)?").exactMatch(arg.at(0)) && arg.size() > 1)
+            appName = arg.at(1);
+        else if (QRegExp("-[-]?l(ength)?").exactMatch(arg.at(0)) && arg.size() > 1) {
+            bool ok;
+            int t = arg.at(1).toInt(&ok);
+            if (!ok) {
+                EVAF_FATAL_ERROR("Invalid argument : %s", qPrintable(args.at(i)));
+                return;
+            }
+            passwordLength = t;
+        }
+    }
+
+    QTextStream cin(stdin);
+    QTextStream cout(stdout);
+
+    // Get missing arguments
+    while (masterPassword.isEmpty()) {
+        cout << tr("Master password : ") << flush;
+        masterPassword = readPassword();
+    }
+
+    while (appName.isEmpty()) {
+        cout << tr("Application name : ") << flush;
+        cin >> appName;
+    }
+
+    // Get more arguments from the storage
+    QExplicitlySharedDataPointer<PswGen::Storage::Data> data;
+    if (mStorage) {
+        data = mStorage->query(appName);
+        if (data)
+            passwordLength = data->length();
+    }
+
+    // Generate password
+    QString password = mGenerator->generatePassword(appName, masterPassword, passwordLength);
+    cout << "Generated password : " << password << endl;
+
+    // Store arguments for this password
+    if (mStorage) {
+        if (!data)
+            data = new Storage::Data(appName, passwordLength);
+        mStorage->save(appName, data);
+    }
+}