/* This file is part of the KDE project Copyright (C) 2005 Jaroslaw Staniek This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kexidbshortcutfile.h" #include #include #include #include #include #include #include //! Version of the KexiDBShortcutFile format. #define KexiDBShortcutFile_version 2 /* CHANGELOG: v1: initial version v2: "encryptedPassword" field added. For backward compatibility, it is not used if the connection data has been loaded from a file saved with version 1. In such cases unencrypted "password" field is used. */ //! @internal class KexiDBShortcutFile::Private { public: Private() : isDatabaseShortcut(true) { } QString fileName; bool isDatabaseShortcut : 1; }; KexiDBShortcutFile::KexiDBShortcutFile( const QString& fileName ) : d( new KexiDBShortcutFile::Private() ) { d->fileName = QDir(fileName).absPath(); } KexiDBShortcutFile::~KexiDBShortcutFile() { delete d; } bool KexiDBShortcutFile::loadProjectData(KexiProjectData& data, QString* _groupKey) { KConfig config(d->fileName, true /* readOnly */, false /* local */ ); config.setGroup("File Information"); data.formatVersion = config.readNumEntry("version", KexiDBShortcutFile_version); QString groupKey; if (!_groupKey || _groupKey->isEmpty()) { QStringList groups(config.groupList()); foreach (QStringList::ConstIterator, it, groups) { if ((*it).lower()!="file information") { groupKey = *it; break; } } if (groupKey.isEmpty()) { //ERR: "File %1 contains no connection information" return false; } if (_groupKey) *_groupKey = groupKey; } else { if (!config.hasGroup(*_groupKey)) return false; groupKey = *_groupKey; } config.setGroup(groupKey); QString type( config.readEntry("type", "database").lower() ); if (type=="database") { d->isDatabaseShortcut = true; } else if (type=="connection") { d->isDatabaseShortcut = false; } else { //ERR: i18n("No valid "type" field specified for section \"%1\": unknown value \"%2\".").arg(group).arg(type) return false; } /* kexidbg << "version=" << version << " using group key=" << groupKey << " type=" << type << " caption=" << config.readEntry("caption") << " name=" << config.readEntry("name") << " engine=" << config.readEntry("engine") << " server=" << config.readEntry("server") << " user=" << config.readEntry("user") << " password=" << QString().fill('*', config.readEntry("password").length()) << " comment=" << config.readEntry("comment") << endl;*/ //no filename by default data.connectionData()->setFileName(QString::null); if (d->isDatabaseShortcut) { data.setCaption( config.readEntry("caption") ); data.setDescription( config.readEntry("comment") ); data.connectionData()->description = QString::null; data.connectionData()->caption = QString::null; /* connection name is not specified... */ data.setDatabaseName( config.readEntry("name") ); } else { data.setCaption( QString::null ); data.connectionData()->caption = config.readEntry("caption"); data.setDescription( QString::null ); data.connectionData()->description = config.readEntry("comment"); data.setDatabaseName( QString::null ); /* db name is not specified... */ } data.connectionData()->driverName = config.readEntry("engine"); if (data.connectionData()->driverName.isEmpty()) { //ERR: "No valid "engine" field specified for %1 section" group return false; } data.connectionData()->hostName = config.readEntry("server"); //empty allowed data.connectionData()->port = config.readNumEntry("port", 0); data.connectionData()->useLocalSocketFile = config.readBoolEntry("useLocalSocketFile", false); data.connectionData()->localSocketFileName = config.readEntry("localSocketFile"); data.connectionData()->savePassword = config.hasKey("password") || config.hasKey("encryptedPassword"); if (data.formatVersion >= 2) { kdDebug() << config.hasKey("encryptedPassword") << endl; data.connectionData()->password = config.readEntry("encryptedPassword"); KexiUtils::simpleDecrypt(data.connectionData()->password); } if (data.connectionData()->password.isEmpty()) {//no "encryptedPassword", for compatibility //UNSAFE data.connectionData()->password = config.readEntry("password"); } // data.connectionData()->savePassword = !data.connectionData()->password.isEmpty(); data.connectionData()->userName = config.readEntry("user"); /* @todo add "options=", eg. as string list? */ return true; } bool KexiDBShortcutFile::saveProjectData(const KexiProjectData& data, bool savePassword, QString* _groupKey, bool overwriteFirstGroup) { KConfig config(d->fileName, false /*rw*/, false /* local */); config.setGroup("File Information"); uint realFormatVersion = data.formatVersion; if (realFormatVersion == 0) /* 0 means "default version"*/ realFormatVersion = KexiDBShortcutFile_version; config.writeEntry("version", realFormatVersion); const bool thisIsConnectionData = data.databaseName().isEmpty(); //use or find a nonempty group key QString groupKey; if (_groupKey && !_groupKey->isEmpty()) { groupKey = *_groupKey; } else { QString groupPrefix; const QStringList groups(config.groupList()); if (overwriteFirstGroup && !groups.isEmpty()) { // groupKey = groups.first(); //found foreach (QStringList::ConstIterator, it, groups) { if ((*it).lower()!="file information") { groupKey = *it; break; } } } if (groupKey.isEmpty()) { //find a new unique name if (thisIsConnectionData) groupPrefix = "Connection%1"; //do not i18n! else groupPrefix = "Database%1"; //do not i18n! int number = 1; while (config.hasGroup(groupPrefix.arg(number))) //a new group key couldn't exist number++; groupKey = groupPrefix.arg(number); } if (_groupKey) //return this one (generated or found) *_groupKey = groupKey; } config.deleteGroup(groupKey); config.setGroup(groupKey); if (thisIsConnectionData) { config.writeEntry("type", "connection"); config.writeEntry("caption", data.constConnectionData()->caption); if (!data.constConnectionData()->description.isEmpty()) config.writeEntry("comment", data.constConnectionData()->description); } else {//database config.writeEntry("type", "database"); config.writeEntry("caption", data.caption()); config.writeEntry("name", data.databaseName()); if (!data.description().isEmpty()) config.writeEntry("comment", data.description()); } config.writeEntry("engine", data.constConnectionData()->driverName); if (!data.constConnectionData()->hostName.isEmpty()) config.writeEntry("server", data.constConnectionData()->hostName); if (data.constConnectionData()->port!=0) config.writeEntry("port", data.constConnectionData()->port); config.writeEntry("useLocalSocketFile", data.constConnectionData()->useLocalSocketFile); if (!data.constConnectionData()->localSocketFileName.isEmpty()) config.writeEntry("localSocketFile", data.constConnectionData()->localSocketFileName); if (savePassword || data.constConnectionData()->savePassword) { if (realFormatVersion < 2) { config.writeEntry("password", data.constConnectionData()->password); } else { QString encryptedPassword = data.constConnectionData()->password; KexiUtils::simpleCrypt(encryptedPassword); config.writeEntry("encryptedPassword", encryptedPassword); encryptedPassword.fill(' '); //for security } } if (!data.constConnectionData()->userName.isEmpty()) config.writeEntry("user", data.constConnectionData()->userName); /* @todo add "options=", eg. as string list? */ config.sync(); return true; } QString KexiDBShortcutFile::fileName() const { return d->fileName; } //--------------------------------------------- KexiDBConnShortcutFile::KexiDBConnShortcutFile( const QString& fileName ) : KexiDBShortcutFile( fileName ) { } KexiDBConnShortcutFile::~KexiDBConnShortcutFile() { } bool KexiDBConnShortcutFile::loadConnectionData(KexiDB::ConnectionData& data, QString* _groupKey) { KexiProjectData pdata(data); if (!loadProjectData(pdata, _groupKey)) return false; data = *pdata.connectionData(); return true; } bool KexiDBConnShortcutFile::saveConnectionData(const KexiDB::ConnectionData& data, bool savePassword, QString* groupKey, bool overwriteFirstGroup) { KexiProjectData pdata(data); return saveProjectData(pdata, savePassword, groupKey, overwriteFirstGroup); } //--------------------------------------------- #if 0 /*! Loads connection data into \a data. */ bool KexiDBConnSetShortcutFiles::loadConnectionDataSet(KexiDBConnectionSet& set) { set.clear(); // QStringList dirs( KGlobal::dirs()->findDirs("data", "kexi/connections") ); // kexidbg << dirs << endl; QStringList files( KGlobal::dirs()->findAllResources("data", "kexi/connections/*.kexic") ); // //also try for capital file extension // files += KGlobal::dirs()->findAllResources("data", "kexi/connections/*.KEXIC"); kexidbg << files << endl; foreach(QStringList::ConstIterator, it, files) { KexiDB::ConnectionData *data = new KexiDB::ConnectionData(); KexiDBConnShortcutFile shortcutFile( *it ); if (!shortcutFile.loadConnectionData(*data)) { delete data; continue; } set.addConnectionData(data); } } /*! Saves a set of connection data \a set to a shortcut files. Existing files are overwritten with a new data. */ bool KexiDBConnSetShortcutFiles::saveConnectionDataSet(const KexiDBConnectionSet& set) { } #endif