summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml16
-rw-r--r--CMakeLists.txt41
-rw-r--r--java/constants.h8
-rw-r--r--java/javautils.cpp108
-rw-r--r--java/javautils.h25
-rw-r--r--libmultimc/include/minecraftprocess.h2
-rw-r--r--libmultimc/src/minecraftprocess.cpp2
-rw-r--r--libsettings/include/keyring.h85
-rw-r--r--libsettings/src/keyring.cpp63
-rw-r--r--libsettings/src/stubkeyring.cpp96
-rw-r--r--libsettings/src/stubkeyring.h42
-rw-r--r--libutil/include/cmdutils.h17
-rw-r--r--libutil/src/cmdutils.cpp16
-rw-r--r--test.cpp60
14 files changed, 493 insertions, 88 deletions
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..c94982f2
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,16 @@
+language: cpp
+compiler:
+ - gcc
+
+before_script:
+ - sudo apt-add-repository -y ppa:czchen/travis-ci
+ - sudo add-apt-repository -y ppa:ubuntu-sdk-team/ppa
+ - sudo add-apt-repository -y ppa:canonical-qt5-edgers/qt5-proper
+ - sudo apt-get update -yqq
+ - sudo apt-get install -yqq cmake
+ - sudo apt-get install -yqq ubuntu-sdk
+
+script: "cmake . && make -j4"
+
+notifications:
+ irc: "irc.esper.net#MultiMC"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fad09575..742f47f6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -47,6 +47,7 @@ find_package(ZLIB REQUIRED)
# Add quazip
add_subdirectory(quazip)
+include_directories(quazip)
# Add bspatch
add_subdirectory(patchlib)
@@ -85,7 +86,7 @@ add_subdirectory(plugins/stdinstance)
INCLUDE(TestBigEndian)
TEST_BIG_ENDIAN(BIGENDIAN)
IF(${BIGENDIAN})
- ADD_DEFINITIONS(-DMULTIMC_BIG_ENDIAN)
+ ADD_DEFINITIONS(-DMULTIMC_BIG_ENDIAN)
ENDIF(${BIGENDIAN})
@@ -126,7 +127,7 @@ IF(DEFINED MultiMC_BUILD_TAG)
MESSAGE(STATUS "Build tag: ${MultiMC_BUILD_TAG}")
ELSE()
MESSAGE(STATUS "No build tag specified.")
- SET(MultiMC_BUILD_TAG custom)
+ SET(MultiMC_BUILD_TAG custom)
ENDIF()
# Architecture detection
@@ -148,13 +149,13 @@ ENDIF()
# Jenkins URL
SET(MultiMC_JOB_URL "http://ci.forkk.net/job/${MultiMC_JOB_NAME}/arch=${MultiMC_ARCH}${MultiMC_Extra_Label}/"
- CACHE STRING "URL of the jenkins job to pull updates from.")
+ CACHE STRING "URL of the jenkins job to pull updates from.")
MESSAGE(STATUS "Job URL: ${MultiMC_JOB_URL}")
######## Configure header ########
configure_file("${PROJECT_SOURCE_DIR}/config.h.in"
- "${PROJECT_BINARY_DIR}/include/config.h")
-include_directories(${PROJECT_BINARY_DIR}/include)
+ "${PROJECT_BINARY_DIR}/include/config.h")
+
################################ FILES ################################
@@ -238,9 +239,9 @@ ENDIF(APPLE)
# Link additional libraries
IF(WIN32)
- SET(MultiMC_LINK_ADDITIONAL_LIBS ${MultiMC_LINK_ADDITIONAL_LIBS}
- Qt5::WinMain # Link WinMain
- )
+ SET(MultiMC_LINK_ADDITIONAL_LIBS ${MultiMC_LINK_ADDITIONAL_LIBS}
+ Qt5::WinMain # Link WinMain
+ )
ENDIF(WIN32)
# Tell CMake that MultiMCLauncher.jar is generated.
@@ -261,11 +262,17 @@ libUtil libSettings libMultiMC libGroupView
${MultiMC_LINK_ADDITIONAL_LIBS})
ADD_DEPENDENCIES(MultiMC MultiMCLauncher libUtil libSettings libMultiMC libGroupView)
+IF(DEFINED MMC_KEYRING_TEST)
+# test.cpp
+ADD_EXECUTABLE(Test test.cpp)
+QT5_USE_MODULES(Test Core)
+TARGET_LINK_LIBRARIES(Test libmmcutil libmmcsettings)
+ENDIF()
################################ INSTALLATION AND PACKAGING ################################
# use QtCreator's QTDIR var
IF(DEFINED ENV{QTDIR})
- SET(Qt5_DIR $ENV{QTDIR})
+ SET(Qt5_DIR $ENV{QTDIR})
ENDIF()
######## Plugin and library folders ########
@@ -283,7 +290,7 @@ ENDIF()
IF(APPLE)
SET(PLUGIN_DEST_DIR MultiMC.app/Contents/MacOS)
SET(QTCONF_DEST_DIR MultiMC.app/Contents/Resources)
- SET(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC.app")
+ SET(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC.app")
ENDIF()
SET(QT_PLUGINS_DIR ${Qt5_DIR}/plugins)
@@ -354,13 +361,13 @@ INSTALL(CODE "
# Package with CPack
IF(UNIX)
- if(APPLE)
- SET(CPACK_GENERATOR "ZIP")
- else()
- SET(CPACK_GENERATOR "TGZ")
- endif()
+ if(APPLE)
+ SET(CPACK_GENERATOR "ZIP")
+ else()
+ SET(CPACK_GENERATOR "TGZ")
+ endif()
ELSEIF(WIN32)
- SET(CPACK_GENERATOR "ZIP")
+ SET(CPACK_GENERATOR "ZIP")
ENDIF()
SET(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0)
@@ -383,3 +390,5 @@ SET(CPACK_PACKAGE_INSTALL_DIRECTORY "MultiMC 5")
ENDIF()
INCLUDE(CPack)
+
+include_directories(${PROJECT_BINARY_DIR}/include)
diff --git a/java/constants.h b/java/constants.h
index 2f968d2e..61aa5687 100644
--- a/java/constants.h
+++ b/java/constants.h
@@ -7,7 +7,7 @@ namespace java
class constant
{
public:
- enum type_t:uint8_t
+ enum type_t : uint8_t
{
j_hole = 0, // HACK: this is a hole in the array, because java is crazy
j_string_data = 1,
@@ -22,6 +22,7 @@ namespace java
j_interface_methodref = 11,
j_nameandtype = 12
} type;
+
constant(util::membuffer & buf )
{
buf.read(type);
@@ -66,10 +67,12 @@ namespace java
break;
}
}
+
constant(int fake)
{
type = j_hole;
}
+
std::string toString()
{
std::ostringstream ss;
@@ -143,6 +146,7 @@ namespace java
} name_and_type;
};
};
+
/**
* A helper class that represents the custom container used in Java class file for storage of constants
*/
@@ -181,7 +185,7 @@ namespace java
index++;
}
}
- };
+ }
typedef std::vector<java::constant> container_type;
/**
* Access constants based on jar file index numbers (index of the first element is 1)
diff --git a/java/javautils.cpp b/java/javautils.cpp
index a07d1541..4a359031 100644
--- a/java/javautils.cpp
+++ b/java/javautils.cpp
@@ -1,69 +1,81 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Authors: Orochimarufan <orochimarufan.x3@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
#include "multimc_pragma.h"
#include "classfile.h"
#include "javautils.h"
-//#include <wx/zipstrm.h>
-#include <memory>
-//#include <wx/wfstream.h>
-//#include "mcversionlist.h"
+
+#include <QFile>
+#include <quazipfile.h>
namespace javautils
{
-QString GetMinecraftJarVersion(QString jar)
+
+QString GetMinecraftJarVersion(QString jarName)
{
- return "Unknown";
- /*
- wxString fullpath = jar.GetFullPath();
- wxString version = MCVer_Unknown;
- if(!jar.FileExists())
+ QString version = MCVer_Unknown;
+
+ // check if minecraft.jar exists
+ QFile jar(jarName);
+ if (!jar.exists())
return version;
- std::auto_ptr<wxZipEntry> entry;
- // convert the local name we are looking for into the internal format
- wxString name = wxZipEntry::GetInternalName("net/minecraft/client/Minecraft.class",wxPATH_UNIX);
- // open the zip
- wxFFileInputStream inStream(jar.GetFullPath());
- wxZipInputStream zipIn(inStream);
+ // open minecraft.jar
+ QuaZip zip(&jar);
+ if (!zip.open(QuaZip::mdUnzip))
+ return version;
- // call GetNextEntry() until the required internal name is found
- do
- {
- entry.reset(zipIn.GetNextEntry());
- }
- while (entry.get() != NULL && entry->GetInternalName() != name);
- auto myentry = entry.get();
- if (myentry == NULL)
+ // open Minecraft.class
+ zip.setCurrentFile("net/minecraft/client/Minecraft.class", QuaZip::csSensitive);
+ QuaZipFile Minecraft(&zip);
+ if (!Minecraft.open(QuaZipFile::ReadOnly))
return version;
-
- // we got the entry, read the data
- std::size_t size = myentry->GetSize();
- char *classdata = new char[size];
- zipIn.Read(classdata,size);
- try
- {
- char * temp = classdata;
- java::classfile Minecraft_jar(temp,size);
- auto cnst = Minecraft_jar.constants;
- auto iter = cnst.begin();
- while (iter != cnst.end())
+
+ // read Minecraft.class
+ qint64 size = Minecraft.size();
+ char *classfile = new char[size];
+ Minecraft.read(classfile, size);
+
+ // parse Minecraft.class
+ try {
+ char *temp = classfile;
+ java::classfile MinecraftClass(temp, size);
+ java::constant_pool constants = MinecraftClass.constants;
+ for(java::constant_pool::container_type::const_iterator iter=constants.begin();
+ iter != constants.end(); iter++)
{
const java::constant & constant = *iter;
- if(constant.type != java::constant::j_string_data)
- {
- iter++;
+ if (constant.type != java::constant::j_string_data)
continue;
- }
- auto & str = constant.str_data;
- const char * lookfor = "Minecraft Minecraft "; // length = 20
- if(str.compare(0,20,lookfor) == 0)
+ const std::string & str = constant.str_data;
+ if (str.compare(0, 20, "Minecraft Minecraft ") == 0)
{
version = str.substr(20).data();
break;
}
- iter++;
}
- } catch(java::classfile_exception &){}
- delete[] classdata;
+ } catch(java::classfile_exception &) {}
+
+ // clean up
+ delete[] classfile;
+ Minecraft.close();
+ zip.close();
+ jar.close();
+
return version;
- */
}
-} \ No newline at end of file
+
+}
diff --git a/java/javautils.h b/java/javautils.h
index c8b5a793..883eff1d 100644
--- a/java/javautils.h
+++ b/java/javautils.h
@@ -1,9 +1,28 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Authors: Orochimarufan <orochimarufan.x3@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
#pragma once
#include <QString>
+
+#define MCVer_Unknown "Unknown"
+
namespace javautils
{
- /*
- * Get the version from a minecraft.jar by parsing its class files. Expensive!
+ /**
+ * @brief Get the version from a minecraft.jar by parsing its class files. Expensive!
*/
QString GetMinecraftJarVersion(QString jar);
-} \ No newline at end of file
+}
diff --git a/libmultimc/include/minecraftprocess.h b/libmultimc/include/minecraftprocess.h
index 8986f7ad..d6b9f612 100644
--- a/libmultimc/include/minecraftprocess.h
+++ b/libmultimc/include/minecraftprocess.h
@@ -85,7 +85,7 @@ protected:
QStringList m_arguments;
void genArgs();
- void log(QString text);
+ void log(QString text, ConsoleWindow::WriteMode mode = ConsoleWindow::MULTIMC);
protected slots:
void finish(int, QProcess::ExitStatus status);
diff --git a/libmultimc/src/minecraftprocess.cpp b/libmultimc/src/minecraftprocess.cpp
index 943d76b1..3aecb1ee 100644
--- a/libmultimc/src/minecraftprocess.cpp
+++ b/libmultimc/src/minecraftprocess.cpp
@@ -197,6 +197,8 @@ void MinecraftProcess::launch()
start(m_instance->settings().get("JavaPath").toString(), m_arguments);
if (!waitForStarted())
{
+ log("Could not launch minecraft!", ConsoleWindow::ERROR);
+ return;
//TODO: error handling
}
diff --git a/libsettings/include/keyring.h b/libsettings/include/keyring.h
new file mode 100644
index 00000000..afdc3bba
--- /dev/null
+++ b/libsettings/include/keyring.h
@@ -0,0 +1,85 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Authors: Orochimarufan <orochimarufan.x3@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef KEYRING_H
+#define KEYRING_H
+
+#include <QObject>
+
+#include "libsettings_config.h"
+
+/**
+ * @file libsettings/include/keyring.h
+ * Access to System Keyrings
+ */
+
+/**
+ * @brief The Keyring class
+ * the System Keyring/Keychain/Wallet/Vault/etc
+ */
+class LIBMMCSETTINGS_EXPORT Keyring : public QObject
+{
+ Q_OBJECT
+public:
+ /**
+ * @brief the System Keyring instance
+ * @return the Keyring instance
+ */
+ static Keyring *instance();
+
+ /**
+ * @brief store a password in the Keyring
+ * @param service the service name
+ * @param username the account name
+ * @param password the password to store
+ * @return success
+ */
+ virtual bool storePassword(QString service, QString username, QString password) = 0;
+
+ /**
+ * @brief get a password from the Keyring
+ * @param service the service name
+ * @param username the account name
+ * @return the password (success=!isNull())
+ */
+ virtual QString getPassword(QString service, QString username) = 0;
+
+ /**
+ * @brief lookup a password
+ * @param service the service name
+ * @param username the account name
+ * @return wether the password is available
+ */
+ virtual bool hasPassword(QString service, QString username) = 0;
+
+ /**
+ * @brief get a list of all stored accounts.
+ * @param service the service name
+ * @return
+ */
+ virtual QStringList getStoredAccounts(QString service) = 0;
+
+protected:
+ /// fall back to StubKeyring if false
+ virtual bool isValid() { return false; }
+
+private:
+ static Keyring *m_instance;
+ static void destroy();
+};
+
+#endif // KEYRING_H
diff --git a/libsettings/src/keyring.cpp b/libsettings/src/keyring.cpp
new file mode 100644
index 00000000..9eaba684
--- /dev/null
+++ b/libsettings/src/keyring.cpp
@@ -0,0 +1,63 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Authors: Orochimarufan <orochimarufan.x3@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "include/keyring.h"
+
+#include "osutils.h"
+
+#include "stubkeyring.h"
+
+// system specific keyrings
+/*#if defined(OSX)
+class OSXKeychain;
+#define KEYRING OSXKeychain
+#elif defined(LINUX)
+class XDGKeyring;
+#define KEYRING XDGKeyring
+#elif defined(WINDOWS)
+class Win32Keystore;
+#define KEYRING Win32Keystore
+#else
+#pragma message Keyrings are not supported on your os. Falling back to the insecure StubKeyring
+#endif*/
+
+Keyring *Keyring::instance()
+{
+ if (m_instance == nullptr)
+ {
+#ifdef KEYRING
+ m_instance = new KEYRING();
+ if (!m_instance->isValid())
+ {
+ qWarning("Could not create SystemKeyring! falling back to StubKeyring.");
+ m_instance = new StubKeyring();
+ }
+#else
+ qWarning("Keyrings are not supported on your OS. Fallback StubKeyring is insecure!");
+ m_instance = new StubKeyring();
+#endif
+ atexit(Keyring::destroy);
+ }
+ return m_instance;
+}
+
+void Keyring::destroy()
+{
+ delete m_instance;
+}
+
+Keyring *Keyring::m_instance;
diff --git a/libsettings/src/stubkeyring.cpp b/libsettings/src/stubkeyring.cpp
new file mode 100644
index 00000000..963f3dd9
--- /dev/null
+++ b/libsettings/src/stubkeyring.cpp
@@ -0,0 +1,96 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Authors: Orochimarufan <orochimarufan.x3@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "stubkeyring.h"
+
+#include <QStringList>
+
+// Scrambling
+// this is NOT SAFE, but it's not plain either.
+int scrambler = 0x9586309;
+
+QString scramble(QString in_)
+{
+ QByteArray in = in_.toUtf8();
+ QByteArray out;
+ for (int i = 0; i<in.length(); i++)
+ out.append(in.at(i) ^ scrambler);
+ return QString::fromUtf8(out);
+}
+
+inline QString base64(QString in)
+{
+ return QString(in.toUtf8().toBase64());
+}
+inline QString unbase64(QString in)
+{
+ return QString::fromUtf8(QByteArray::fromBase64(in.toLatin1()));
+}
+
+inline QString scramble64(QString in)
+{
+ return base64(scramble(in));
+}
+inline QString unscramble64(QString in)
+{
+ return scramble(unbase64(in));
+}
+
+// StubKeyring implementation
+inline QString generateKey(QString service, QString username)
+{
+ return QString("%1/%2").arg(base64(service)).arg(scramble64(username));
+}
+
+bool StubKeyring::storePassword(QString service, QString username, QString password)
+{
+ m_settings.setValue(generateKey(service, username), scramble64(password));
+ return true;
+}
+
+QString StubKeyring::getPassword(QString service, QString username)
+{
+ QString key = generateKey(service, username);
+ if (!m_settings.contains(key))
+ return QString();
+ return unscramble64(m_settings.value(key).toString());
+}
+
+bool StubKeyring::hasPassword(QString service, QString username)
+{
+ return m_settings.contains(generateKey(service, username));
+}
+
+QStringList StubKeyring::getStoredAccounts(QString service)
+{
+ service = base64(service).append('/');
+ QStringList out;
+ QStringList in(m_settings.allKeys());
+ QStringListIterator it(in);
+ while(it.hasNext())
+ {
+ QString c = it.next();
+ if (c.startsWith(service))
+ out << unscramble64(c.mid(service.length()));
+ }
+ return out;
+}
+
+StubKeyring::StubKeyring() :
+ m_settings(QSettings::UserScope, "Orochimarufan", "Keyring")
+{
+}
diff --git a/libsettings/src/stubkeyring.h b/libsettings/src/stubkeyring.h
new file mode 100644
index 00000000..0566d5ab
--- /dev/null
+++ b/libsettings/src/stubkeyring.h
@@ -0,0 +1,42 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Authors: Orochimarufan <orochimarufan.x3@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef STUBKEYRING_H
+#define STUBKEYRING_H
+
+#include "include/keyring.h"
+
+#include <QSettings>
+
+class StubKeyring : public Keyring
+{
+ Q_OBJECT
+public:
+ virtual bool storePassword(QString service, QString username, QString password);
+ virtual QString getPassword(QString service, QString username);
+ virtual bool hasPassword(QString service, QString username);
+ virtual QStringList getStoredAccounts(QString service);
+
+private:
+ friend class Keyring;
+ explicit StubKeyring();
+ virtual bool isValid() { return true; }
+
+ QSettings m_settings;
+};
+
+#endif // STUBKEYRING_H
diff --git a/libutil/include/cmdutils.h b/libutil/include/cmdutils.h
index 32261dd7..83397e73 100644
--- a/libutil/include/cmdutils.h
+++ b/libutil/include/cmdutils.h
@@ -73,15 +73,6 @@ enum LIBUTIL_EXPORT Enum
};
}
-namespace OptionType
-{
-enum LIBUTIL_EXPORT Enum
-{
- Switch,
- Option
-};
-}
-
/**
* @brief The ParsingError class
*/
@@ -210,6 +201,12 @@ public:
private:
FlagStyle::Enum m_flagStyle;
ArgumentStyle::Enum m_argStyle;
+
+ enum OptionType
+ {
+ otSwitch,
+ otOption
+ };
// Important: the common part MUST BE COMMON ON ALL THREE structs
struct CommonDef {
@@ -226,7 +223,7 @@ private:
QString metavar;
QVariant def;
// option
- OptionType::Enum type;
+ OptionType type;
QChar flag;
};
diff --git a/libutil/src/cmdutils.cpp b/libutil/src/cmdutils.cpp
index 3bf4e872..13db503d 100644
--- a/libutil/src/cmdutils.cpp
+++ b/libutil/src/cmdutils.cpp
@@ -56,7 +56,7 @@ void Parser::addSwitch(QString name, bool def)
throw "Name not unique";
OptionDef *param = new OptionDef;
- param->type = OptionType::Switch;
+ param->type = otSwitch;
param->name = name;
param->metavar = QString("<%1>").arg(name);
param->def = def;
@@ -72,7 +72,7 @@ void Parser::addOption(QString name, QVariant def)
throw "Name not unique";
OptionDef *param = new OptionDef;
- param->type = OptionType::Option;
+ param->type = otOption;
param->name = name;
param->metavar = QString("<%1>").arg(name);
param->def = def;
@@ -161,7 +161,7 @@ QString Parser::compileHelp(QString progName, int helpIndent, bool useFlags)
help << flagPrefix << option->flag << ", ";
}
help << optPrefix << option->name;
- if (option->type == OptionType::Option)
+ if (option->type == otOption)
{
QString arg = QString("%1%2").arg(((m_argStyle == ArgumentStyle::Equals) ? "=" : " "), option->metavar);
nameLength += arg.length();
@@ -193,7 +193,7 @@ QString Parser::compileUsage(QString progName, bool useFlags)
usage << flagPrefix << option->flag;
else
usage << optPrefix << option->name;
- if (option->type == OptionType::Option)
+ if (option->type == otOption)
usage << ((m_argStyle == ArgumentStyle::Equals) ? "=" : " ") << option->metavar;
usage << "]";
}
@@ -265,9 +265,9 @@ QHash<QString, QVariant> Parser::parse(QStringList argv)
throw ParsingError(QString("Option %2%1 was given multiple times").arg(name, optionPrefix));
OptionDef *option = m_options[name];
- if (option->type == OptionType::Switch)
+ if (option->type == otSwitch)
map[name] = true;
- else //if (option->type == OptionType::Option)
+ else //if (option->type == otOption)
{
if (m_argStyle == ArgumentStyle::Space)
expecting.append(name);
@@ -312,9 +312,9 @@ QHash<QString, QVariant> Parser::parse(QStringList argv)
if (map.contains(option->name))
throw ParsingError(QString("Option %2%1 was given multiple times").arg(option->name, optionPrefix));
- if (option->type == OptionType::Switch)
+ if (option->type == otSwitch)
map[option->name] = true;
- else //if (option->type == OptionType::Option)
+ else //if (option->type == otOption)
{
if (m_argStyle == ArgumentStyle::Space)
expecting.append(option->name);
diff --git a/test.cpp b/test.cpp
new file mode 100644
index 00000000..2b015454
--- /dev/null
+++ b/test.cpp
@@ -0,0 +1,60 @@
+
+#include <iostream>
+
+#include "keyring.h"
+#include "cmdutils.h"
+
+using namespace Util::Commandline;
+
+#include <QCoreApplication>
+
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+ app.setApplicationName("MMC Keyring test");
+ app.setOrganizationName("Orochimarufan");
+
+ Parser p;
+ p.addArgument("user", false);
+ p.addArgument("password", false);
+ p.addSwitch("set");
+ p.addSwitch("get");
+ p.addSwitch("list");
+ p.addOption("service", "Test");
+ p.addShortOpt("service", 's');
+
+ QHash<QString, QVariant> args;
+ try {
+ args = p.parse(app.arguments());
+ } catch (ParsingError) {
+ std::cout << "Syntax error." << std::endl;
+ return 1;
+ }
+
+ if (args["set"].toBool()) {
+ if (args["user"].isNull() || args["password"].isNull()) {
+ std::cout << "set operation needs bot user and password set" << std::endl;
+ return 1;
+ }
+
+ return Keyring::instance()->storePassword(args["service"].toString(),
+ args["user"].toString(), args["password"].toString());
+ } else if (args["get"].toBool()) {
+ if (args["user"].isNull()) {
+ std::cout << "get operation needs user set" << std::endl;
+ return 1;
+ }
+
+ std::cout << "Password: " << qPrintable(Keyring::instance()->getPassword(args["service"].toString(),
+ args["user"].toString())) << std::endl;
+ return 0;
+ } else if (args["list"].toBool()) {
+ QStringList accounts = Keyring::instance()->getStoredAccounts(args["service"].toString());
+ std::cout << "stored accounts:" << std::endl << '\t' << qPrintable(accounts.join("\n\t")) << std::endl;
+ return 0;
+ } else {
+ std::cout << "No operation given!" << std::endl;
+ std::cout << qPrintable(p.compileHelp(argv[0])) << std::endl;
+ return 1;
+ }
+}