-rw-r--r-- | pwmanager/pwmanager/globalstuff.h | 27 | ||||
-rw-r--r-- | pwmanager/pwmanager/ipc.cpp | 80 | ||||
-rw-r--r-- | pwmanager/pwmanager/ipc.h | 26 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwmdoc.cpp | 142 |
4 files changed, 259 insertions, 16 deletions
diff --git a/pwmanager/pwmanager/globalstuff.h b/pwmanager/pwmanager/globalstuff.h index 7bc4173..428ce95 100644 --- a/pwmanager/pwmanager/globalstuff.h +++ b/pwmanager/pwmanager/globalstuff.h @@ -1,113 +1,134 @@ /*************************************************************************** * * * copyright (C) 2003, 2004 by Michael Buesch * * email: mbuesch@freenet.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation. * * * ***************************************************************************/ /*************************************************************************** * copyright (C) 2004 by Ulf Schenk * This file is originaly based on version 1.0.1 of pwmanager * and was modified to run on embedded devices that run microkde * * $Id$ **************************************************************************/ #ifndef __GLOBALSTUFF_H #define __GLOBALSTUFF_H #ifndef PWM_EMBEDDED #include "config.h" #endif #include "compiler.h" + //US BUG: the following code caused compile errors with certain gcccompilers (2.95). + // Because of that I replaced it with a Qt version, which should do the same. #include <string> + +#ifndef PWM_EMBEDDED #include <sstream> +#else +#include <qstring.h> +#include <qtextstream.h> +#endif #ifndef CONFIG_KEYCARD class QWidget; void no_keycard_support_msg_box(QWidget *parentWidget); #endif // CONFIG_KEYCARD #ifdef PROG_NAME # undef PROG_NAME #endif #define PROG_NAME "PwManager" #ifdef PACKAGE_NAME # undef PACKAGE_NAME #endif #define PACKAGE_NAME "pwmanager" #ifdef PACKAGE_VER # undef PACKAGE_VER #endif #define PACKAGE_VER "1.0.1" #ifdef CONFIG_DEBUG # define PWM_DEBUG #else # undef PWM_DEBUG #endif #ifdef QT_MAKE_VERSION # undef QT_MAKE_VERSION #endif #define QT_MAKE_VERSION(a,b,c) (((a) << 16) | ((b) << 8) | (c)) /** remove "unused parameter" warnings */ #ifdef PARAM_UNUSED # undef PARAM_UNUSED #endif #define PARAM_UNUSED(x) (void)x /** return the number of elements in an array */ #ifdef array_size # undef array_size #endif #define array_size(x) (sizeof(x) / sizeof((x)[0])) +//US BUG: the following code caused compile errors with certain gcccompilers (2.95). +// Because of that I replaced it with a Qt version, which should do the same. +#ifndef PWM_EMBEDDED +/** convert something to string using ostringstream */ +template <class T> inline +std::string tostr(const T &t) +{ + std::ostringstream s; + s << t; + return s.str(); +} +#else /** convert something to string using ostringstream */ template <class T> inline std::string tostr(const T &t) { - std::ostringstream s; - s << t; - return s.str(); + QString result; + QTextOStream(&result) << t; + return result.latin1(); } +#endif /** delete the memory and NULL the pointer */ template<class T> inline void delete_and_null(T *&p) { delete p; p = 0; } /** delete the memory if the pointer isn't a NULL pointer */ template<class T> inline void delete_ifnot_null(T *&p) { if (p) delete_and_null(p); } template<class T> inline void delete_and_null_array(T *&p) { delete [] p; p = 0; } template<class T> inline void delete_ifnot_null_array(T *&p) { if (p) delete_and_null_array(p); } #endif // GLOBALSTUFF_H diff --git a/pwmanager/pwmanager/ipc.cpp b/pwmanager/pwmanager/ipc.cpp index 7468357..b1d2c68 100644 --- a/pwmanager/pwmanager/ipc.cpp +++ b/pwmanager/pwmanager/ipc.cpp @@ -1,152 +1,216 @@ /*************************************************************************** * * * copyright (C) 2004 by Michael Buesch * * email: mbuesch@freenet.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation. * * * ***************************************************************************/ /*************************************************************************** * copyright (C) 2004 by Ulf Schenk * This file is originaly based on version 1.0.1 of pwmanager * and was modified to run on embedded devices that run microkde * * $Id$ **************************************************************************/ #include "ipc.h" #include "pwmexception.h" #include <qsocketnotifier.h> -#include <sys/types.h> #include <sys/socket.h> + +#ifndef PWM_EMBEDDED +#include <sys/types.h> #include <stdio.h> +#else +#include <qsocket.h> +#endif #define END_OF_LINE '\n' #define INIT_LINEBUF_LEN 64 /* byte */ +#ifndef PWM_EMBEDDED Ipc::Ipc() : stream (0) , notifier (0) , rdBuf (0) { -#ifndef PWM_EMBEDDED if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sock)) { throw PwMException(PwMException::EX_GENERIC, "Ipc: socketpair() failed"); } rdBufSize = INIT_LINEBUF_LEN; rdBuf = static_cast<char *>(malloc(rdBufSize)); if (!rdBuf) { close(sock[0]); close(sock[1]); throw PwMException(PwMException::EX_GENERIC, "Ipc: OOM"); } stream = fdopen(sock[0], "r"); if (!stream) { close(sock[0]); close(sock[1]); free(rdBuf); throw PwMException(PwMException::EX_GENERIC, "Ipc: fdopen() failed"); } + + notifier = new QSocketNotifier(sock[0], QSocketNotifier::Read); + connect(notifier, SIGNAL(activated(int)), + this, SLOT(receiveData(int))); + host = true; +} #else +Ipc::Ipc() + : notifier (0) + , rdBuf (0) +{ if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sock)) { qDebug("Ipc: socketpair() failed"); } + + QSocket* qsock = new QSocket(); + qsock->setSocket(sock[0]); + rdBufSize = INIT_LINEBUF_LEN; rdBuf = (char *)(malloc(rdBufSize)); if (!rdBuf) { close(sock[0]); close(sock[1]); qDebug("Ipc: OOM"); } + + qsock = new QSocket(); + qsock->setSocket(sock[0]); + + /*US stream = fdopen(sock[0], "r"); if (!stream) { close(sock[0]); close(sock[1]); free(rdBuf); qDebug("Ipc: fdopen() failed"); } -#endif + */ notifier = new QSocketNotifier(sock[0], QSocketNotifier::Read); connect(notifier, SIGNAL(activated(int)), this, SLOT(receiveData(int))); host = true; } +#endif + + +#ifndef PWM_EMBEDDED + Ipc::Ipc(const Ipc *ipc) : stream (0) , notifier (0) , rdBuf (0) { -#ifndef PWM_EMBEDDED rdBufSize = INIT_LINEBUF_LEN; rdBuf = static_cast<char *>(malloc(rdBufSize)); if (!rdBuf) { throw PwMException(PwMException::EX_GENERIC, "Ipc: OOM"); } sock[0] = ipc->sock[1]; sock[1] = ipc->sock[0]; stream = fdopen(sock[0], "r"); if (!stream) { free(rdBuf); throw PwMException(PwMException::EX_GENERIC, "Ipc: fdopen() failed"); } + + notifier = new QSocketNotifier(sock[0], QSocketNotifier::Read); + connect(notifier, SIGNAL(activated(int)), + this, SLOT(receiveData(int))); + host = false; +} + #else + +Ipc::Ipc(const Ipc *ipc) + : notifier (0) + , rdBuf (0) +{ rdBufSize = INIT_LINEBUF_LEN; rdBuf = (char *)(malloc(rdBufSize)); if (!rdBuf) { qDebug("Ipc: OOM"); } sock[0] = ipc->sock[1]; sock[1] = ipc->sock[0]; + + qSock = new QSocket(); + qSock->setSocket(sock[0]); + + /*US stream = fdopen(sock[0], "r"); if (!stream) { free(rdBuf); qDebug("Ipc: fdopen() failed"); } -#endif + */ + notifier = new QSocketNotifier(sock[0], QSocketNotifier::Read); connect(notifier, SIGNAL(activated(int)), this, SLOT(receiveData(int))); host = false; } +#endif + Ipc::~Ipc() { +#ifdef PWM_EMBEDDED + delete qSock; +#endif delete_ifnot_null(notifier); if (rdBuf) free(rdBuf); +#ifndef PWM_EMBEDDED if (stream) fclose(stream); +#endif if (host) { close(sock[0]); close(sock[1]); } + } void Ipc::receiveData(int s) { - ssize_t rd; - PWM_ASSERT(s == sock[0]); PARAM_UNUSED(s); - rd = getline(&rdBuf, &rdBufSize, stream); +#ifndef PWM_EMBEDDED + ssize_t rd; + + rd = ::getline(&rdBuf, &rdBufSize, stream); if (likely(rd > 0)) { emit lineAvailable(rdBuf, rd); } +#else + int rd; + rd = qSock->readLine(rdBuf, rdBufSize); + if (rd > 0) { + emit lineAvailable(rdBuf, rd); + } +#endif + qDebug("void Ipc::receiveData(int s) has to be implemented."); + } #ifndef PWM_EMBEDDED #include "ipc.moc" #endif diff --git a/pwmanager/pwmanager/ipc.h b/pwmanager/pwmanager/ipc.h index ccdaafb..e5a496d 100644 --- a/pwmanager/pwmanager/ipc.h +++ b/pwmanager/pwmanager/ipc.h @@ -1,73 +1,89 @@ /*************************************************************************** * * * copyright (C) 2004 by Michael Buesch * * email: mbuesch@freenet.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation. * * * ***************************************************************************/ /*************************************************************************** * copyright (C) 2004 by Ulf Schenk * This file is originaly based on version 1.0.1 of pwmanager * and was modified to run on embedded devices that run microkde * * $Id$ **************************************************************************/ #ifndef __PWM_IPC_H #define __PWM_IPC_H +#include <qobject.h> #include <unistd.h> -#include <qobject.h> +#ifndef PWM_EMBEDDED #include <stdio.h> +#else +#include <qsocket.h> +#endif class QSocketNotifier; /** very simple interprocess communication class */ class Ipc : public QObject { Q_OBJECT public: /** create a new Ipc communication object */ Ipc(); /** create a new Ipc communication object and * connect it to "ipc" */ Ipc(const Ipc *ipc); /** destructor */ ~Ipc(); /** send data to the other socket end * (To the connected ipc object) */ +#ifndef PWM_EMBEDDED void send(const char *buf, size_t size) { write(sock[0], buf, size); } +#else + void send(const char *buf, size_t size) + { qSock->writeBlock(buf, size); } +#endif signals: /** a line is available */ void lineAvailable(const char *buf, size_t size); protected slots: /** received data on socket */ void receiveData(int s); protected: - /** full-duplex socket file desciptors */ - int sock[2]; +#ifndef PWM_EMBEDDED /** stream on "this" end of the socket (sock[0]) */ FILE *stream; + /** current receive buffer size */ + size_t rdBufSize; +#else + QSocket* qSock; + /** current receive buffer size */ + unsigned int rdBufSize; +#endif + + /** full-duplex socket file desciptors */ + int sock[2]; /** socket notifier */ QSocketNotifier *notifier; /** are we the host or the client object? */ bool host; /** receive buffer */ char *rdBuf; - /** current receive buffer size */ - size_t rdBufSize; }; #endif // __PWM_IPC_H diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp index 3f2f042..4ad392e 100644 --- a/pwmanager/pwmanager/pwmdoc.cpp +++ b/pwmanager/pwmanager/pwmdoc.cpp @@ -2053,899 +2053,1041 @@ bool PwMDoc::findCategory(const QString &name, unsigned int *index) bool PwMDoc::renameCategory(const QString &category, const QString &newName) { unsigned int cat = 0; if (!findCategory(category, &cat)) return false; return renameCategory(cat, newName); } bool PwMDoc::renameCategory(unsigned int category, const QString &newName, bool dontFlagDirty) { if (category > numCategories() - 1) return false; dti.dta[category].name = newName.latin1(); if (!dontFlagDirty) flagDirty(); return true; } bool PwMDoc::delCategory(const QString &category) { unsigned int cat = 0; if (!findCategory(category, &cat)) return false; return delCategory(cat); } bool PwMDoc::delCategory(unsigned int category, bool dontFlagDirty) { if (category > numCategories() - 1) return false; // We don't delete it, if it is the last existing // category! Instead we rename it to "Default". if (numCategories() > 1) { dti.dta.erase(dti.dta.begin() + category); } else { renameCategory(category, DEFAULT_CATEGORY, dontFlagDirty); return true; } if (!dontFlagDirty) flagDirty(); return true; } void PwMDoc::delAllEmptyCat(bool dontFlagDirty) { vector<PwMCategoryItem>::iterator begin = dti.dta.begin(), end = dti.dta.end(), i = begin; while (i != end) { if (i->d.empty()) { delCategory(begin - i, dontFlagDirty); } ++i; } } void PwMDoc::getCategoryList(vector<string> *list) { PWM_ASSERT(list); list->clear(); vector<PwMCategoryItem>::iterator i = dti.dta.begin(), end = dti.dta.end(); while (i != end) { list->push_back(i->name); ++i; } } void PwMDoc::getCategoryList(QStringList *list) { PWM_ASSERT(list); list->clear(); vector<PwMCategoryItem>::iterator i = dti.dta.begin(), end = dti.dta.end(); while (i != end) { #ifndef PWM_EMBEDDED list->push_back(i->name.c_str()); #else list->append(i->name.c_str()); #endif ++i; } } void PwMDoc::getEntryList(const QString &category, QStringList *list) { PWM_ASSERT(list); unsigned int cat = 0; if (!findCategory(category, &cat)) { list->clear(); return; } getEntryList(cat, list); } void PwMDoc::getEntryList(const QString &category, vector<string> *list) { PWM_ASSERT(list); unsigned int cat = 0; if (!findCategory(category, &cat)) { list->clear(); return; } getEntryList(cat, list); } void PwMDoc::getEntryList(unsigned int category, vector<string> *list) { PWM_ASSERT(list); list->clear(); vector<PwMDataItem>::iterator begin = dti.dta[category].d.begin(), end = dti.dta[category].d.end(), i = begin; while (i != end) { list->push_back(i->desc); ++i; } } void PwMDoc::getEntryList(unsigned int category, QStringList *list) { PWM_ASSERT(list); list->clear(); vector<PwMDataItem>::iterator begin = dti.dta[category].d.begin(), end = dti.dta[category].d.end(), i = begin; while (i != end) { #ifndef PWM_EMBEDDED list->push_back(i->desc.c_str()); #else list->append(i->desc.c_str()); #endif ++i; } } bool PwMDoc::execLauncher(const QString &category, unsigned int entryIndex) { unsigned int cat = 0; if (!findCategory(category, &cat)) return false; return execLauncher(cat, entryIndex); } bool PwMDoc::execLauncher(unsigned int category, unsigned int entryIndex) { if (geteuid() == 0) { rootAlertMsgBox(); return false; } QString command(dti.dta[category].d[entryIndex].launcher.c_str()); bool wasLocked = isLocked(category, entryIndex); if (command.find("$p") != -1) { /* the user requested the password to be included * into the command. We have to ask for the password, * if it's locked. We do that by unlocking the entry */ if (!lockAt(category, entryIndex, false)) return false; } #ifndef PWM_EMBEDDED command.replace("$d", dti.dta[category].d[entryIndex].desc.c_str()); command.replace("$n", dti.dta[category].d[entryIndex].name.c_str()); command.replace("$p", dti.dta[category].d[entryIndex].pw.c_str()); command.replace("$u", dti.dta[category].d[entryIndex].url.c_str()); command.replace("$c", dti.dta[category].d[entryIndex].comment.c_str()); #else command.replace(QRegExp("$d"), dti.dta[category].d[entryIndex].desc.c_str()); command.replace(QRegExp("$n"), dti.dta[category].d[entryIndex].name.c_str()); command.replace(QRegExp("$p"), dti.dta[category].d[entryIndex].pw.c_str()); command.replace(QRegExp("$u"), dti.dta[category].d[entryIndex].url.c_str()); command.replace(QRegExp("$c"), dti.dta[category].d[entryIndex].comment.c_str()); #endif command.append(" &"); QString customXterm(conf()->confGlobXtermCommand()); if (!customXterm.isEmpty()) command = customXterm + " " + command; system(command.latin1()); lockAt(category, entryIndex, wasLocked); return true; } bool PwMDoc::goToURL(const QString &category, unsigned int entryIndex) { unsigned int cat = 0; if (!findCategory(category, &cat)) return false; return goToURL(cat, entryIndex); } bool PwMDoc::goToURL(unsigned int category, unsigned int entryIndex) { if (geteuid() == 0) { rootAlertMsgBox(); return false; } QString url(dti.dta[category].d[entryIndex].url.c_str()); if (url.isEmpty()) return false; QString customBrowser(conf()->confGlobBrowserCommand()); if (!customBrowser.isEmpty()) { browserProc.clearArguments(); browserProc << customBrowser << url; if (browserProc.start(KProcess::DontCare)) return true; } browserProc.clearArguments(); browserProc << "konqueror" << url; if (browserProc.start(KProcess::DontCare)) return true; browserProc.clearArguments(); browserProc << "mozilla" << url; if (browserProc.start(KProcess::DontCare)) return true; browserProc.clearArguments(); browserProc << "opera" << url; if (browserProc.start(KProcess::DontCare)) return true; return false; } PwMerror PwMDoc::exportToText(const QString *file) { PWM_ASSERT(file); if (QFile::exists(*file)) { if (!QFile::remove(*file)) return e_accessFile; } QFile f(*file); if (!f.open(IO_ReadWrite)) return e_openFile; if (!unlockAll_tempoary()) { f.close(); return e_lock; } // write header string header = i18n("Password table generated by\nPwM v").latin1(); header += PACKAGE_VER; header += i18n("\non ").latin1(); QDate currDate = QDate::currentDate(); QTime currTime = QTime::currentTime(); #ifndef PWM_EMBEDDED header += currDate.toString("ddd MMMM d ").latin1(); header += currTime.toString("hh:mm:ss ").latin1(); #else QString dfs = KGlobal::locale()->dateFormatShort(); bool ampm = KGlobal::locale()->use12Clock(); KGlobal::locale()->setDateFormatShort("%A %B %d"); KGlobal::locale()->setHore24Format(true); header += KGlobal::locale()->formatDate(currDate, true, KLocale::Userdefined); header += KGlobal::locale()->formatTime(currTime, true); KGlobal::locale()->setDateFormatShort(dfs); KGlobal::locale()->setHore24Format(!ampm); #endif header += tostr(currDate.year()); header += "\n==============================\n\n"; #ifndef PWM_EMBEDDED if (f.writeBlock(header.c_str(), header.length()) != (Q_LONG)header.length()) { unlockAll_tempoary(true); f.close(); return e_writeFile; } #else if (f.writeBlock(header.c_str(), header.length()) != (long)header.length()) { unlockAll_tempoary(true); f.close(); return e_writeFile; } #endif unsigned int i, numCat = numCategories(); unsigned int j, numEnt; string exp; for (i = 0; i < numCat; ++i) { numEnt = numEntries(i); exp = "\n== Category: "; exp += dti.dta[i].name; exp += " ==\n"; #ifndef PWM_EMBEDDED if (f.writeBlock(exp.c_str(), exp.length()) != (Q_LONG)exp.length()) { unlockAll_tempoary(true); f.close(); return e_writeFile; } #else if (f.writeBlock(exp.c_str(), exp.length()) != (long)exp.length()) { unlockAll_tempoary(true); f.close(); return e_writeFile; } #endif for (j = 0; j < numEnt; ++j) { exp = "\n-- "; exp += dti.dta[i].d[j].desc; exp += " --\n"; exp += i18n("Username: ").latin1(); exp += dti.dta[i].d[j].name; exp += "\n"; exp += i18n("Password: ").latin1(); exp += dti.dta[i].d[j].pw; exp += "\n"; exp += i18n("Comment: ").latin1(); exp += dti.dta[i].d[j].comment; exp += "\n"; exp += i18n("URL: ").latin1(); exp += dti.dta[i].d[j].url; exp += "\n"; exp += i18n("Launcher: ").latin1(); exp += dti.dta[i].d[j].launcher; exp += "\n"; #ifndef PWM_EMBEDDED if (f.writeBlock(exp.c_str(), exp.length()) != (Q_LONG)exp.length()) { unlockAll_tempoary(true); f.close(); return e_writeFile; } #else if (f.writeBlock(exp.c_str(), exp.length()) != (long)exp.length()) { unlockAll_tempoary(true); f.close(); return e_writeFile; } #endif } } unlockAll_tempoary(true); f.close(); return e_success; } PwMerror PwMDoc::importFromText(const QString *file, int format) { PWM_ASSERT(file); if (format == 0) return importText_PwM(file); else if (format == -1) { // probe for all formats if (importText_PwM(file) == e_success) return e_success; dti.clear(); emitDataChanged(this); // add next format here... return e_fileFormat; } return e_invalidArg; } PwMerror PwMDoc::importText_PwM(const QString *file) { +#ifndef PWM_EMBEDDED PWM_ASSERT(file); FILE *f; int tmp; ssize_t ret; string curCat; unsigned int entriesRead = 0; PwMDataItem currItem; f = fopen(file->latin1(), "r"); if (!f) return e_openFile; size_t ch_tmp_size = 1024; char *ch_tmp = (char*)malloc(ch_tmp_size); if (!ch_tmp) { fclose(f); return e_outOfMem; } // - check header if (getline(&ch_tmp, &ch_tmp_size, f) == -1) // skip first line. goto formatError; // check version-string and return version in "ch_tmp". if (fscanf(f, "PwM v%s", ch_tmp) != 1) { // header not recognized as PwM generated header goto formatError; } // set filepointer behind version-string-line previously checked if (getline(&ch_tmp, &ch_tmp_size, f) == -1) goto formatError; // skip next line containing the build-date if (getline(&ch_tmp, &ch_tmp_size, f) == -1) goto formatError; // read header termination line if (getline(&ch_tmp, &ch_tmp_size, f) == -1) goto formatError; if (strcmp(ch_tmp, "==============================\n")) goto formatError; // - read entries do { // find beginning of next category do { tmp = fgetc(f); } while (tmp == '\n' && tmp != EOF); if (tmp == EOF) break; // decrement filepos by one fseek(f, -1, SEEK_CUR); // read cat-name if (getline(&ch_tmp, &ch_tmp_size, f) == -1) goto formatError; // check cat-name format if (memcmp(ch_tmp, "== Category: ", 13) != 0) goto formatError; if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " ==", 3) != 0) goto formatError; // copy cat-name curCat.assign(ch_tmp + 13, strlen(ch_tmp) - 1 - 16); do { // find beginning of next entry do { tmp = fgetc(f); } while (tmp == '\n' && tmp != EOF && tmp != '='); if (tmp == EOF) break; if (tmp == '=') { fseek(f, -1, SEEK_CUR); break; } // decrement filepos by one fseek(f, -1, SEEK_CUR); // read desc-line if (getline(&ch_tmp, &ch_tmp_size, f) == -1) goto formatError; // check desc-line format if (memcmp(ch_tmp, "-- ", 3) != 0) goto formatError; if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " --", 3) != 0) goto formatError; // add desc-line currItem.desc.assign(ch_tmp + 3, strlen(ch_tmp) - 1 - 6); // read username-line if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1) goto formatError; if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.name)) goto formatError; // read pw-line if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1) goto formatError; if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.pw)) goto formatError; // read comment-line if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1) goto formatError; if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.comment)) goto formatError; // read URL-line if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1) goto formatError; if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.url)) goto formatError; // read launcher-line if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1) goto formatError; if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.launcher)) goto formatError; currItem.lockStat = true; currItem.listViewPos = -1; addEntry(curCat.c_str(), &currItem, true); ++entriesRead; } while (1); } while (1); if (!entriesRead) goto formatError; free(ch_tmp); fclose(f); flagDirty(); return e_success; formatError: free(ch_tmp); fclose(f); return e_fileFormat; +#else + PWM_ASSERT(file); + QFile f(file->latin1()); + int tmp; + ssize_t ret; + string curCat; + unsigned int entriesRead = 0; + PwMDataItem currItem; + bool res = f.open(IO_ReadOnly); + if (res == false) + return e_openFile; + + unsigned int ch_tmp_size = 1024; + char *ch_tmp = (char*)malloc(ch_tmp_size); + if (!ch_tmp) { + f.close(); + return e_outOfMem; + } + + // - check header + if (f.readLine(ch_tmp, ch_tmp_size) == -1) // skip first line. + goto formatError; + + //US read fileversion first, then check if ok. + if (f.readLine(ch_tmp, ch_tmp_size) == -1) + goto formatError; + + // check version-string and return version in "ch_tmp". + //US if (fscanf(f, "PwM v%s", ch_tmp) != 1) { + //US // header not recognized as PwM generated header + //US goto formatError; + //US } + //US set filepointer behind version-string-line previously checked + //US if (f.readLine(ch_tmp, ch_tmp_size) == -1) + //US goto formatError; + // skip next line containing the build-date + if (f.readLine(ch_tmp, ch_tmp_size) == -1) + goto formatError; + // read header termination line + if (f.readLine(ch_tmp, ch_tmp_size) == -1) + goto formatError; + if (strcmp(ch_tmp, "==============================\n")) + goto formatError; + + // - read entries + do { + // find beginning of next category + do { + tmp = f.getch(); + } while (tmp == '\n' && tmp != EOF); + if (tmp == EOF) + break; + + // decrement filepos by one + f.at(f.at()-1); + // read cat-name + if (f.readLine(ch_tmp, ch_tmp_size) == -1) + goto formatError; + // check cat-name format + if (memcmp(ch_tmp, "== Category: ", 13) != 0) + goto formatError; + if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " ==", 3) != 0) + goto formatError; + // copy cat-name + curCat.assign(ch_tmp + 13, strlen(ch_tmp) - 1 - 16); + + do { + // find beginning of next entry + do { + tmp = f.getch(); + } while (tmp == '\n' && tmp != EOF && tmp != '='); + if (tmp == EOF) + break; + if (tmp == '=') { + f.at(f.at()-1); + break; + } + // decrement filepos by one + f.at(f.at()-1); + // read desc-line + if (f.readLine(ch_tmp, ch_tmp_size) == -1) + goto formatError; + // check desc-line format + if (memcmp(ch_tmp, "-- ", 3) != 0) + goto formatError; + if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " --", 3) != 0) + goto formatError; + // add desc-line + currItem.desc.assign(ch_tmp + 3, strlen(ch_tmp) - 1 - 6); + + // read username-line + if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1) + goto formatError; + if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.name)) + goto formatError; + + // read pw-line + if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1) + goto formatError; + if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.pw)) + goto formatError; + + // read comment-line + if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1) + goto formatError; + if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.comment)) + goto formatError; + + // read URL-line + if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1) + goto formatError; + if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.url)) + goto formatError; + + // read launcher-line + if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1) + goto formatError; + if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.launcher)) + goto formatError; + + currItem.lockStat = true; + currItem.listViewPos = -1; + addEntry(curCat.c_str(), &currItem, true); + ++entriesRead; + } while (1); + } while (1); + if (!entriesRead) + goto formatError; + + free(ch_tmp); + f.close(); + flagDirty(); + return e_success; + + formatError: + free(ch_tmp); + f.close(); + return e_fileFormat; + +#endif + } bool PwMDoc::textExtractEntry_PwM(const char *in, ssize_t in_size, string *out) { PWM_ASSERT(in && out); ssize_t i = 0, len = in_size - 1; while (i < len) { if (in[i] == ':') break; ++i; } i += 2; *out = ""; out->append(in + i, in_size - i - 1); return true; } PwMerror PwMDoc::exportToGpasman(const QString *file) { PWM_ASSERT(file); GpasmanFile gp; int ret; if (!unlockAll_tempoary()) return e_lock; QString gpmPassword; while (1) { gpmPassword = requestNewMpw(0); if (gpmPassword == "") { unlockAll_tempoary(true); return e_noPw; } if (gpmPassword.length() < 4) { gpmPwLenErrMsgBox(); } else { break; } } ret = gp.save_init(file->latin1(), gpmPassword.latin1()); if (ret != 1) { unlockAll_tempoary(true); return e_accessFile; } char *entry[4]; unsigned int numCat = numCategories(), i; unsigned int numEntr, j; int descLen, nameLen, pwLen, commentLen; for (i = 0; i < numCat; ++i) { numEntr = numEntries(i); for (j = 0; j < numEntr; ++j) { descLen = dti.dta[i].d[j].desc.length(); nameLen = dti.dta[i].d[j].name.length(); pwLen = dti.dta[i].d[j].pw.length(); commentLen = dti.dta[i].d[j].comment.length(); entry[0] = new char[descLen + 1]; entry[1] = new char[nameLen + 1]; entry[2] = new char[pwLen + 1]; entry[3] = new char[commentLen + 1]; strcpy(entry[0], descLen == 0 ? " " : dti.dta[i].d[j].desc.c_str()); strcpy(entry[1], nameLen == 0 ? " " : dti.dta[i].d[j].name.c_str()); strcpy(entry[2], pwLen == 0 ? " " : dti.dta[i].d[j].pw.c_str()); strcpy(entry[3], commentLen == 0 ? " " : dti.dta[i].d[j].comment.c_str()); entry[0][descLen == 0 ? descLen + 1 : descLen] = '\0'; entry[1][nameLen == 0 ? nameLen + 1 : nameLen] = '\0'; entry[2][pwLen == 0 ? pwLen + 1 : pwLen] = '\0'; entry[3][commentLen == 0 ? commentLen + 1 : commentLen] = '\0'; ret = gp.save_entry(entry); if (ret == -1){ delete [] entry[0]; delete [] entry[1]; delete [] entry[2]; delete [] entry[3]; gp.save_finalize(); unlockAll_tempoary(true); return e_writeFile; } delete [] entry[0]; delete [] entry[1]; delete [] entry[2]; delete [] entry[3]; } } unlockAll_tempoary(true); if (gp.save_finalize() == -1) return e_writeFile; return e_success; } PwMerror PwMDoc::importFromGpasman(const QString *file) { PWM_ASSERT(file); QString pw = requestMpw(false); if (pw == "") return e_noPw; GpasmanFile gp; int ret, i; PwMerror ret2; char *entry[4]; PwMDataItem tmpData; ret = gp.load_init(file->latin1(), pw.latin1()); if (ret != 1) return e_accessFile; do { ret = gp.load_entry(entry); if(ret != 1) break; tmpData.desc = entry[0]; tmpData.name = entry[1]; tmpData.pw = entry[2]; tmpData.comment = entry[3]; tmpData.lockStat = true; tmpData.listViewPos = -1; ret2 = addEntry(DEFAULT_CATEGORY, &tmpData, true); for (i = 0; i < 4; ++i) free(entry[i]); if (ret2 == e_maxAllowedEntr) { gp.load_finalize(); return e_maxAllowedEntr; } } while (1); gp.load_finalize(); if (isDocEmpty()) return e_wrongPw; // we assume this. flagDirty(); return e_success; } void PwMDoc::ensureLvp() { if (isDocEmpty()) return; vector< vector<PwMDataItem>::iterator > undefined; vector< vector<PwMDataItem>::iterator >::iterator undefBegin, undefEnd, undefI; vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), catEnd = dti.dta.end(), catI = catBegin; vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; int lvpTop, tmpLvp; while (catI != catEnd) { lvpTop = -1; undefined.clear(); entrBegin = catI->d.begin(); entrEnd = catI->d.end(); entrI = entrBegin; while (entrI != entrEnd) { tmpLvp = entrI->listViewPos; if (tmpLvp == -1) undefined.push_back(entrI); else if (tmpLvp > lvpTop) lvpTop = tmpLvp; ++entrI; } undefBegin = undefined.begin(); undefEnd = undefined.end(); undefI = undefBegin; while (undefI != undefEnd) { (*undefI)->listViewPos = ++lvpTop; ++undefI; } ++catI; } } QString PwMDoc::getTitle() { /* NOTE: We have to ensure, that the returned title * is unique and not reused somewhere else while * this document is valid (open). */ QString title(getFilename()); if (title.isEmpty()) { if (unnamedNum == 0) { unnamedNum = PwMDocList::getNewUnnamedNumber(); PWM_ASSERT(unnamedNum != 0); } title = DEFAULT_TITLE; title += " "; title += tostr(unnamedNum).c_str(); } return title; } bool PwMDoc::tryDelete() { if (deleted) return true; int ret; if (isDirty()) { ret = dirtyAskSave(getTitle()); if (ret == 0) { // save to disk if (!saveDocUi(this)) goto out_ignore; } else if (ret == 1) { // don't save and delete goto out_accept; } else { // cancel operation goto out_ignore; } } out_accept: deleted = true; delete this; return true; out_ignore: return false; } #ifdef PWM_EMBEDDED //US ENH: this is the magic function that syncronizes the this doc with the remote doc //US it could have been defined as static, but I did not want to. PwMerror PwMDoc::syncronize(KSyncManager* manager, PwMDoc* syncLocal , PwMDoc* syncRemote, int mode ) { int addedPasswordsLocal = 0; int addedPasswordsRemote = 0; int deletedPasswordsRemote = 0; int deletedPasswordsLocal = 0; int changedLocal = 0; int changedRemote = 0; PwMSyncItem* syncItemLocal; PwMSyncItem* syncItemRemote; QString mCurrentSyncName = manager->getCurrentSyncName(); QString mCurrentSyncDevice = manager->getCurrentSyncDevice(); bool fullDateRange = false; int take; // local->resetTempSyncStat(); QDateTime mLastSync = QDateTime::currentDateTime(); QDateTime modifiedSync = mLastSync; unsigned int index; //Step 1. Find syncinfo in Local file and create if not existent. bool found = syncLocal->findSyncData(mCurrentSyncDevice, &index); if (found == false) { PwMSyncItem newSyncItemLocal; newSyncItemLocal.syncName = mCurrentSyncDevice; newSyncItemLocal.lastSyncDate = mLastSync; syncLocal->addSyncDataEntry(&newSyncItemLocal, true); found = syncLocal->findSyncData(mCurrentSyncDevice, &index); if (found == false) { qDebug("PwMDoc::syncronize : newly created local sync data could not be found"); return e_syncError; } } syncItemLocal = syncLocal->getSyncDataEntry(index); qDebug("Last Sync %s ", syncItemLocal->lastSyncDate.toString().latin1()); //Step 2. Find syncinfo in remote file and create if not existent. found = syncRemote->findSyncData(mCurrentSyncName, &index); if (found == false) { qDebug("FULLDATE 1"); fullDateRange = true; PwMSyncItem newSyncItemRemote; newSyncItemRemote.syncName = mCurrentSyncName; newSyncItemRemote.lastSyncDate = mLastSync; syncRemote->addSyncDataEntry(&newSyncItemRemote, true); found = syncRemote->findSyncData(mCurrentSyncName, &index); if (found == false) { qDebug("PwMDoc::syncronize : newly created remote sync data could not be found"); return e_syncError; } } syncItemRemote = syncRemote->getSyncDataEntry(index); //and remove the found entry here. We will reenter it later again. //US syncRemote->delSyncDataEntry(index, true); if ( syncItemLocal->lastSyncDate == mLastSync ) { qDebug("FULLDATE 2"); fullDateRange = true; } if ( ! fullDateRange ) { if ( syncItemLocal->lastSyncDate != syncItemRemote->lastSyncDate ) { // qDebug("set fulldate to true %s %s" ,addresseeLSync->dtStart().toString().latin1(), addresseeRSync->dtStart().toString().latin1() ); //qDebug("%d %d %d %d ", addresseeLSync->dtStart().time().second(), addresseeLSync->dtStart().time().msec() , addresseeRSync->dtStart().time().second(), addresseeRSync->dtStart().time().msec()); fullDateRange = true; qDebug("FULLDATE 3 %s %s", syncItemLocal->lastSyncDate.toString().latin1() , syncItemRemote->lastSyncDate.toString().latin1() ); } } // fullDateRange = true; // debug only! if ( fullDateRange ) mLastSync = QDateTime::currentDateTime().addDays( -100*365); else mLastSync = syncItemLocal->lastSyncDate; qDebug("*************************** "); // qDebug("mLastAddressbookSync %s ",mLastAddressbookSync.toString().latin1() ); QStringList er = syncRemote->getIDEntryList(); PwMDataItem* inRemote ;//= er.first(); PwMDataItem* inLocal; unsigned int catLocal, indexLocal; unsigned int catRemote, indexRemote; QString uid; manager->showProgressBar(0, i18n("Syncing - close to abort!"), er.count()); int modulo = (er.count()/10)+1; unsigned int incCounter = 0; while ( incCounter < er.count()) { if (manager->isProgressBarCanceled()) return e_syncError; if ( incCounter % modulo == 0 ) manager->showProgressBar(incCounter); uid = er[ incCounter ]; qDebug("sync uid %s from remote file", uid.latin1()); qApp->processEvents(); inLocal = syncLocal->findEntryByID( uid, &catLocal, &indexLocal ); inRemote = syncRemote->findEntryByID( uid, &catRemote, &indexRemote ); PWM_ASSERT(inRemote); if ( inLocal != 0 ) { // maybe conflict - same uid in both files if ( (take = takePwMDataItem( inLocal, inRemote, mLastSync, mode, fullDateRange) ) ) { //qDebug("take %d %s ", take, inL.summary().latin1()); if ( take == 3 ) return e_syncError; if ( take == 1 ) {// take local //US syncRemote->removeAddressee( inRemote ); (*inRemote) = (*inLocal); //US syncRemote->insertAddressee( inRemote , false); ++changedRemote; } else { // take == 2 take remote //US syncLocal->removeAddressee( inLocal ); (*inLocal) = (*inRemote); //US syncLocal->insertAddressee( inLocal , false ); ++changedLocal; } } } else { // no conflict if ( inRemote->meta.update > mLastSync || mode == 5 ) { inRemote->meta.update = modifiedSync; //first check if we have a matching category in the local file const string* remotecat = syncRemote->getCategory(catRemote); //US syncRemote->insertAddressee( inRemote, false ); //US syncLocal->insertAddressee( inRemote, false ); syncLocal->addEntry(remotecat->c_str(), inRemote, true, false); ++addedPasswordsLocal; } else { // pending checkExternSyncAddressee(addresseeRSyncSharp, inR); syncRemote->delEntry(catRemote, indexRemote, true); //USsyncRemote->removeAddressee( inRemote ); ++deletedPasswordsRemote; } } ++incCounter; } er.clear(); QStringList el = syncLocal->getIDEntryList(); modulo = (el.count()/10)+1; manager->showProgressBar(0, i18n("Add / remove addressees"), el.count()); incCounter = 0; while ( incCounter < el.count()) { qApp->processEvents(); if (manager->isProgressBarCanceled()) |