summaryrefslogtreecommitdiffabout
path: root/pwmanager
Unidiff
Diffstat (limited to 'pwmanager') (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/pwmanager/pwmdoc.cpp102
-rw-r--r--pwmanager/pwmanager/pwmdoc.h23
2 files changed, 60 insertions, 65 deletions
diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp
index 2a7b11d..e9906a4 100644
--- a/pwmanager/pwmanager/pwmdoc.cpp
+++ b/pwmanager/pwmanager/pwmdoc.cpp
@@ -757,2676 +757,2690 @@ PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress,
757 case PWM_HASH_SHA256: 757 case PWM_HASH_SHA256:
758 /*... fall through */ 758 /*... fall through */
759 case PWM_HASH_SHA384: 759 case PWM_HASH_SHA384:
760 case PWM_HASH_SHA512: 760 case PWM_HASH_SHA512:
761 case PWM_HASH_MD5: 761 case PWM_HASH_MD5:
762 case PWM_HASH_RMD160: 762 case PWM_HASH_RMD160:
763 case PWM_HASH_TIGER: { 763 case PWM_HASH_TIGER: {
764 if (!LibGCryptIf::available()) 764 if (!LibGCryptIf::available())
765 return e_hashNotImpl; 765 return e_hashNotImpl;
766 LibGCryptIf gc; 766 LibGCryptIf gc;
767 PwMerror err; 767 PwMerror err;
768 unsigned char *buf; 768 unsigned char *buf;
769 size_t hashLen; 769 size_t hashLen;
770 err = gc.hash(&buf, 770 err = gc.hash(&buf,
771 &hashLen, 771 &hashLen,
772 reinterpret_cast<const unsigned char *>(pw->latin1()), 772 reinterpret_cast<const unsigned char *>(pw->latin1()),
773 pw->length(), 773 pw->length(),
774 keyHash); 774 keyHash);
775 if (err != e_success) 775 if (err != e_success)
776 return e_hashNotImpl; 776 return e_hashNotImpl;
777 string calcHash(reinterpret_cast<const char *>(buf), 777 string calcHash(reinterpret_cast<const char *>(buf),
778 static_cast<string::size_type>(hashLen)); 778 static_cast<string::size_type>(hashLen));
779 delete [] buf; 779 delete [] buf;
780 // read hash from header 780 // read hash from header
781 string readHash; 781 string readHash;
782 size_t i; 782 size_t i;
783 for (i = 0; i < hashLen; ++i) 783 for (i = 0; i < hashLen; ++i)
784 readHash.push_back(f->getch()); 784 readHash.push_back(f->getch());
785 if (calcHash != readHash) 785 if (calcHash != readHash)
786 return e_wrongPw;// hash doesn't match (wrong key) 786 return e_wrongPw;// hash doesn't match (wrong key)
787 break; 787 break;
788 } 788 }
789 default: { 789 default: {
790 return e_hashNotImpl; 790 return e_hashNotImpl;
791 } } 791 } }
792 // read the data-hash from the file 792 // read the data-hash from the file
793 unsigned int hashLen, i; 793 unsigned int hashLen, i;
794 switch (*dataHashType) { 794 switch (*dataHashType) {
795 case PWM_HASH_SHA1: 795 case PWM_HASH_SHA1:
796 hashLen = SHA1_HASH_LEN_BYTE; 796 hashLen = SHA1_HASH_LEN_BYTE;
797 break; 797 break;
798 case PWM_HASH_SHA256: 798 case PWM_HASH_SHA256:
799 /*... fall through */ 799 /*... fall through */
800 case PWM_HASH_SHA384: 800 case PWM_HASH_SHA384:
801 case PWM_HASH_SHA512: 801 case PWM_HASH_SHA512:
802 case PWM_HASH_MD5: 802 case PWM_HASH_MD5:
803 case PWM_HASH_RMD160: 803 case PWM_HASH_RMD160:
804 case PWM_HASH_TIGER: { 804 case PWM_HASH_TIGER: {
805 if (!LibGCryptIf::available()) 805 if (!LibGCryptIf::available())
806 return e_hashNotImpl; 806 return e_hashNotImpl;
807 LibGCryptIf gc; 807 LibGCryptIf gc;
808 hashLen = gc.hashLength(*dataHashType); 808 hashLen = gc.hashLength(*dataHashType);
809 if (hashLen == 0) 809 if (hashLen == 0)
810 return e_hashNotImpl; 810 return e_hashNotImpl;
811 break; 811 break;
812 } 812 }
813 default: 813 default:
814 return e_hashNotImpl; 814 return e_hashNotImpl;
815 } 815 }
816 *dataHash = ""; 816 *dataHash = "";
817 for (i = 0; i < hashLen; ++i) { 817 for (i = 0; i < hashLen; ++i) {
818 tmpRet = f->getch(); 818 tmpRet = f->getch();
819 if (tmpRet == -1) 819 if (tmpRet == -1)
820 return e_fileFormat; 820 return e_fileFormat;
821 dataHash->push_back(static_cast<char>(tmpRet)); 821 dataHash->push_back(static_cast<char>(tmpRet));
822 } 822 }
823 *headerLength = f->at(); 823 *headerLength = f->at();
824#ifndef PWM_EMBEDDED 824#ifndef PWM_EMBEDDED
825 printDebug(string("opening file { compress: ") 825 printDebug(string("opening file { compress: ")
826 + tostr(static_cast<int>(*compress)) + " cryptAlgo: " 826 + tostr(static_cast<int>(*compress)) + " cryptAlgo: "
827 + tostr(static_cast<int>(*cryptAlgo)) + " keyHashAlgo: " 827 + tostr(static_cast<int>(*cryptAlgo)) + " keyHashAlgo: "
828 + tostr(static_cast<int>(keyHash)) 828 + tostr(static_cast<int>(keyHash))
829 + " }"); 829 + " }");
830#else 830#else
831 printDebug(string("opening file { compress: ") 831 printDebug(string("opening file { compress: ")
832 + tostr((int)(*compress)) + " cryptAlgo: " 832 + tostr((int)(*compress)) + " cryptAlgo: "
833 + tostr((int)(*cryptAlgo)) + " keyHashAlgo: " 833 + tostr((int)(*cryptAlgo)) + " keyHashAlgo: "
834 + tostr((int)(keyHash)) 834 + tostr((int)(keyHash))
835 + " }"); 835 + " }");
836#endif 836#endif
837 837
838 return e_success; 838 return e_success;
839} 839}
840 840
841PwMerror PwMDoc::writeDataHash(char dataHash, string *d, QFile *f) 841PwMerror PwMDoc::writeDataHash(char dataHash, string *d, QFile *f)
842{ 842{
843 PWM_ASSERT(d); 843 PWM_ASSERT(d);
844 PWM_ASSERT(f); 844 PWM_ASSERT(f);
845 845
846 switch (dataHash) { 846 switch (dataHash) {
847 case PWM_HASH_SHA1: { 847 case PWM_HASH_SHA1: {
848 const int hashLen = SHA1_HASH_LEN_BYTE; 848 const int hashLen = SHA1_HASH_LEN_BYTE;
849 Sha1 h; 849 Sha1 h;
850 h.sha1_write(reinterpret_cast<const byte *>(d->c_str()), d->size()); 850 h.sha1_write(reinterpret_cast<const byte *>(d->c_str()), d->size());
851 string hRet = h.sha1_read(); 851 string hRet = h.sha1_read();
852 if (f->writeBlock(hRet.c_str(), hashLen) != hashLen) 852 if (f->writeBlock(hRet.c_str(), hashLen) != hashLen)
853 return e_writeFile; 853 return e_writeFile;
854 break; 854 break;
855 } 855 }
856 case PWM_HASH_SHA256: 856 case PWM_HASH_SHA256:
857 /*... fall through */ 857 /*... fall through */
858 case PWM_HASH_SHA384: 858 case PWM_HASH_SHA384:
859 case PWM_HASH_SHA512: 859 case PWM_HASH_SHA512:
860 case PWM_HASH_MD5: 860 case PWM_HASH_MD5:
861 case PWM_HASH_RMD160: 861 case PWM_HASH_RMD160:
862 case PWM_HASH_TIGER: { 862 case PWM_HASH_TIGER: {
863 if (!LibGCryptIf::available()) 863 if (!LibGCryptIf::available())
864 return e_hashNotImpl; 864 return e_hashNotImpl;
865 LibGCryptIf gc; 865 LibGCryptIf gc;
866 PwMerror err; 866 PwMerror err;
867 unsigned char *buf; 867 unsigned char *buf;
868 size_t hashLen; 868 size_t hashLen;
869 err = gc.hash(&buf, 869 err = gc.hash(&buf,
870 &hashLen, 870 &hashLen,
871 reinterpret_cast<const unsigned char *>(d->c_str()), 871 reinterpret_cast<const unsigned char *>(d->c_str()),
872 d->size(), 872 d->size(),
873 dataHash); 873 dataHash);
874 if (err != e_success) 874 if (err != e_success)
875 return e_hashNotImpl; 875 return e_hashNotImpl;
876 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen) 876 if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen)
877 != static_cast<Q_LONG>(hashLen)) { 877 != static_cast<Q_LONG>(hashLen)) {
878 delete [] buf; 878 delete [] buf;
879 return e_hashNotImpl; 879 return e_hashNotImpl;
880 } 880 }
881 delete [] buf; 881 delete [] buf;
882 break; 882 break;
883 } 883 }
884 default: { 884 default: {
885 return e_hashNotImpl; 885 return e_hashNotImpl;
886 } } 886 } }
887 887
888 return e_success; 888 return e_success;
889} 889}
890 890
891bool PwMDoc::backupFile(const QString &filePath) 891bool PwMDoc::backupFile(const QString &filePath)
892{ 892{
893 QFileInfo fi(filePath); 893 QFileInfo fi(filePath);
894 if (!fi.exists()) 894 if (!fi.exists())
895 return true; // Yes, true is correct. 895 return true; // Yes, true is correct.
896 QString pathOnly(fi.dirPath(true)); 896 QString pathOnly(fi.dirPath(true));
897 QString nameOnly(fi.fileName()); 897 QString nameOnly(fi.fileName());
898 QString backupPath = pathOnly 898 QString backupPath = pathOnly
899 + "/~" 899 + "/~"
900 + nameOnly 900 + nameOnly
901 + ".backup"; 901 + ".backup";
902 return copyFile(filePath, backupPath); 902 return copyFile(filePath, backupPath);
903} 903}
904 904
905bool PwMDoc::copyFile(const QString &src, const QString &dst) 905bool PwMDoc::copyFile(const QString &src, const QString &dst)
906{ 906{
907 QFileInfo fi(src); 907 QFileInfo fi(src);
908 if (!fi.exists()) 908 if (!fi.exists())
909 return false; 909 return false;
910 if (QFile::exists(dst)) { 910 if (QFile::exists(dst)) {
911 if (!QFile::remove(dst)) 911 if (!QFile::remove(dst))
912 return false; 912 return false;
913 } 913 }
914 QFile srcFd(src); 914 QFile srcFd(src);
915 if (!srcFd.open(IO_ReadOnly)) 915 if (!srcFd.open(IO_ReadOnly))
916 return false; 916 return false;
917 QFile dstFd(dst); 917 QFile dstFd(dst);
918 if (!dstFd.open(IO_ReadWrite)) { 918 if (!dstFd.open(IO_ReadWrite)) {
919 srcFd.close(); 919 srcFd.close();
920 return false; 920 return false;
921 } 921 }
922 const int tmpBuf_size = 512; 922 const int tmpBuf_size = 512;
923 char tmpBuf[tmpBuf_size]; 923 char tmpBuf[tmpBuf_size];
924 Q_LONG bytesRead, bytesWritten; 924 Q_LONG bytesRead, bytesWritten;
925 925
926 while (!srcFd.atEnd()) { 926 while (!srcFd.atEnd()) {
927 bytesRead = srcFd.readBlock(tmpBuf, 927 bytesRead = srcFd.readBlock(tmpBuf,
928 static_cast<Q_ULONG>(tmpBuf_size)); 928 static_cast<Q_ULONG>(tmpBuf_size));
929 if (bytesRead == -1) { 929 if (bytesRead == -1) {
930 srcFd.close(); 930 srcFd.close();
931 dstFd.close(); 931 dstFd.close();
932 return false; 932 return false;
933 } 933 }
934 bytesWritten = dstFd.writeBlock(tmpBuf, 934 bytesWritten = dstFd.writeBlock(tmpBuf,
935 static_cast<Q_ULONG>(bytesRead)); 935 static_cast<Q_ULONG>(bytesRead));
936 if (bytesWritten != bytesRead) { 936 if (bytesWritten != bytesRead) {
937 srcFd.close(); 937 srcFd.close();
938 dstFd.close(); 938 dstFd.close();
939 return false; 939 return false;
940 } 940 }
941 } 941 }
942 srcFd.close(); 942 srcFd.close();
943 dstFd.close(); 943 dstFd.close();
944 return true; 944 return true;
945} 945}
946 946
947PwMerror PwMDoc::addEntry(const QString &category, PwMDataItem *d, 947PwMerror PwMDoc::addEntry(const QString &category, PwMDataItem *d,
948 bool dontFlagDirty, bool updateMeta) 948 bool dontFlagDirty, bool updateMeta)
949{ 949{
950 PWM_ASSERT(d); 950 PWM_ASSERT(d);
951 unsigned int cat = 0; 951 unsigned int cat = 0;
952 952
953 if (isDeepLocked()) { 953 if (isDeepLocked()) {
954 PwMerror ret; 954 PwMerror ret;
955 ret = deepLock(false); 955 ret = deepLock(false);
956 if (ret != e_success) 956 if (ret != e_success)
957 return e_lock; 957 return e_lock;
958 } 958 }
959 959
960 addCategory(category, &cat); 960 addCategory(category, &cat);
961 961
962 if (numEntries(category) >= maxEntries) 962 if (numEntries(category) >= maxEntries)
963 return e_maxAllowedEntr; 963 return e_maxAllowedEntr;
964 964
965 vector<unsigned int> foundPositions; 965 vector<unsigned int> foundPositions;
966 /* historically this was: 966 /* historically this was:
967 *const int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME | 967 *const int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME |
968 * SEARCH_IN_URL | SEARCH_IN_LAUNCHER; 968 * SEARCH_IN_URL | SEARCH_IN_LAUNCHER;
969 * But for now we only search in desc. 969 * But for now we only search in desc.
970 * That's a tweak to be KWallet compatible. But it should not add 970 * That's a tweak to be KWallet compatible. But it should not add
971 * usability-drop onto PwManager, does it? 971 * usability-drop onto PwManager, does it?
972 * (And yes, "int" was a bug. Correct is "unsigned int") 972 * (And yes, "int" was a bug. Correct is "unsigned int")
973 */ 973 */
974 const unsigned int searchIn = SEARCH_IN_DESC; 974 const unsigned int searchIn = SEARCH_IN_DESC;
975 findEntry(cat, *d, searchIn, &foundPositions, true); 975 findEntry(cat, *d, searchIn, &foundPositions, true);
976 if (foundPositions.size()) { 976 if (foundPositions.size()) {
977 // DOH! We found this entry. 977 // DOH! We found this entry.
978 return e_entryExists; 978 return e_entryExists;
979 } 979 }
980 980
981 d->listViewPos = -1; 981 d->listViewPos = -1;
982 d->lockStat = conf()->confGlobNewEntrLockStat(); 982 d->lockStat = conf()->confGlobNewEntrLockStat();
983 if (updateMeta) { 983 if (updateMeta) {
984 d->meta.create = QDateTime::currentDateTime(); 984 d->meta.create = QDateTime::currentDateTime();
985 d->meta.update = d->meta.create; 985 d->meta.update = d->meta.create;
986 } 986 }
987 dti.dta[cat].d.push_back(*d); 987 dti.dta[cat].d.push_back(*d);
988 988
989 delAllEmptyCat(true); 989 delAllEmptyCat(true);
990 990
991 if (!dontFlagDirty) 991 if (!dontFlagDirty)
992 flagDirty(); 992 flagDirty();
993 return e_success; 993 return e_success;
994} 994}
995 995
996PwMerror PwMDoc::addCategory(const QString &category, unsigned int *categoryIndex, 996PwMerror PwMDoc::addCategory(const QString &category, unsigned int *categoryIndex,
997 bool checkIfExist) 997 bool checkIfExist)
998{ 998{
999 if (isDeepLocked()) { 999 if (isDeepLocked()) {
1000 PwMerror ret; 1000 PwMerror ret;
1001 ret = deepLock(false); 1001 ret = deepLock(false);
1002 if (ret != e_success) 1002 if (ret != e_success)
1003 return e_lock; 1003 return e_lock;
1004 } 1004 }
1005 if (checkIfExist) { 1005 if (checkIfExist) {
1006 if (findCategory(category, categoryIndex)) 1006 if (findCategory(category, categoryIndex))
1007 return e_categoryExists; 1007 return e_categoryExists;
1008 } 1008 }
1009 PwMCategoryItem item; 1009 PwMCategoryItem item;
1010 item.name = category.latin1(); 1010 item.name = category.latin1();
1011 dti.dta.push_back(item); 1011 dti.dta.push_back(item);
1012 if (categoryIndex) 1012 if (categoryIndex)
1013 *categoryIndex = dti.dta.size() - 1; 1013 *categoryIndex = dti.dta.size() - 1;
1014 return e_success; 1014 return e_success;
1015} 1015}
1016 1016
1017bool PwMDoc::delEntry(const QString &category, unsigned int index, bool dontFlagDirty) 1017bool PwMDoc::delEntry(const QString &category, unsigned int index, bool dontFlagDirty)
1018{ 1018{
1019 unsigned int cat = 0; 1019 unsigned int cat = 0;
1020 1020
1021 if (!findCategory(category, &cat)) { 1021 if (!findCategory(category, &cat)) {
1022 BUG(); 1022 BUG();
1023 return false; 1023 return false;
1024 } 1024 }
1025 1025
1026 return delEntry(cat, index, dontFlagDirty); 1026 return delEntry(cat, index, dontFlagDirty);
1027} 1027}
1028 1028
1029bool PwMDoc::delEntry(unsigned int category, unsigned int index, bool dontFlagDirty) 1029bool PwMDoc::delEntry(unsigned int category, unsigned int index, bool dontFlagDirty)
1030{ 1030{
1031 if (isDeepLocked()) 1031 if (isDeepLocked())
1032 return false; 1032 return false;
1033 if (index > dti.dta[category].d.size() - 1) 1033 if (index > dti.dta[category].d.size() - 1)
1034 return false; 1034 return false;
1035 getDataChangedLock(); 1035 getDataChangedLock();
1036 if (!lockAt(category, index, false)) { 1036 if (!lockAt(category, index, false)) {
1037 putDataChangedLock(); 1037 putDataChangedLock();
1038 return false; 1038 return false;
1039 } 1039 }
1040 putDataChangedLock(); 1040 putDataChangedLock();
1041 int lvPos = dti.dta[category].d[index].listViewPos; 1041 int lvPos = dti.dta[category].d[index].listViewPos;
1042 1042
1043 // delete entry 1043 // delete entry
1044 dti.dta[category].d.erase(dti.dta[category].d.begin() + index); 1044 dti.dta[category].d.erase(dti.dta[category].d.begin() + index);
1045 1045
1046 unsigned int i, entries = numEntries(category); 1046 unsigned int i, entries = numEntries(category);
1047 if (!entries) { 1047 if (!entries) {
1048 // no more entries in this category, so 1048 // no more entries in this category, so
1049 // we can delete it, too. 1049 // we can delete it, too.
1050 BUG_ON(!delCategory(category)); 1050 BUG_ON(!delCategory(category));
1051 // delCategory() flags it dirty, so we need not to do so. 1051 // delCategory() flags it dirty, so we need not to do so.
1052 return true; 1052 return true;
1053 } 1053 }
1054 for (i = 0; i < entries; ++i) { 1054 for (i = 0; i < entries; ++i) {
1055 // decrement all listViewPositions that are greater than the deleted. 1055 // decrement all listViewPositions that are greater than the deleted.
1056 if (dti.dta[category].d[i].listViewPos > lvPos) 1056 if (dti.dta[category].d[i].listViewPos > lvPos)
1057 --dti.dta[category].d[i].listViewPos; 1057 --dti.dta[category].d[i].listViewPos;
1058 } 1058 }
1059 1059
1060 if (!dontFlagDirty) 1060 if (!dontFlagDirty)
1061 flagDirty(); 1061 flagDirty();
1062 return true; 1062 return true;
1063} 1063}
1064 1064
1065bool PwMDoc::editEntry(const QString &oldCategory, const QString &newCategory, 1065bool PwMDoc::editEntry(const QString &oldCategory, const QString &newCategory,
1066 unsigned int index, PwMDataItem *d, bool updateMeta) 1066 unsigned int index, PwMDataItem *d, bool updateMeta)
1067{ 1067{
1068 PWM_ASSERT(d); 1068 PWM_ASSERT(d);
1069 unsigned int oldCat = 0; 1069 unsigned int oldCat = 0;
1070 1070
1071 if (!findCategory(oldCategory, &oldCat)) { 1071 if (!findCategory(oldCategory, &oldCat)) {
1072 BUG(); 1072 BUG();
1073 return false; 1073 return false;
1074 } 1074 }
1075 1075
1076 return editEntry(oldCat, newCategory, index, d, updateMeta); 1076 return editEntry(oldCat, newCategory, index, d, updateMeta);
1077} 1077}
1078 1078
1079bool PwMDoc::editEntry(unsigned int oldCategory, const QString &newCategory, 1079bool PwMDoc::editEntry(unsigned int oldCategory, const QString &newCategory,
1080 unsigned int index, PwMDataItem *d, bool updateMeta) 1080 unsigned int index, PwMDataItem *d, bool updateMeta)
1081{ 1081{
1082 if (isDeepLocked()) 1082 if (isDeepLocked())
1083 return false; 1083 return false;
1084 if (updateMeta) { 1084 if (updateMeta) {
1085 d->meta.update = QDateTime::currentDateTime(); 1085 d->meta.update = QDateTime::currentDateTime();
1086 if (d->meta.create.isNull()) { 1086 if (d->meta.create.isNull()) {
1087 d->meta.create = d->meta.update; 1087 d->meta.create = d->meta.update;
1088 } 1088 }
1089 } 1089 }
1090 if (dti.dta[oldCategory].name != newCategory.latin1()) { 1090 if (dti.dta[oldCategory].name != newCategory.latin1()) {
1091 // the user changed the category. 1091 // the user changed the category.
1092 PwMerror ret; 1092 PwMerror ret;
1093 d->rev = 0; 1093 d->rev = 0;
1094 ret = addEntry(newCategory, d, true, false); 1094 ret = addEntry(newCategory, d, true, false);
1095 if (ret != e_success) 1095 if (ret != e_success)
1096 return false; 1096 return false;
1097 if (!delEntry(oldCategory, index, true)) 1097 if (!delEntry(oldCategory, index, true))
1098 return false; 1098 return false;
1099 } else { 1099 } else {
1100 d->rev = dti.dta[oldCategory].d[index].rev + 1; // increment revision counter. 1100 d->rev = dti.dta[oldCategory].d[index].rev + 1; // increment revision counter.
1101 dti.dta[oldCategory].d[index] = *d; 1101 dti.dta[oldCategory].d[index] = *d;
1102 } 1102 }
1103 flagDirty(); 1103 flagDirty();
1104 return true; 1104 return true;
1105} 1105}
1106 1106
1107unsigned int PwMDoc::numEntries(const QString &category) 1107unsigned int PwMDoc::numEntries(const QString &category)
1108{ 1108{
1109 unsigned int cat = 0; 1109 unsigned int cat = 0;
1110 1110
1111 if (!findCategory(category, &cat)) { 1111 if (!findCategory(category, &cat)) {
1112 BUG(); 1112 BUG();
1113 return 0; 1113 return 0;
1114 } 1114 }
1115 1115
1116 return numEntries(cat); 1116 return numEntries(cat);
1117} 1117}
1118 1118
1119bool PwMDoc::serializeDta(string *d) 1119bool PwMDoc::serializeDta(string *d)
1120{ 1120{
1121 PWM_ASSERT(d); 1121 PWM_ASSERT(d);
1122 Serializer ser; 1122 Serializer ser;
1123 if (!ser.serialize(dti)) 1123 if (!ser.serialize(dti))
1124 return false; 1124 return false;
1125 d->assign(ser.getXml()); 1125 d->assign(ser.getXml());
1126 if (!d->size()) 1126 if (!d->size())
1127 return false; 1127 return false;
1128 return true; 1128 return true;
1129} 1129}
1130 1130
1131bool PwMDoc::deSerializeDta(const string *d, bool entriesLocked) 1131bool PwMDoc::deSerializeDta(const string *d, bool entriesLocked)
1132{ 1132{
1133 PWM_ASSERT(d); 1133 PWM_ASSERT(d);
1134#ifndef PWM_EMBEDDED 1134#ifndef PWM_EMBEDDED
1135 try { 1135 try {
1136 1136
1137 Serializer ser(d->c_str()); 1137 Serializer ser(d->c_str());
1138 ser.setDefaultLockStat(entriesLocked); 1138 ser.setDefaultLockStat(entriesLocked);
1139 if (!ser.deSerialize(&dti)) 1139 if (!ser.deSerialize(&dti))
1140 return false; 1140 return false;
1141 } catch (PwMException) { 1141 } catch (PwMException) {
1142 return false; 1142 return false;
1143 } 1143 }
1144#else 1144#else
1145 Serializer ser(d->c_str()); 1145 Serializer ser(d->c_str());
1146 ser.setDefaultLockStat(entriesLocked); 1146 ser.setDefaultLockStat(entriesLocked);
1147 if (!ser.deSerialize(&dti)) 1147 if (!ser.deSerialize(&dti))
1148 return false; 1148 return false;
1149#endif 1149#endif
1150 1150
1151 emitDataChanged(this); 1151 emitDataChanged(this);
1152 return true; 1152 return true;
1153} 1153}
1154 1154
1155bool PwMDoc::getEntry(const QString &category, unsigned int index, 1155bool PwMDoc::getEntry(const QString &category, unsigned int index,
1156 PwMDataItem * d, bool unlockIfLocked) 1156 PwMDataItem * d, bool unlockIfLocked)
1157{ 1157{
1158 PWM_ASSERT(d); 1158 PWM_ASSERT(d);
1159 unsigned int cat = 0; 1159 unsigned int cat = 0;
1160 1160
1161 if (!findCategory(category, &cat)) { 1161 if (!findCategory(category, &cat)) {
1162 BUG(); 1162 BUG();
1163 return false; 1163 return false;
1164 } 1164 }
1165 1165
1166 return getEntry(cat, index, d, unlockIfLocked); 1166 return getEntry(cat, index, d, unlockIfLocked);
1167} 1167}
1168 1168
1169bool PwMDoc::getEntry(unsigned int category, unsigned int index, 1169bool PwMDoc::getEntry(unsigned int category, unsigned int index,
1170 PwMDataItem *d, bool unlockIfLocked) 1170 PwMDataItem *d, bool unlockIfLocked)
1171{ 1171{
1172 if (index > dti.dta[category].d.size() - 1) 1172 if (index > dti.dta[category].d.size() - 1)
1173 return false; 1173 return false;
1174 1174
1175 bool locked = isLocked(category, index); 1175 bool locked = isLocked(category, index);
1176 if (locked) { 1176 if (locked) {
1177 /* this entry is locked. We don't return a password, 1177 /* this entry is locked. We don't return a password,
1178 * until it's unlocked by the user by inserting 1178 * until it's unlocked by the user by inserting
1179 * chipcard or entering the mpw 1179 * chipcard or entering the mpw
1180 */ 1180 */
1181 if (unlockIfLocked) { 1181 if (unlockIfLocked) {
1182 if (!lockAt(category, index, false)) { 1182 if (!lockAt(category, index, false)) {
1183 return false; 1183 return false;
1184 } 1184 }
1185 locked = false; 1185 locked = false;
1186 } 1186 }
1187 } 1187 }
1188 1188
1189 *d = dti.dta[category].d[index]; 1189 *d = dti.dta[category].d[index];
1190 if (locked) 1190 if (locked)
1191 d->pw = LOCKED_STRING.latin1(); 1191 d->pw = LOCKED_STRING.latin1();
1192 1192
1193 return true; 1193 return true;
1194} 1194}
1195 1195
1196PwMerror PwMDoc::getCommentByLvp(const QString &category, int listViewPos, 1196PwMerror PwMDoc::getCommentByLvp(const QString &category, int listViewPos,
1197 string *foundComment) 1197 string *foundComment)
1198{ 1198{
1199 PWM_ASSERT(foundComment); 1199 PWM_ASSERT(foundComment);
1200 unsigned int cat = 0; 1200 unsigned int cat = 0;
1201 1201
1202 if (!findCategory(category, &cat)) 1202 if (!findCategory(category, &cat))
1203 return e_invalidArg; 1203 return e_invalidArg;
1204 1204
1205 unsigned int i, entries = numEntries(cat); 1205 unsigned int i, entries = numEntries(cat);
1206 for (i = 0; i < entries; ++i) { 1206 for (i = 0; i < entries; ++i) {
1207 if (dti.dta[cat].d[i].listViewPos == listViewPos) { 1207 if (dti.dta[cat].d[i].listViewPos == listViewPos) {
1208 *foundComment = dti.dta[cat].d[i].comment; 1208 *foundComment = dti.dta[cat].d[i].comment;
1209 if (dti.dta[cat].d[i].binary) 1209 if (dti.dta[cat].d[i].binary)
1210 return e_binEntry; 1210 return e_binEntry;
1211 return e_normalEntry; 1211 return e_normalEntry;
1212 } 1212 }
1213 } 1213 }
1214 BUG(); 1214 BUG();
1215 return e_generic; 1215 return e_generic;
1216} 1216}
1217 1217
1218bool PwMDoc::compressDta(string *d, char algo) 1218bool PwMDoc::compressDta(string *d, char algo)
1219{ 1219{
1220 PWM_ASSERT(d); 1220 PWM_ASSERT(d);
1221 switch (algo) { 1221 switch (algo) {
1222 case PWM_COMPRESS_GZIP: { 1222 case PWM_COMPRESS_GZIP: {
1223 CompressGzip comp; 1223 CompressGzip comp;
1224 return comp.compress(d); 1224 return comp.compress(d);
1225 /*US } case PWM_COMPRESS_BZIP2: { 1225 /*US } case PWM_COMPRESS_BZIP2: {
1226 CompressBzip2 comp; 1226 CompressBzip2 comp;
1227 return comp.compress(d); 1227 return comp.compress(d);
1228*/ 1228*/
1229 } case PWM_COMPRESS_NONE: { 1229 } case PWM_COMPRESS_NONE: {
1230 return true; 1230 return true;
1231 } default: { 1231 } default: {
1232 BUG(); 1232 BUG();
1233 } 1233 }
1234 } 1234 }
1235 return false; 1235 return false;
1236} 1236}
1237 1237
1238bool PwMDoc::decompressDta(string *d, char algo) 1238bool PwMDoc::decompressDta(string *d, char algo)
1239{ 1239{
1240 PWM_ASSERT(d); 1240 PWM_ASSERT(d);
1241 switch (algo) { 1241 switch (algo) {
1242 case PWM_COMPRESS_GZIP: { 1242 case PWM_COMPRESS_GZIP: {
1243 CompressGzip comp; 1243 CompressGzip comp;
1244 return comp.decompress(d); 1244 return comp.decompress(d);
1245 /*US } case PWM_COMPRESS_BZIP2: { 1245 /*US } case PWM_COMPRESS_BZIP2: {
1246 CompressBzip2 comp; 1246 CompressBzip2 comp;
1247 return comp.decompress(d); 1247 return comp.decompress(d);
1248 */ 1248 */
1249 } case PWM_COMPRESS_NONE: { 1249 } case PWM_COMPRESS_NONE: {
1250 return true; 1250 return true;
1251 } 1251 }
1252 } 1252 }
1253 return false; 1253 return false;
1254} 1254}
1255 1255
1256PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo) 1256PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo)
1257{ 1257{
1258 PWM_ASSERT(d); 1258 PWM_ASSERT(d);
1259 PWM_ASSERT(pw); 1259 PWM_ASSERT(pw);
1260 PWM_ASSERT(f); 1260 PWM_ASSERT(f);
1261 1261
1262 size_t encSize; 1262 size_t encSize;
1263 byte *encrypted = 0; 1263 byte *encrypted = 0;
1264 1264
1265 switch (algo) { 1265 switch (algo) {
1266 case PWM_CRYPT_BLOWFISH: { 1266 case PWM_CRYPT_BLOWFISH: {
1267 Blowfish::padNull(d); 1267 Blowfish::padNull(d);
1268 encSize = d->length(); 1268 encSize = d->length();
1269 encrypted = new byte[encSize]; 1269 encrypted = new byte[encSize];
1270 Blowfish bf; 1270 Blowfish bf;
1271 if (bf.bf_setkey((byte *) pw->latin1(), pw->length())) { 1271 if (bf.bf_setkey((byte *) pw->latin1(), pw->length())) {
1272 delete [] encrypted; 1272 delete [] encrypted;
1273 return e_weakPw; 1273 return e_weakPw;
1274 } 1274 }
1275 bf.bf_encrypt((byte *) encrypted, (byte *) d->c_str(), encSize); 1275 bf.bf_encrypt((byte *) encrypted, (byte *) d->c_str(), encSize);
1276 break; 1276 break;
1277 } 1277 }
1278 case PWM_CRYPT_AES128: 1278 case PWM_CRYPT_AES128:
1279 /*... fall through */ 1279 /*... fall through */
1280 case PWM_CRYPT_AES192: 1280 case PWM_CRYPT_AES192:
1281 case PWM_CRYPT_AES256: 1281 case PWM_CRYPT_AES256:
1282 case PWM_CRYPT_3DES: 1282 case PWM_CRYPT_3DES:
1283 case PWM_CRYPT_TWOFISH: 1283 case PWM_CRYPT_TWOFISH:
1284 case PWM_CRYPT_TWOFISH128: { 1284 case PWM_CRYPT_TWOFISH128: {
1285 if (!LibGCryptIf::available()) 1285 if (!LibGCryptIf::available())
1286 return e_cryptNotImpl; 1286 return e_cryptNotImpl;
1287 LibGCryptIf gc; 1287 LibGCryptIf gc;
1288 PwMerror err; 1288 PwMerror err;
1289 unsigned char *plain = new unsigned char[d->length() + 1024]; 1289 unsigned char *plain = new unsigned char[d->length() + 1024];
1290 memcpy(plain, d->c_str(), d->length()); 1290 memcpy(plain, d->c_str(), d->length());
1291 err = gc.encrypt(&encrypted, 1291 err = gc.encrypt(&encrypted,
1292 &encSize, 1292 &encSize,
1293 plain, 1293 plain,
1294 d->length(), 1294 d->length(),
1295 reinterpret_cast<const unsigned char *>(pw->latin1()), 1295 reinterpret_cast<const unsigned char *>(pw->latin1()),
1296 pw->length(), 1296 pw->length(),
1297 algo); 1297 algo);
1298 delete [] plain; 1298 delete [] plain;
1299 if (err != e_success) 1299 if (err != e_success)
1300 return e_cryptNotImpl; 1300 return e_cryptNotImpl;
1301 break; 1301 break;
1302 } 1302 }
1303 default: { 1303 default: {
1304 delete_ifnot_null_array(encrypted); 1304 delete_ifnot_null_array(encrypted);
1305 return e_cryptNotImpl; 1305 return e_cryptNotImpl;
1306 } } 1306 } }
1307 1307
1308 // write encrypted data to file 1308 // write encrypted data to file
1309 if (f->writeBlock(reinterpret_cast<const char *>(encrypted), 1309 if (f->writeBlock(reinterpret_cast<const char *>(encrypted),
1310 static_cast<Q_ULONG>(encSize)) 1310 static_cast<Q_ULONG>(encSize))
1311 != static_cast<Q_LONG>(encSize)) { 1311 != static_cast<Q_LONG>(encSize)) {
1312 delete_ifnot_null_array(encrypted); 1312 delete_ifnot_null_array(encrypted);
1313 return e_writeFile; 1313 return e_writeFile;
1314 } 1314 }
1315 delete_ifnot_null_array(encrypted); 1315 delete_ifnot_null_array(encrypted);
1316 return e_success; 1316 return e_success;
1317} 1317}
1318 1318
1319PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw, 1319PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw,
1320 char algo, QFile *f) 1320 char algo, QFile *f)
1321{ 1321{
1322 PWM_ASSERT(d); 1322 PWM_ASSERT(d);
1323 PWM_ASSERT(pw); 1323 PWM_ASSERT(pw);
1324 PWM_ASSERT(f); 1324 PWM_ASSERT(f);
1325 1325
1326 unsigned int cryptLen = f->size() - pos; 1326 unsigned int cryptLen = f->size() - pos;
1327 byte *encrypted = new byte[cryptLen]; 1327 byte *encrypted = new byte[cryptLen];
1328 byte *decrypted = new byte[cryptLen]; 1328 byte *decrypted = new byte[cryptLen];
1329 1329
1330 f->at(pos); 1330 f->at(pos);
1331#ifndef PWM_EMBEDDED 1331#ifndef PWM_EMBEDDED
1332 if (f->readBlock(reinterpret_cast<char *>(encrypted), 1332 if (f->readBlock(reinterpret_cast<char *>(encrypted),
1333 static_cast<Q_ULONG>(cryptLen)) 1333 static_cast<Q_ULONG>(cryptLen))
1334 != static_cast<Q_LONG>(cryptLen)) { 1334 != static_cast<Q_LONG>(cryptLen)) {
1335 delete [] encrypted; 1335 delete [] encrypted;
1336 delete [] decrypted; 1336 delete [] decrypted;
1337 return e_readFile; 1337 return e_readFile;
1338 } 1338 }
1339#else 1339#else
1340 if (f->readBlock((char *)(encrypted), 1340 if (f->readBlock((char *)(encrypted),
1341 (unsigned long)(cryptLen)) 1341 (unsigned long)(cryptLen))
1342 != (long)(cryptLen)) { 1342 != (long)(cryptLen)) {
1343 delete [] encrypted; 1343 delete [] encrypted;
1344 delete [] decrypted; 1344 delete [] decrypted;
1345 return e_readFile; 1345 return e_readFile;
1346 } 1346 }
1347#endif 1347#endif
1348 switch (algo) { 1348 switch (algo) {
1349 case PWM_CRYPT_BLOWFISH: { 1349 case PWM_CRYPT_BLOWFISH: {
1350 Blowfish bf; 1350 Blowfish bf;
1351 bf.bf_setkey((byte *) pw->latin1(), pw->length()); 1351 bf.bf_setkey((byte *) pw->latin1(), pw->length());
1352 bf.bf_decrypt(decrypted, encrypted, cryptLen); 1352 bf.bf_decrypt(decrypted, encrypted, cryptLen);
1353 break; 1353 break;
1354 } 1354 }
1355 case PWM_CRYPT_AES128: 1355 case PWM_CRYPT_AES128:
1356 /*... fall through */ 1356 /*... fall through */
1357 case PWM_CRYPT_AES192: 1357 case PWM_CRYPT_AES192:
1358 case PWM_CRYPT_AES256: 1358 case PWM_CRYPT_AES256:
1359 case PWM_CRYPT_3DES: 1359 case PWM_CRYPT_3DES:
1360 case PWM_CRYPT_TWOFISH: 1360 case PWM_CRYPT_TWOFISH:
1361 case PWM_CRYPT_TWOFISH128: { 1361 case PWM_CRYPT_TWOFISH128: {
1362 if (!LibGCryptIf::available()) 1362 if (!LibGCryptIf::available())
1363 return e_cryptNotImpl; 1363 return e_cryptNotImpl;
1364 LibGCryptIf gc; 1364 LibGCryptIf gc;
1365 PwMerror err; 1365 PwMerror err;
1366 err = gc.decrypt(&decrypted, 1366 err = gc.decrypt(&decrypted,
1367 &cryptLen, 1367 &cryptLen,
1368 encrypted, 1368 encrypted,
1369 cryptLen, 1369 cryptLen,
1370 reinterpret_cast<const unsigned char *>(pw->latin1()), 1370 reinterpret_cast<const unsigned char *>(pw->latin1()),
1371 pw->length(), 1371 pw->length(),
1372 algo); 1372 algo);
1373 if (err != e_success) { 1373 if (err != e_success) {
1374 delete [] encrypted; 1374 delete [] encrypted;
1375 delete [] decrypted; 1375 delete [] decrypted;
1376 return e_cryptNotImpl; 1376 return e_cryptNotImpl;
1377 } 1377 }
1378 break; 1378 break;
1379 } 1379 }
1380 default: { 1380 default: {
1381 delete [] encrypted; 1381 delete [] encrypted;
1382 delete [] decrypted; 1382 delete [] decrypted;
1383 return e_cryptNotImpl; 1383 return e_cryptNotImpl;
1384 } } 1384 } }
1385 delete [] encrypted; 1385 delete [] encrypted;
1386#ifndef PWM_EMBEDDED 1386#ifndef PWM_EMBEDDED
1387 d->assign(reinterpret_cast<const char *>(decrypted), 1387 d->assign(reinterpret_cast<const char *>(decrypted),
1388 static_cast<string::size_type>(cryptLen)); 1388 static_cast<string::size_type>(cryptLen));
1389#else 1389#else
1390 d->assign((const char *)(decrypted), 1390 d->assign((const char *)(decrypted),
1391 (string::size_type)(cryptLen)); 1391 (string::size_type)(cryptLen));
1392#endif 1392#endif
1393 delete [] decrypted; 1393 delete [] decrypted;
1394 if (algo == PWM_CRYPT_BLOWFISH) { 1394 if (algo == PWM_CRYPT_BLOWFISH) {
1395 if (!Blowfish::unpadNull(d)) { 1395 if (!Blowfish::unpadNull(d)) {
1396 BUG(); 1396 BUG();
1397 return e_readFile; 1397 return e_readFile;
1398 } 1398 }
1399 } 1399 }
1400 return e_success; 1400 return e_success;
1401} 1401}
1402 1402
1403PwMerror PwMDoc::checkDataHash(char dataHashType, const string *dataHash, 1403PwMerror PwMDoc::checkDataHash(char dataHashType, const string *dataHash,
1404 const string *dataStream) 1404 const string *dataStream)
1405{ 1405{
1406 PWM_ASSERT(dataHash); 1406 PWM_ASSERT(dataHash);
1407 PWM_ASSERT(dataStream); 1407 PWM_ASSERT(dataStream);
1408 switch(dataHashType) { 1408 switch(dataHashType) {
1409 case PWM_HASH_SHA1: { 1409 case PWM_HASH_SHA1: {
1410 Sha1 hash; 1410 Sha1 hash;
1411 hash.sha1_write((byte*)dataStream->c_str(), dataStream->length()); 1411 hash.sha1_write((byte*)dataStream->c_str(), dataStream->length());
1412 string ret = hash.sha1_read(); 1412 string ret = hash.sha1_read();
1413 if (ret != *dataHash) 1413 if (ret != *dataHash)
1414 return e_fileCorrupt; 1414 return e_fileCorrupt;
1415 break; 1415 break;
1416 } 1416 }
1417 case PWM_HASH_SHA256: 1417 case PWM_HASH_SHA256:
1418 /*... fall through */ 1418 /*... fall through */
1419 case PWM_HASH_SHA384: 1419 case PWM_HASH_SHA384:
1420 case PWM_HASH_SHA512: 1420 case PWM_HASH_SHA512:
1421 case PWM_HASH_MD5: 1421 case PWM_HASH_MD5:
1422 case PWM_HASH_RMD160: 1422 case PWM_HASH_RMD160:
1423 case PWM_HASH_TIGER: { 1423 case PWM_HASH_TIGER: {
1424 if (!LibGCryptIf::available()) 1424 if (!LibGCryptIf::available())
1425 return e_hashNotImpl; 1425 return e_hashNotImpl;
1426 LibGCryptIf gc; 1426 LibGCryptIf gc;
1427 PwMerror err; 1427 PwMerror err;
1428 unsigned char *buf; 1428 unsigned char *buf;
1429 size_t hashLen; 1429 size_t hashLen;
1430 err = gc.hash(&buf, 1430 err = gc.hash(&buf,
1431 &hashLen, 1431 &hashLen,
1432 reinterpret_cast<const unsigned char *>(dataStream->c_str()), 1432 reinterpret_cast<const unsigned char *>(dataStream->c_str()),
1433 dataStream->length(), 1433 dataStream->length(),
1434 dataHashType); 1434 dataHashType);
1435 if (err != e_success) 1435 if (err != e_success)
1436 return e_hashNotImpl; 1436 return e_hashNotImpl;
1437 string calcHash(reinterpret_cast<const char *>(buf), 1437 string calcHash(reinterpret_cast<const char *>(buf),
1438 static_cast<string::size_type>(hashLen)); 1438 static_cast<string::size_type>(hashLen));
1439 delete [] buf; 1439 delete [] buf;
1440 if (calcHash != *dataHash) 1440 if (calcHash != *dataHash)
1441 return e_fileCorrupt; 1441 return e_fileCorrupt;
1442 break; 1442 break;
1443 } 1443 }
1444 default: 1444 default:
1445 return e_hashNotImpl; 1445 return e_hashNotImpl;
1446 } 1446 }
1447 return e_success; 1447 return e_success;
1448} 1448}
1449 1449
1450bool PwMDoc::lockAt(unsigned int category, unsigned int index, 1450bool PwMDoc::lockAt(unsigned int category, unsigned int index,
1451 bool lock) 1451 bool lock)
1452{ 1452{
1453 if (index >= numEntries(category)) { 1453 if (index >= numEntries(category)) {
1454 BUG(); 1454 BUG();
1455 return false; 1455 return false;
1456 } 1456 }
1457 if (lock == dti.dta[category].d[index].lockStat) 1457 if (lock == dti.dta[category].d[index].lockStat)
1458 return true; 1458 return true;
1459 1459
1460 if (!lock && currentPw != "") { 1460 if (!lock && currentPw != "") {
1461 // "unlocking" and "password is already set" 1461 // "unlocking" and "password is already set"
1462 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { 1462 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) {
1463 // unlocking without pw not allowed 1463 // unlocking without pw not allowed
1464 QString pw; 1464 QString pw;
1465 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1465 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1466 if (pw != "") { 1466 if (pw != "") {
1467 if (pw != currentPw) { 1467 if (pw != currentPw) {
1468 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1468 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1469 return false; 1469 return false;
1470 } else { 1470 } else {
1471 timer()->start(DocTimer::id_mpwTimer); 1471 timer()->start(DocTimer::id_mpwTimer);
1472 } 1472 }
1473 } else { 1473 } else {
1474 return false; 1474 return false;
1475 } 1475 }
1476 } else { 1476 } else {
1477 timer()->start(DocTimer::id_mpwTimer); 1477 timer()->start(DocTimer::id_mpwTimer);
1478 } 1478 }
1479 } 1479 }
1480 1480
1481 dti.dta[category].d[index].lockStat = lock; 1481 dti.dta[category].d[index].lockStat = lock;
1482 dti.dta[category].d[index].rev++; // increment revision counter. 1482 dti.dta[category].d[index].rev++; // increment revision counter.
1483 1483
1484 emitDataChanged(this); 1484 emitDataChanged(this);
1485 if (!lock) 1485 if (!lock)
1486 timer()->start(DocTimer::id_autoLockTimer); 1486 timer()->start(DocTimer::id_autoLockTimer);
1487 1487
1488 return true; 1488 return true;
1489 1489
1490} 1490}
1491 1491
1492bool PwMDoc::lockAt(const QString &category,unsigned int index, 1492bool PwMDoc::lockAt(const QString &category,unsigned int index,
1493 bool lock) 1493 bool lock)
1494{ 1494{
1495 unsigned int cat = 0; 1495 unsigned int cat = 0;
1496 1496
1497 if (!findCategory(category, &cat)) { 1497 if (!findCategory(category, &cat)) {
1498 BUG(); 1498 BUG();
1499 return false; 1499 return false;
1500 } 1500 }
1501 1501
1502 return lockAt(cat, index, lock); 1502 return lockAt(cat, index, lock);
1503} 1503}
1504 1504
1505bool PwMDoc::lockAll(bool lock) 1505bool PwMDoc::lockAll(bool lock)
1506{ 1506{
1507 if (!lock && isDeepLocked()) { 1507 if (!lock && isDeepLocked()) {
1508 PwMerror ret; 1508 PwMerror ret;
1509 ret = deepLock(false); 1509 ret = deepLock(false);
1510 if (ret != e_success) 1510 if (ret != e_success)
1511 return false; 1511 return false;
1512 return true; 1512 return true;
1513 } 1513 }
1514 if (isDocEmpty()) { 1514 if (isDocEmpty()) {
1515 return true; 1515 return true;
1516 } 1516 }
1517 if (!lock && currentPw != "") { 1517 if (!lock && currentPw != "") {
1518 // unlocking and password is already set 1518 // unlocking and password is already set
1519 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { 1519 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) {
1520 // unlocking without pw not allowed 1520 // unlocking without pw not allowed
1521 QString pw; 1521 QString pw;
1522 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1522 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1523 if (pw != "") { 1523 if (pw != "") {
1524 if (pw != currentPw) { 1524 if (pw != currentPw) {
1525 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1525 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1526 return false; 1526 return false;
1527 } else { 1527 } else {
1528 timer()->start(DocTimer::id_mpwTimer); 1528 timer()->start(DocTimer::id_mpwTimer);
1529 } 1529 }
1530 } else { 1530 } else {
1531 return false; 1531 return false;
1532 } 1532 }
1533 } else { 1533 } else {
1534 timer()->start(DocTimer::id_mpwTimer); 1534 timer()->start(DocTimer::id_mpwTimer);
1535 } 1535 }
1536 } 1536 }
1537 1537
1538 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1538 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1539 catEnd = dti.dta.end(), 1539 catEnd = dti.dta.end(),
1540 catI = catBegin; 1540 catI = catBegin;
1541 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1541 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1542 while (catI != catEnd) { 1542 while (catI != catEnd) {
1543 entrBegin = catI->d.begin(); 1543 entrBegin = catI->d.begin();
1544 entrEnd = catI->d.end(); 1544 entrEnd = catI->d.end();
1545 entrI = entrBegin; 1545 entrI = entrBegin;
1546 while (entrI != entrEnd) { 1546 while (entrI != entrEnd) {
1547 entrI->lockStat = lock; 1547 entrI->lockStat = lock;
1548 entrI->rev++; // increment revision counter. 1548 entrI->rev++; // increment revision counter.
1549 ++entrI; 1549 ++entrI;
1550 } 1550 }
1551 ++catI; 1551 ++catI;
1552 } 1552 }
1553 1553
1554 emitDataChanged(this); 1554 emitDataChanged(this);
1555 if (lock) 1555 if (lock)
1556 timer()->stop(DocTimer::id_autoLockTimer); 1556 timer()->stop(DocTimer::id_autoLockTimer);
1557 else 1557 else
1558 timer()->start(DocTimer::id_autoLockTimer); 1558 timer()->start(DocTimer::id_autoLockTimer);
1559 1559
1560 return true; 1560 return true;
1561} 1561}
1562 1562
1563bool PwMDoc::isLocked(const QString &category, unsigned int index) 1563bool PwMDoc::isLocked(const QString &category, unsigned int index)
1564{ 1564{
1565 unsigned int cat = 0; 1565 unsigned int cat = 0;
1566 1566
1567 if (!findCategory(category, &cat)) { 1567 if (!findCategory(category, &cat)) {
1568 BUG(); 1568 BUG();
1569 return false; 1569 return false;
1570 } 1570 }
1571 1571
1572 return isLocked(cat, index); 1572 return isLocked(cat, index);
1573} 1573}
1574 1574
1575bool PwMDoc::unlockAll_tempoary(bool revert) 1575bool PwMDoc::unlockAll_tempoary(bool revert)
1576{ 1576{
1577 static vector< vector<bool> > *oldLockStates = 0; 1577 static vector< vector<bool> > *oldLockStates = 0;
1578 static bool wasDeepLocked; 1578 static bool wasDeepLocked;
1579 1579
1580 if (revert) {// revert the unlocking 1580 if (revert) {// revert the unlocking
1581 if (oldLockStates) { 1581 if (oldLockStates) {
1582 /* we actually _have_ unlocked something, because 1582 /* we actually _have_ unlocked something, because
1583 * we have allocated space for the oldLockStates. 1583 * we have allocated space for the oldLockStates.
1584 * So, go on and revert them! 1584 * So, go on and revert them!
1585 */ 1585 */
1586 if (wasDeepLocked) { 1586 if (wasDeepLocked) {
1587 PwMerror ret = deepLock(true); 1587 PwMerror ret = deepLock(true);
1588 if (ret == e_success) { 1588 if (ret == e_success) {
1589 /* deep-lock succeed. We are save. 1589 /* deep-lock succeed. We are save.
1590 * (but if it failed, just go on 1590 * (but if it failed, just go on
1591 * lock them normally) 1591 * lock them normally)
1592 */ 1592 */
1593 delete_and_null(oldLockStates); 1593 delete_and_null(oldLockStates);
1594 timer()->start(DocTimer::id_autoLockTimer); 1594 timer()->start(DocTimer::id_autoLockTimer);
1595 printDebug("tempoary unlocking of dta " 1595 printDebug("tempoary unlocking of dta "
1596 "reverted by deep-locking."); 1596 "reverted by deep-locking.");
1597 return true; 1597 return true;
1598 } 1598 }
1599 printDebug("deep-lock failed while reverting! " 1599 printDebug("deep-lock failed while reverting! "
1600 "Falling back to normal-lock."); 1600 "Falling back to normal-lock.");
1601 } 1601 }
1602 if (unlikely(!wasDeepLocked && 1602 if (unlikely(!wasDeepLocked &&
1603 numCategories() != oldLockStates->size())) { 1603 numCategories() != oldLockStates->size())) {
1604 /* DOH! We have modified "dta" while 1604 /* DOH! We have modified "dta" while
1605 * it was unlocked tempoary. DON'T DO THIS! 1605 * it was unlocked tempoary. DON'T DO THIS!
1606 */ 1606 */
1607 BUG(); 1607 BUG();
1608 delete_and_null(oldLockStates); 1608 delete_and_null(oldLockStates);
1609 timer()->start(DocTimer::id_autoLockTimer); 1609 timer()->start(DocTimer::id_autoLockTimer);
1610 return false; 1610 return false;
1611 } 1611 }
1612 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1612 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1613 catEnd = dti.dta.end(), 1613 catEnd = dti.dta.end(),
1614 catI = catBegin; 1614 catI = catBegin;
1615 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1615 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1616 vector< vector<bool> >::iterator oldCatStatI = oldLockStates->begin(); 1616 vector< vector<bool> >::iterator oldCatStatI = oldLockStates->begin();
1617 vector<bool>::iterator oldEntrStatBegin, 1617 vector<bool>::iterator oldEntrStatBegin,
1618 oldEntrStatEnd, 1618 oldEntrStatEnd,
1619 oldEntrStatI; 1619 oldEntrStatI;
1620 while (catI != catEnd) { 1620 while (catI != catEnd) {
1621 entrBegin = catI->d.begin(); 1621 entrBegin = catI->d.begin();
1622 entrEnd = catI->d.end(); 1622 entrEnd = catI->d.end();
1623 entrI = entrBegin; 1623 entrI = entrBegin;
1624 if (likely(!wasDeepLocked)) { 1624 if (likely(!wasDeepLocked)) {
1625 oldEntrStatBegin = oldCatStatI->begin(); 1625 oldEntrStatBegin = oldCatStatI->begin();
1626 oldEntrStatEnd = oldCatStatI->end(); 1626 oldEntrStatEnd = oldCatStatI->end();
1627 oldEntrStatI = oldEntrStatBegin; 1627 oldEntrStatI = oldEntrStatBegin;
1628 if (unlikely(catI->d.size() != oldCatStatI->size())) { 1628 if (unlikely(catI->d.size() != oldCatStatI->size())) {
1629 /* DOH! We have modified "dta" while 1629 /* DOH! We have modified "dta" while
1630 * it was unlocked tempoary. DON'T DO THIS! 1630 * it was unlocked tempoary. DON'T DO THIS!
1631 */ 1631 */
1632 BUG(); 1632 BUG();
1633 delete_and_null(oldLockStates); 1633 delete_and_null(oldLockStates);
1634 timer()->start(DocTimer::id_autoLockTimer); 1634 timer()->start(DocTimer::id_autoLockTimer);
1635 return false; 1635 return false;
1636 } 1636 }
1637 } 1637 }
1638 while (entrI != entrEnd) { 1638 while (entrI != entrEnd) {
1639 if (wasDeepLocked) { 1639 if (wasDeepLocked) {
1640 /* this is an error-fallback if 1640 /* this is an error-fallback if
1641 * deeplock didn't succeed 1641 * deeplock didn't succeed
1642 */ 1642 */
1643 entrI->lockStat = true; 1643 entrI->lockStat = true;
1644 } else { 1644 } else {
1645 entrI->lockStat = *oldEntrStatI; 1645 entrI->lockStat = *oldEntrStatI;
1646 } 1646 }
1647 ++entrI; 1647 ++entrI;
1648 if (likely(!wasDeepLocked)) 1648 if (likely(!wasDeepLocked))
1649 ++oldEntrStatI; 1649 ++oldEntrStatI;
1650 } 1650 }
1651 ++catI; 1651 ++catI;
1652 if (likely(!wasDeepLocked)) 1652 if (likely(!wasDeepLocked))
1653 ++oldCatStatI; 1653 ++oldCatStatI;
1654 } 1654 }
1655 delete_and_null(oldLockStates); 1655 delete_and_null(oldLockStates);
1656 if (unlikely(wasDeepLocked)) { 1656 if (unlikely(wasDeepLocked)) {
1657 /* error fallback... */ 1657 /* error fallback... */
1658 unsetDocStatFlag(DOC_STAT_DEEPLOCKED); 1658 unsetDocStatFlag(DOC_STAT_DEEPLOCKED);
1659 emitDataChanged(this); 1659 emitDataChanged(this);
1660 printDebug("WARNING: unlockAll_tempoary(true) " 1660 printDebug("WARNING: unlockAll_tempoary(true) "
1661 "deeplock fallback!"); 1661 "deeplock fallback!");
1662 } 1662 }
1663 printDebug("tempoary unlocking of dta reverted."); 1663 printDebug("tempoary unlocking of dta reverted.");
1664 } else { 1664 } else {
1665 printDebug("unlockAll_tempoary(true): nothing to do."); 1665 printDebug("unlockAll_tempoary(true): nothing to do.");
1666 } 1666 }
1667 timer()->start(DocTimer::id_autoLockTimer); 1667 timer()->start(DocTimer::id_autoLockTimer);
1668 } else {// unlock all data tempoary 1668 } else {// unlock all data tempoary
1669 if (unlikely(oldLockStates != 0)) { 1669 if (unlikely(oldLockStates != 0)) {
1670 /* DOH! We have already unlocked the data tempoarly. 1670 /* DOH! We have already unlocked the data tempoarly.
1671 * No need to do it twice. ;) 1671 * No need to do it twice. ;)
1672 */ 1672 */
1673 BUG(); 1673 BUG();
1674 return false; 1674 return false;
1675 } 1675 }
1676 wasDeepLocked = false; 1676 wasDeepLocked = false;
1677 bool mustUnlock = false; 1677 bool mustUnlock = false;
1678 if (isDeepLocked()) { 1678 if (isDeepLocked()) {
1679 PwMerror ret; 1679 PwMerror ret;
1680 while (1) { 1680 while (1) {
1681 ret = deepLock(false); 1681 ret = deepLock(false);
1682 if (ret == e_success) { 1682 if (ret == e_success) {
1683 break; 1683 break;
1684 } else if (ret == e_wrongPw) { 1684 } else if (ret == e_wrongPw) {
1685 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1685 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1686 } else { 1686 } else {
1687 printDebug("deep-unlocking failed while " 1687 printDebug("deep-unlocking failed while "
1688 "tempoary unlocking!"); 1688 "tempoary unlocking!");
1689 return false; 1689 return false;
1690 } 1690 }
1691 } 1691 }
1692 wasDeepLocked = true; 1692 wasDeepLocked = true;
1693 mustUnlock = true; 1693 mustUnlock = true;
1694 } else { 1694 } else {
1695 // first check if it's needed to unlock some entries 1695 // first check if it's needed to unlock some entries
1696 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1696 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1697 catEnd = dti.dta.end(), 1697 catEnd = dti.dta.end(),
1698 catI = catBegin; 1698 catI = catBegin;
1699 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1699 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1700 while (catI != catEnd) { 1700 while (catI != catEnd) {
1701 entrBegin = catI->d.begin(); 1701 entrBegin = catI->d.begin();
1702 entrEnd = catI->d.end(); 1702 entrEnd = catI->d.end();
1703 entrI = entrBegin; 1703 entrI = entrBegin;
1704 while (entrI != entrEnd) { 1704 while (entrI != entrEnd) {
1705 if (entrI->lockStat == true) { 1705 if (entrI->lockStat == true) {
1706 mustUnlock = true; 1706 mustUnlock = true;
1707 break; 1707 break;
1708 } 1708 }
1709 ++entrI; 1709 ++entrI;
1710 } 1710 }
1711 if (mustUnlock) 1711 if (mustUnlock)
1712 break; 1712 break;
1713 ++catI; 1713 ++catI;
1714 } 1714 }
1715 } 1715 }
1716 if (!mustUnlock) { 1716 if (!mustUnlock) {
1717 // nothing to do. 1717 // nothing to do.
1718 timer()->stop(DocTimer::id_autoLockTimer); 1718 timer()->stop(DocTimer::id_autoLockTimer);
1719 printDebug("unlockAll_tempoary(): nothing to do."); 1719 printDebug("unlockAll_tempoary(): nothing to do.");
1720 return true; 1720 return true;
1721 } else if (!wasDeepLocked) { 1721 } else if (!wasDeepLocked) {
1722 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW) && 1722 if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW) &&
1723 currentPw != "") { 1723 currentPw != "") {
1724 /* we can't unlock without mpw, so 1724 /* we can't unlock without mpw, so
1725 * we need to ask for it. 1725 * we need to ask for it.
1726 */ 1726 */
1727 QString pw; 1727 QString pw;
1728 while (1) { 1728 while (1) {
1729 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1729 pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1730 if (pw == "") { 1730 if (pw == "") {
1731 return false; 1731 return false;
1732 } else if (pw == currentPw) { 1732 } else if (pw == currentPw) {
1733 break; 1733 break;
1734 } 1734 }
1735 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); 1735 wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
1736 } 1736 }
1737 } 1737 }
1738 } 1738 }
1739 timer()->stop(DocTimer::id_autoLockTimer); 1739 timer()->stop(DocTimer::id_autoLockTimer);
1740 oldLockStates = new vector< vector<bool> >; 1740 oldLockStates = new vector< vector<bool> >;
1741 vector<bool> tmp_vec; 1741 vector<bool> tmp_vec;
1742 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 1742 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
1743 catEnd = dti.dta.end(), 1743 catEnd = dti.dta.end(),
1744 catI = catBegin; 1744 catI = catBegin;
1745 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 1745 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
1746 while (catI != catEnd) { 1746 while (catI != catEnd) {
1747 entrBegin = catI->d.begin(); 1747 entrBegin = catI->d.begin();
1748 entrEnd = catI->d.end(); 1748 entrEnd = catI->d.end();
1749 entrI = entrBegin; 1749 entrI = entrBegin;
1750 while (entrI != entrEnd) { 1750 while (entrI != entrEnd) {
1751 if (!wasDeepLocked) { 1751 if (!wasDeepLocked) {
1752 tmp_vec.push_back(entrI->lockStat); 1752 tmp_vec.push_back(entrI->lockStat);
1753 } 1753 }
1754 entrI->lockStat = false; 1754 entrI->lockStat = false;
1755 ++entrI; 1755 ++entrI;
1756 } 1756 }
1757 if (!wasDeepLocked) { 1757 if (!wasDeepLocked) {
1758 oldLockStates->push_back(tmp_vec); 1758 oldLockStates->push_back(tmp_vec);
1759 tmp_vec.clear(); 1759 tmp_vec.clear();
1760 } 1760 }
1761 ++catI; 1761 ++catI;
1762 } 1762 }
1763 printDebug("tempoary unlocked dta."); 1763 printDebug("tempoary unlocked dta.");
1764 } 1764 }
1765 1765
1766 return true; 1766 return true;
1767} 1767}
1768 1768
1769PwMerror PwMDoc::deepLock(bool lock, bool saveToFile) 1769PwMerror PwMDoc::deepLock(bool lock, bool saveToFile)
1770{ 1770{
1771 PwMerror ret; 1771 PwMerror ret;
1772 1772
1773 if (lock) { 1773 if (lock) {
1774 if (isDeepLocked()) 1774 if (isDeepLocked())
1775 return e_lock; 1775 return e_lock;
1776 if (saveToFile) { 1776 if (saveToFile) {
1777 if (isDocEmpty()) 1777 if (isDocEmpty())
1778 return e_docIsEmpty; 1778 return e_docIsEmpty;
1779 ret = saveDoc(conf()->confGlobCompression()); 1779 ret = saveDoc(conf()->confGlobCompression());
1780 if (ret == e_filename) { 1780 if (ret == e_filename) {
1781 /* the doc wasn't saved to a file 1781 /* the doc wasn't saved to a file
1782 * by the user, yet. 1782 * by the user, yet.
1783 */ 1783 */
1784 cantDeeplock_notSavedMsgBox(); 1784 cantDeeplock_notSavedMsgBox();
1785 return e_docNotSaved; 1785 return e_docNotSaved;
1786 } else if (ret != e_success) { 1786 } else if (ret != e_success) {
1787 return e_lock; 1787 return e_lock;
1788 } 1788 }
1789 } 1789 }
1790 timer()->stop(DocTimer::id_autoLockTimer); 1790 timer()->stop(DocTimer::id_autoLockTimer);
1791 clearDoc(); 1791 clearDoc();
1792 PwMDataItem d; 1792 PwMDataItem d;
1793 d.desc = IS_DEEPLOCKED_SHORTMSG.latin1(); 1793 d.desc = IS_DEEPLOCKED_SHORTMSG.latin1();
1794 d.comment = IS_DEEPLOCKED_MSG.latin1(); 1794 d.comment = IS_DEEPLOCKED_MSG.latin1();
1795 d.listViewPos = 0; 1795 d.listViewPos = 0;
1796 addEntry(DEFAULT_CATEGORY, &d, true); 1796 addEntry(DEFAULT_CATEGORY, &d, true);
1797 lockAt(DEFAULT_CATEGORY, 0, true); 1797 lockAt(DEFAULT_CATEGORY, 0, true);
1798 unsetDocStatFlag(DOC_STAT_DISK_DIRTY); 1798 unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
1799 setDocStatFlag(DOC_STAT_DEEPLOCKED); 1799 setDocStatFlag(DOC_STAT_DEEPLOCKED);
1800 } else { 1800 } else {
1801 if (!isDeepLocked()) 1801 if (!isDeepLocked())
1802 return e_lock; 1802 return e_lock;
1803 ret = openDoc(&filename, (conf()->confGlobUnlockOnOpen()) 1803 ret = openDoc(&filename, (conf()->confGlobUnlockOnOpen())
1804 ? 0 : 1); 1804 ? 0 : 1);
1805 if (ret == e_wrongPw) { 1805 if (ret == e_wrongPw) {
1806 return e_wrongPw; 1806 return e_wrongPw;
1807 } else if (ret != e_success) { 1807 } else if (ret != e_success) {
1808 printDebug(string("PwMDoc::deepLock(false): ERR! openDoc() == ") 1808 printDebug(string("PwMDoc::deepLock(false): ERR! openDoc() == ")
1809 + tostr(static_cast<int>(ret))); 1809 + tostr(static_cast<int>(ret)));
1810 return e_lock; 1810 return e_lock;
1811 } 1811 }
1812 unsetDocStatFlag(DOC_STAT_DEEPLOCKED); 1812 unsetDocStatFlag(DOC_STAT_DEEPLOCKED);
1813 timer()->start(DocTimer::id_autoLockTimer); 1813 timer()->start(DocTimer::id_autoLockTimer);
1814 } 1814 }
1815 1815
1816 emitDataChanged(this); 1816 emitDataChanged(this);
1817 return e_success; 1817 return e_success;
1818} 1818}
1819 1819
1820void PwMDoc::_deepUnlock() 1820void PwMDoc::_deepUnlock()
1821{ 1821{
1822 deepLock(false); 1822 deepLock(false);
1823} 1823}
1824 1824
1825void PwMDoc::clearDoc() 1825void PwMDoc::clearDoc()
1826{ 1826{
1827 dti.clear(); 1827 dti.clear();
1828 PwMCategoryItem d; 1828 PwMCategoryItem d;
1829 d.name = DEFAULT_CATEGORY.latin1(); 1829 d.name = DEFAULT_CATEGORY.latin1();
1830 dti.dta.push_back(d); 1830 dti.dta.push_back(d);
1831 currentPw = ""; 1831 currentPw = "";
1832 unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); 1832 unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
1833} 1833}
1834 1834
1835void PwMDoc::changeCurrentPw() 1835void PwMDoc::changeCurrentPw()
1836{ 1836{
1837 if (currentPw == "") 1837 if (currentPw == "")
1838 return; // doc hasn't been saved. No mpw available. 1838 return; // doc hasn't been saved. No mpw available.
1839 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD); 1839 bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD);
1840 QString pw = requestMpwChange(&currentPw, &useChipcard); 1840 QString pw = requestMpwChange(&currentPw, &useChipcard);
1841 if (pw == "") 1841 if (pw == "")
1842 return; 1842 return;
1843 if (useChipcard) 1843 if (useChipcard)
1844 setDocStatFlag(DOC_STAT_USE_CHIPCARD); 1844 setDocStatFlag(DOC_STAT_USE_CHIPCARD);
1845 else 1845 else
1846 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD); 1846 unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
1847 setCurrentPw(pw); 1847 setCurrentPw(pw);
1848} 1848}
1849 1849
1850void PwMDoc::setListViewPos(const QString &category, unsigned int index, 1850void PwMDoc::setListViewPos(const QString &category, unsigned int index,
1851 int pos) 1851 int pos)
1852{ 1852{
1853 unsigned int cat = 0; 1853 unsigned int cat = 0;
1854 1854
1855 if (!findCategory(category, &cat)) { 1855 if (!findCategory(category, &cat)) {
1856 BUG(); 1856 BUG();
1857 return; 1857 return;
1858 } 1858 }
1859 setListViewPos(cat, index, pos); 1859 setListViewPos(cat, index, pos);
1860} 1860}
1861 1861
1862void PwMDoc::setListViewPos(unsigned int category, unsigned int index, 1862void PwMDoc::setListViewPos(unsigned int category, unsigned int index,
1863 int pos) 1863 int pos)
1864{ 1864{
1865 dti.dta[category].d[index].listViewPos = pos; 1865 dti.dta[category].d[index].listViewPos = pos;
1866 1866
1867/* FIXME workaround: don't flag dirty, because this function sometimes 1867/* FIXME workaround: don't flag dirty, because this function sometimes
1868 * get's called when it shouldn't. It's because PwMView assumes 1868 * get's called when it shouldn't. It's because PwMView assumes
1869 * the user resorted the UI on behalf of signal layoutChanged(). 1869 * the user resorted the UI on behalf of signal layoutChanged().
1870 * This is somewhat broken and incorrect, but I've no other 1870 * This is somewhat broken and incorrect, but I've no other
1871 * solution for now. 1871 * solution for now.
1872 */ 1872 */
1873 //setDocStatFlag(DOC_STAT_DISK_DIRTY); 1873 //setDocStatFlag(DOC_STAT_DISK_DIRTY);
1874} 1874}
1875 1875
1876int PwMDoc::getListViewPos(const QString &category, unsigned int index) 1876int PwMDoc::getListViewPos(const QString &category, unsigned int index)
1877{ 1877{
1878 unsigned int cat = 0; 1878 unsigned int cat = 0;
1879 1879
1880 if (!findCategory(category, &cat)) { 1880 if (!findCategory(category, &cat)) {
1881 BUG(); 1881 BUG();
1882 return -1; 1882 return -1;
1883 } 1883 }
1884 1884
1885 return dti.dta[cat].d[index].listViewPos; 1885 return dti.dta[cat].d[index].listViewPos;
1886} 1886}
1887 1887
1888void PwMDoc::findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn, 1888void PwMDoc::findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn,
1889 vector<unsigned int> *foundPositions, bool breakAfterFound, 1889 vector<unsigned int> *foundPositions, bool breakAfterFound,
1890 bool caseSensitive, bool exactWordMatch, bool sortByLvp) 1890 bool caseSensitive, bool exactWordMatch, bool sortByLvp)
1891{ 1891{
1892 PWM_ASSERT(foundPositions); 1892 PWM_ASSERT(foundPositions);
1893 PWM_ASSERT(searchIn); 1893 PWM_ASSERT(searchIn);
1894 foundPositions->clear(); 1894 foundPositions->clear();
1895 1895
1896 unsigned int i, entries = numEntries(category); 1896 unsigned int i, entries = numEntries(category);
1897 for (i = 0; i < entries; ++i) { 1897 for (i = 0; i < entries; ++i) {
1898 if (searchIn & SEARCH_IN_DESC) { 1898 if (searchIn & SEARCH_IN_DESC) {
1899 if (!compareString(find.desc, dti.dta[category].d[i].desc, 1899 if (!compareString(find.desc, dti.dta[category].d[i].desc,
1900 caseSensitive, exactWordMatch)) { 1900 caseSensitive, exactWordMatch)) {
1901 continue; 1901 continue;
1902 } 1902 }
1903 } 1903 }
1904 if (searchIn & SEARCH_IN_NAME) { 1904 if (searchIn & SEARCH_IN_NAME) {
1905 if (!compareString(find.name, dti.dta[category].d[i].name, 1905 if (!compareString(find.name, dti.dta[category].d[i].name,
1906 caseSensitive, exactWordMatch)) { 1906 caseSensitive, exactWordMatch)) {
1907 continue; 1907 continue;
1908 } 1908 }
1909 } 1909 }
1910 if (searchIn & SEARCH_IN_PW) { 1910 if (searchIn & SEARCH_IN_PW) {
1911 bool wasLocked = isLocked(category, i); 1911 bool wasLocked = isLocked(category, i);
1912 getDataChangedLock(); 1912 getDataChangedLock();
1913 lockAt(category, i, false); 1913 lockAt(category, i, false);
1914 if (!compareString(find.pw, dti.dta[category].d[i].pw, 1914 if (!compareString(find.pw, dti.dta[category].d[i].pw,
1915 caseSensitive, exactWordMatch)) { 1915 caseSensitive, exactWordMatch)) {
1916 lockAt(category, i, wasLocked); 1916 lockAt(category, i, wasLocked);
1917 putDataChangedLock(); 1917 putDataChangedLock();
1918 continue; 1918 continue;
1919 } 1919 }
1920 lockAt(category, i, wasLocked); 1920 lockAt(category, i, wasLocked);
1921 putDataChangedLock(); 1921 putDataChangedLock();
1922 } 1922 }
1923 if (searchIn & SEARCH_IN_COMMENT) { 1923 if (searchIn & SEARCH_IN_COMMENT) {
1924 if (!compareString(find.comment, dti.dta[category].d[i].comment, 1924 if (!compareString(find.comment, dti.dta[category].d[i].comment,
1925 caseSensitive, exactWordMatch)) { 1925 caseSensitive, exactWordMatch)) {
1926 continue; 1926 continue;
1927 } 1927 }
1928 } 1928 }
1929 if (searchIn & SEARCH_IN_URL) { 1929 if (searchIn & SEARCH_IN_URL) {
1930 if (!compareString(find.url, dti.dta[category].d[i].url, 1930 if (!compareString(find.url, dti.dta[category].d[i].url,
1931 caseSensitive, exactWordMatch)) { 1931 caseSensitive, exactWordMatch)) {
1932 continue; 1932 continue;
1933 } 1933 }
1934 } 1934 }
1935 if (searchIn & SEARCH_IN_LAUNCHER) { 1935 if (searchIn & SEARCH_IN_LAUNCHER) {
1936 if (!compareString(find.launcher, dti.dta[category].d[i].launcher, 1936 if (!compareString(find.launcher, dti.dta[category].d[i].launcher,
1937 caseSensitive, exactWordMatch)) { 1937 caseSensitive, exactWordMatch)) {
1938 continue; 1938 continue;
1939 } 1939 }
1940 } 1940 }
1941 1941
1942 // all selected "searchIn" matched. 1942 // all selected "searchIn" matched.
1943 foundPositions->push_back(i); 1943 foundPositions->push_back(i);
1944 if (breakAfterFound) 1944 if (breakAfterFound)
1945 break; 1945 break;
1946 } 1946 }
1947 1947
1948 if (sortByLvp && foundPositions->size() > 1) { 1948 if (sortByLvp && foundPositions->size() > 1) {
1949 vector< pair<unsigned int /* foundPosition (real doc pos) */, 1949 vector< pair<unsigned int /* foundPosition (real doc pos) */,
1950 unsigned int /* lvp-pos */> > tmp_vec; 1950 unsigned int /* lvp-pos */> > tmp_vec;
1951 1951
1952 unsigned int i, items = foundPositions->size(); 1952 unsigned int i, items = foundPositions->size();
1953 pair<unsigned int, unsigned int> tmp_pair; 1953 pair<unsigned int, unsigned int> tmp_pair;
1954 for (i = 0; i < items; ++i) { 1954 for (i = 0; i < items; ++i) {
1955 tmp_pair.first = (*foundPositions)[i]; 1955 tmp_pair.first = (*foundPositions)[i];
1956 tmp_pair.second = dti.dta[category].d[(*foundPositions)[i]].listViewPos; 1956 tmp_pair.second = dti.dta[category].d[(*foundPositions)[i]].listViewPos;
1957 tmp_vec.push_back(tmp_pair); 1957 tmp_vec.push_back(tmp_pair);
1958 } 1958 }
1959 sort(tmp_vec.begin(), tmp_vec.end(), dta_lvp_greater()); 1959 sort(tmp_vec.begin(), tmp_vec.end(), dta_lvp_greater());
1960 foundPositions->clear(); 1960 foundPositions->clear();
1961 for (i = 0; i < items; ++i) { 1961 for (i = 0; i < items; ++i) {
1962 foundPositions->push_back(tmp_vec[i].first); 1962 foundPositions->push_back(tmp_vec[i].first);
1963 } 1963 }
1964 } 1964 }
1965} 1965}
1966 1966
1967void PwMDoc::findEntry(const QString &category, PwMDataItem find, unsigned int searchIn, 1967void PwMDoc::findEntry(const QString &category, PwMDataItem find, unsigned int searchIn,
1968 vector<unsigned int> *foundPositions, bool breakAfterFound, 1968 vector<unsigned int> *foundPositions, bool breakAfterFound,
1969 bool caseSensitive, bool exactWordMatch, bool sortByLvp) 1969 bool caseSensitive, bool exactWordMatch, bool sortByLvp)
1970{ 1970{
1971 PWM_ASSERT(foundPositions); 1971 PWM_ASSERT(foundPositions);
1972 unsigned int cat = 0; 1972 unsigned int cat = 0;
1973 1973
1974 if (!findCategory(category, &cat)) { 1974 if (!findCategory(category, &cat)) {
1975 foundPositions->clear(); 1975 foundPositions->clear();
1976 return; 1976 return;
1977 } 1977 }
1978 1978
1979 findEntry(cat, find, searchIn, foundPositions, breakAfterFound, 1979 findEntry(cat, find, searchIn, foundPositions, breakAfterFound,
1980 caseSensitive, exactWordMatch, sortByLvp); 1980 caseSensitive, exactWordMatch, sortByLvp);
1981} 1981}
1982 1982
1983bool PwMDoc::compareString(const string &s1, const string &s2, bool caseSensitive, 1983bool PwMDoc::compareString(const string &s1, const string &s2, bool caseSensitive,
1984 bool exactWordMatch) 1984 bool exactWordMatch)
1985{ 1985{
1986 QString _s1(s1.c_str()); 1986 QString _s1(s1.c_str());
1987 QString _s2(s2.c_str()); 1987 QString _s2(s2.c_str());
1988 if (!caseSensitive) { 1988 if (!caseSensitive) {
1989 _s1 = _s1.lower(); 1989 _s1 = _s1.lower();
1990 _s2 = _s2.lower(); 1990 _s2 = _s2.lower();
1991 } 1991 }
1992 if (exactWordMatch ? (_s1 == _s2) : (_s2.find(_s1) != -1)) 1992 if (exactWordMatch ? (_s1 == _s2) : (_s2.find(_s1) != -1))
1993 return true; 1993 return true;
1994 return false; 1994 return false;
1995} 1995}
1996 1996
1997bool PwMDoc::findCategory(const QString &name, unsigned int *index) 1997bool PwMDoc::findCategory(const QString &name, unsigned int *index)
1998{ 1998{
1999 vector<PwMCategoryItem>::iterator i = dti.dta.begin(), 1999 vector<PwMCategoryItem>::iterator i = dti.dta.begin(),
2000 end = dti.dta.end(); 2000 end = dti.dta.end();
2001 while (i != end) { 2001 while (i != end) {
2002 if ((*i).name == name.latin1()) { 2002 if ((*i).name == name.latin1()) {
2003 if (index) { 2003 if (index) {
2004 *index = i - dti.dta.begin(); 2004 *index = i - dti.dta.begin();
2005 } 2005 }
2006 return true; 2006 return true;
2007 } 2007 }
2008 ++i; 2008 ++i;
2009 } 2009 }
2010 return false; 2010 return false;
2011} 2011}
2012 2012
2013bool PwMDoc::renameCategory(const QString &category, const QString &newName) 2013bool PwMDoc::renameCategory(const QString &category, const QString &newName)
2014{ 2014{
2015 unsigned int cat = 0; 2015 unsigned int cat = 0;
2016 2016
2017 if (!findCategory(category, &cat)) 2017 if (!findCategory(category, &cat))
2018 return false; 2018 return false;
2019 2019
2020 return renameCategory(cat, newName); 2020 return renameCategory(cat, newName);
2021} 2021}
2022 2022
2023bool PwMDoc::renameCategory(unsigned int category, const QString &newName, 2023bool PwMDoc::renameCategory(unsigned int category, const QString &newName,
2024 bool dontFlagDirty) 2024 bool dontFlagDirty)
2025{ 2025{
2026 if (category > numCategories() - 1) 2026 if (category > numCategories() - 1)
2027 return false; 2027 return false;
2028 2028
2029 dti.dta[category].name = newName.latin1(); 2029 dti.dta[category].name = newName.latin1();
2030 if (!dontFlagDirty) 2030 if (!dontFlagDirty)
2031 flagDirty(); 2031 flagDirty();
2032 2032
2033 return true; 2033 return true;
2034} 2034}
2035 2035
2036bool PwMDoc::delCategory(const QString &category) 2036bool PwMDoc::delCategory(const QString &category)
2037{ 2037{
2038 unsigned int cat = 0; 2038 unsigned int cat = 0;
2039 2039
2040 if (!findCategory(category, &cat)) 2040 if (!findCategory(category, &cat))
2041 return false; 2041 return false;
2042 2042
2043 return delCategory(cat); 2043 return delCategory(cat);
2044} 2044}
2045 2045
2046bool PwMDoc::delCategory(unsigned int category, bool dontFlagDirty) 2046bool PwMDoc::delCategory(unsigned int category, bool dontFlagDirty)
2047{ 2047{
2048 if (category > numCategories() - 1) 2048 if (category > numCategories() - 1)
2049 return false; 2049 return false;
2050 2050
2051 // We don't delete it, if it is the last existing 2051 // We don't delete it, if it is the last existing
2052 // category! Instead we rename it to "Default". 2052 // category! Instead we rename it to "Default".
2053 if (numCategories() > 1) { 2053 if (numCategories() > 1) {
2054 dti.dta.erase(dti.dta.begin() + category); 2054 dti.dta.erase(dti.dta.begin() + category);
2055 } else { 2055 } else {
2056 renameCategory(category, DEFAULT_CATEGORY, dontFlagDirty); 2056 renameCategory(category, DEFAULT_CATEGORY, dontFlagDirty);
2057 return true; 2057 return true;
2058 } 2058 }
2059 if (!dontFlagDirty) 2059 if (!dontFlagDirty)
2060 flagDirty(); 2060 flagDirty();
2061 2061
2062 return true; 2062 return true;
2063} 2063}
2064 2064
2065void PwMDoc::delAllEmptyCat(bool dontFlagDirty) 2065void PwMDoc::delAllEmptyCat(bool dontFlagDirty)
2066{ 2066{
2067 vector<PwMCategoryItem>::iterator begin = dti.dta.begin(), 2067 vector<PwMCategoryItem>::iterator begin = dti.dta.begin(),
2068 end = dti.dta.end(), 2068 end = dti.dta.end(),
2069 i = begin; 2069 i = begin;
2070 while (i != end) { 2070 while (i != end) {
2071 if (i->d.empty()) { 2071 if (i->d.empty()) {
2072 delCategory(begin - i, dontFlagDirty); 2072 delCategory(begin - i, dontFlagDirty);
2073 } 2073 }
2074 ++i; 2074 ++i;
2075 } 2075 }
2076} 2076}
2077 2077
2078void PwMDoc::getCategoryList(vector<string> *list) 2078void PwMDoc::getCategoryList(vector<string> *list)
2079{ 2079{
2080 PWM_ASSERT(list); 2080 PWM_ASSERT(list);
2081 list->clear(); 2081 list->clear();
2082 vector<PwMCategoryItem>::iterator i = dti.dta.begin(), 2082 vector<PwMCategoryItem>::iterator i = dti.dta.begin(),
2083 end = dti.dta.end(); 2083 end = dti.dta.end();
2084 while (i != end) { 2084 while (i != end) {
2085 list->push_back(i->name); 2085 list->push_back(i->name);
2086 ++i; 2086 ++i;
2087 } 2087 }
2088} 2088}
2089 2089
2090void PwMDoc::getCategoryList(QStringList *list) 2090void PwMDoc::getCategoryList(QStringList *list)
2091{ 2091{
2092 PWM_ASSERT(list); 2092 PWM_ASSERT(list);
2093 list->clear(); 2093 list->clear();
2094 vector<PwMCategoryItem>::iterator i = dti.dta.begin(), 2094 vector<PwMCategoryItem>::iterator i = dti.dta.begin(),
2095 end = dti.dta.end(); 2095 end = dti.dta.end();
2096 while (i != end) { 2096 while (i != end) {
2097#ifndef PWM_EMBEDDED 2097#ifndef PWM_EMBEDDED
2098 list->push_back(i->name.c_str()); 2098 list->push_back(i->name.c_str());
2099#else 2099#else
2100 list->append(i->name.c_str()); 2100 list->append(i->name.c_str());
2101#endif 2101#endif
2102 ++i; 2102 ++i;
2103 } 2103 }
2104} 2104}
2105 2105
2106void PwMDoc::getEntryList(const QString &category, QStringList *list) 2106void PwMDoc::getEntryList(const QString &category, QStringList *list)
2107{ 2107{
2108 PWM_ASSERT(list); 2108 PWM_ASSERT(list);
2109 unsigned int cat = 0; 2109 unsigned int cat = 0;
2110 if (!findCategory(category, &cat)) { 2110 if (!findCategory(category, &cat)) {
2111 list->clear(); 2111 list->clear();
2112 return; 2112 return;
2113 } 2113 }
2114 getEntryList(cat, list); 2114 getEntryList(cat, list);
2115} 2115}
2116 2116
2117void PwMDoc::getEntryList(const QString &category, vector<string> *list) 2117void PwMDoc::getEntryList(const QString &category, vector<string> *list)
2118{ 2118{
2119 PWM_ASSERT(list); 2119 PWM_ASSERT(list);
2120 unsigned int cat = 0; 2120 unsigned int cat = 0;
2121 if (!findCategory(category, &cat)) { 2121 if (!findCategory(category, &cat)) {
2122 list->clear(); 2122 list->clear();
2123 return; 2123 return;
2124 } 2124 }
2125 getEntryList(cat, list); 2125 getEntryList(cat, list);
2126} 2126}
2127 2127
2128void PwMDoc::getEntryList(unsigned int category, vector<string> *list) 2128void PwMDoc::getEntryList(unsigned int category, vector<string> *list)
2129{ 2129{
2130 PWM_ASSERT(list); 2130 PWM_ASSERT(list);
2131 list->clear(); 2131 list->clear();
2132 vector<PwMDataItem>::iterator begin = dti.dta[category].d.begin(), 2132 vector<PwMDataItem>::iterator begin = dti.dta[category].d.begin(),
2133 end = dti.dta[category].d.end(), 2133 end = dti.dta[category].d.end(),
2134 i = begin; 2134 i = begin;
2135 while (i != end) { 2135 while (i != end) {
2136 list->push_back(i->desc); 2136 list->push_back(i->desc);
2137 ++i; 2137 ++i;
2138 } 2138 }
2139} 2139}
2140 2140
2141void PwMDoc::getEntryList(unsigned int category, QStringList *list) 2141void PwMDoc::getEntryList(unsigned int category, QStringList *list)
2142{ 2142{
2143 PWM_ASSERT(list); 2143 PWM_ASSERT(list);
2144 list->clear(); 2144 list->clear();
2145 vector<PwMDataItem>::iterator begin = dti.dta[category].d.begin(), 2145 vector<PwMDataItem>::iterator begin = dti.dta[category].d.begin(),
2146 end = dti.dta[category].d.end(), 2146 end = dti.dta[category].d.end(),
2147 i = begin; 2147 i = begin;
2148 while (i != end) { 2148 while (i != end) {
2149#ifndef PWM_EMBEDDED 2149#ifndef PWM_EMBEDDED
2150 list->push_back(i->desc.c_str()); 2150 list->push_back(i->desc.c_str());
2151#else 2151#else
2152 list->append(i->desc.c_str()); 2152 list->append(i->desc.c_str());
2153#endif 2153#endif
2154 ++i; 2154 ++i;
2155 } 2155 }
2156} 2156}
2157 2157
2158bool PwMDoc::execLauncher(const QString &category, unsigned int entryIndex) 2158bool PwMDoc::execLauncher(const QString &category, unsigned int entryIndex)
2159{ 2159{
2160 unsigned int cat = 0; 2160 unsigned int cat = 0;
2161 2161
2162 if (!findCategory(category, &cat)) 2162 if (!findCategory(category, &cat))
2163 return false; 2163 return false;
2164 2164
2165 return execLauncher(cat, entryIndex); 2165 return execLauncher(cat, entryIndex);
2166} 2166}
2167 2167
2168bool PwMDoc::execLauncher(unsigned int category, unsigned int entryIndex) 2168bool PwMDoc::execLauncher(unsigned int category, unsigned int entryIndex)
2169{ 2169{
2170 if (geteuid() == 0) { 2170 if (geteuid() == 0) {
2171 rootAlertMsgBox(); 2171 rootAlertMsgBox();
2172 return false; 2172 return false;
2173 } 2173 }
2174 QString command(dti.dta[category].d[entryIndex].launcher.c_str()); 2174 QString command(dti.dta[category].d[entryIndex].launcher.c_str());
2175 bool wasLocked = isLocked(category, entryIndex); 2175 bool wasLocked = isLocked(category, entryIndex);
2176 2176
2177 if (command.find("$p") != -1) { 2177 if (command.find("$p") != -1) {
2178 /* the user requested the password to be included 2178 /* the user requested the password to be included
2179 * into the command. We have to ask for the password, 2179 * into the command. We have to ask for the password,
2180 * if it's locked. We do that by unlocking the entry 2180 * if it's locked. We do that by unlocking the entry
2181 */ 2181 */
2182 if (!lockAt(category, entryIndex, false)) 2182 if (!lockAt(category, entryIndex, false))
2183 return false; 2183 return false;
2184 } 2184 }
2185#ifndef PWM_EMBEDDED 2185#ifndef PWM_EMBEDDED
2186 command.replace("$d", dti.dta[category].d[entryIndex].desc.c_str()); 2186 command.replace("$d", dti.dta[category].d[entryIndex].desc.c_str());
2187 command.replace("$n", dti.dta[category].d[entryIndex].name.c_str()); 2187 command.replace("$n", dti.dta[category].d[entryIndex].name.c_str());
2188 command.replace("$p", dti.dta[category].d[entryIndex].pw.c_str()); 2188 command.replace("$p", dti.dta[category].d[entryIndex].pw.c_str());
2189 command.replace("$u", dti.dta[category].d[entryIndex].url.c_str()); 2189 command.replace("$u", dti.dta[category].d[entryIndex].url.c_str());
2190 command.replace("$c", dti.dta[category].d[entryIndex].comment.c_str()); 2190 command.replace("$c", dti.dta[category].d[entryIndex].comment.c_str());
2191#else 2191#else
2192 command.replace(QRegExp("$d"), dti.dta[category].d[entryIndex].desc.c_str()); 2192 command.replace(QRegExp("$d"), dti.dta[category].d[entryIndex].desc.c_str());
2193 command.replace(QRegExp("$n"), dti.dta[category].d[entryIndex].name.c_str()); 2193 command.replace(QRegExp("$n"), dti.dta[category].d[entryIndex].name.c_str());
2194 command.replace(QRegExp("$p"), dti.dta[category].d[entryIndex].pw.c_str()); 2194 command.replace(QRegExp("$p"), dti.dta[category].d[entryIndex].pw.c_str());
2195 command.replace(QRegExp("$u"), dti.dta[category].d[entryIndex].url.c_str()); 2195 command.replace(QRegExp("$u"), dti.dta[category].d[entryIndex].url.c_str());
2196 command.replace(QRegExp("$c"), dti.dta[category].d[entryIndex].comment.c_str()); 2196 command.replace(QRegExp("$c"), dti.dta[category].d[entryIndex].comment.c_str());
2197#endif 2197#endif
2198 command.append(" &"); 2198 command.append(" &");
2199 2199
2200 QString customXterm(conf()->confGlobXtermCommand()); 2200 QString customXterm(conf()->confGlobXtermCommand());
2201 if (!customXterm.isEmpty()) 2201 if (!customXterm.isEmpty())
2202 command = customXterm + " " + command; 2202 command = customXterm + " " + command;
2203 2203
2204 system(command.latin1()); 2204 system(command.latin1());
2205 2205
2206 lockAt(category, entryIndex, wasLocked); 2206 lockAt(category, entryIndex, wasLocked);
2207 return true; 2207 return true;
2208} 2208}
2209 2209
2210bool PwMDoc::goToURL(const QString &category, unsigned int entryIndex) 2210bool PwMDoc::goToURL(const QString &category, unsigned int entryIndex)
2211{ 2211{
2212 unsigned int cat = 0; 2212 unsigned int cat = 0;
2213 2213
2214 if (!findCategory(category, &cat)) 2214 if (!findCategory(category, &cat))
2215 return false; 2215 return false;
2216 2216
2217 return goToURL(cat, entryIndex); 2217 return goToURL(cat, entryIndex);
2218} 2218}
2219 2219
2220bool PwMDoc::goToURL(unsigned int category, unsigned int entryIndex) 2220bool PwMDoc::goToURL(unsigned int category, unsigned int entryIndex)
2221{ 2221{
2222 if (geteuid() == 0) { 2222 if (geteuid() == 0) {
2223 rootAlertMsgBox(); 2223 rootAlertMsgBox();
2224 return false; 2224 return false;
2225 } 2225 }
2226 QString url(dti.dta[category].d[entryIndex].url.c_str()); 2226 QString url(dti.dta[category].d[entryIndex].url.c_str());
2227 if (url.isEmpty()) 2227 if (url.isEmpty())
2228 return false; 2228 return false;
2229 2229
2230 QString customBrowser(conf()->confGlobBrowserCommand()); 2230 QString customBrowser(conf()->confGlobBrowserCommand());
2231 if (!customBrowser.isEmpty()) { 2231 if (!customBrowser.isEmpty()) {
2232 browserProc.clearArguments(); 2232 browserProc.clearArguments();
2233 browserProc << customBrowser << url; 2233 browserProc << customBrowser << url;
2234 if (browserProc.start(KProcess::DontCare)) 2234 if (browserProc.start(KProcess::DontCare))
2235 return true; 2235 return true;
2236 } 2236 }
2237 2237
2238 browserProc.clearArguments(); 2238 browserProc.clearArguments();
2239 browserProc << "konqueror" << url; 2239 browserProc << "konqueror" << url;
2240 if (browserProc.start(KProcess::DontCare)) 2240 if (browserProc.start(KProcess::DontCare))
2241 return true; 2241 return true;
2242 2242
2243 browserProc.clearArguments(); 2243 browserProc.clearArguments();
2244 browserProc << "mozilla" << url; 2244 browserProc << "mozilla" << url;
2245 if (browserProc.start(KProcess::DontCare)) 2245 if (browserProc.start(KProcess::DontCare))
2246 return true; 2246 return true;
2247 2247
2248 browserProc.clearArguments(); 2248 browserProc.clearArguments();
2249 browserProc << "opera" << url; 2249 browserProc << "opera" << url;
2250 if (browserProc.start(KProcess::DontCare)) 2250 if (browserProc.start(KProcess::DontCare))
2251 return true; 2251 return true;
2252 return false; 2252 return false;
2253} 2253}
2254 2254
2255PwMerror PwMDoc::exportToText(const QString *file) 2255PwMerror PwMDoc::exportToText(const QString *file)
2256{ 2256{
2257 PWM_ASSERT(file); 2257 PWM_ASSERT(file);
2258 if (QFile::exists(*file)) { 2258 if (QFile::exists(*file)) {
2259 if (!QFile::remove(*file)) 2259 if (!QFile::remove(*file))
2260 return e_accessFile; 2260 return e_accessFile;
2261 } 2261 }
2262 QFile f(*file); 2262 QFile f(*file);
2263 if (!f.open(IO_ReadWrite)) 2263 if (!f.open(IO_ReadWrite))
2264 return e_openFile; 2264 return e_openFile;
2265 2265
2266 if (!unlockAll_tempoary()) { 2266 if (!unlockAll_tempoary()) {
2267 f.close(); 2267 f.close();
2268 return e_lock; 2268 return e_lock;
2269 } 2269 }
2270 2270
2271 // write header 2271 // write header
2272 string header = i18n("Password table generated by\nPwM v").latin1(); 2272 string header = i18n("Password table generated by\nPwM v").latin1();
2273 header += PACKAGE_VER; 2273 header += PACKAGE_VER;
2274 header += i18n("\non ").latin1(); 2274 header += i18n("\non ").latin1();
2275 QDate currDate = QDate::currentDate(); 2275 QDate currDate = QDate::currentDate();
2276 QTime currTime = QTime::currentTime(); 2276 QTime currTime = QTime::currentTime();
2277 2277
2278#ifndef PWM_EMBEDDED 2278#ifndef PWM_EMBEDDED
2279 header += currDate.toString("ddd MMMM d ").latin1(); 2279 header += currDate.toString("ddd MMMM d ").latin1();
2280 header += currTime.toString("hh:mm:ss ").latin1(); 2280 header += currTime.toString("hh:mm:ss ").latin1();
2281#else 2281#else
2282 QString dfs = KGlobal::locale()->dateFormatShort(); 2282 QString dfs = KGlobal::locale()->dateFormatShort();
2283 bool ampm = KGlobal::locale()->use12Clock(); 2283 bool ampm = KGlobal::locale()->use12Clock();
2284 KGlobal::locale()->setDateFormatShort("%A %B %d"); 2284 KGlobal::locale()->setDateFormatShort("%A %B %d");
2285 KGlobal::locale()->setHore24Format(true); 2285 KGlobal::locale()->setHore24Format(true);
2286 2286
2287 header += KGlobal::locale()->formatDate(currDate, true, KLocale::Userdefined); 2287 header += KGlobal::locale()->formatDate(currDate, true, KLocale::Userdefined);
2288 header += KGlobal::locale()->formatTime(currTime, true); 2288 header += KGlobal::locale()->formatTime(currTime, true);
2289 KGlobal::locale()->setDateFormatShort(dfs); 2289 KGlobal::locale()->setDateFormatShort(dfs);
2290 KGlobal::locale()->setHore24Format(!ampm); 2290 KGlobal::locale()->setHore24Format(!ampm);
2291 2291
2292#endif 2292#endif
2293 header += tostr(currDate.year()); 2293 header += tostr(currDate.year());
2294 header += "\n==============================\n\n"; 2294 header += "\n==============================\n\n";
2295 2295
2296 2296
2297#ifndef PWM_EMBEDDED 2297#ifndef PWM_EMBEDDED
2298 if (f.writeBlock(header.c_str(), header.length()) != (Q_LONG)header.length()) { 2298 if (f.writeBlock(header.c_str(), header.length()) != (Q_LONG)header.length()) {
2299 unlockAll_tempoary(true); 2299 unlockAll_tempoary(true);
2300 f.close(); 2300 f.close();
2301 return e_writeFile; 2301 return e_writeFile;
2302 } 2302 }
2303#else 2303#else
2304 if (f.writeBlock(header.c_str(), header.length()) != (long)header.length()) { 2304 if (f.writeBlock(header.c_str(), header.length()) != (long)header.length()) {
2305 unlockAll_tempoary(true); 2305 unlockAll_tempoary(true);
2306 f.close(); 2306 f.close();
2307 return e_writeFile; 2307 return e_writeFile;
2308 } 2308 }
2309#endif 2309#endif
2310 unsigned int i, numCat = numCategories(); 2310 unsigned int i, numCat = numCategories();
2311 unsigned int j, numEnt; 2311 unsigned int j, numEnt;
2312 string exp; 2312 string exp;
2313 for (i = 0; i < numCat; ++i) { 2313 for (i = 0; i < numCat; ++i) {
2314 numEnt = numEntries(i); 2314 numEnt = numEntries(i);
2315 2315
2316 exp = "\n== Category: "; 2316 exp = "\n== Category: ";
2317 exp += dti.dta[i].name; 2317 exp += dti.dta[i].name;
2318 exp += " ==\n"; 2318 exp += " ==\n";
2319#ifndef PWM_EMBEDDED 2319#ifndef PWM_EMBEDDED
2320 if (f.writeBlock(exp.c_str(), exp.length()) != (Q_LONG)exp.length()) { 2320 if (f.writeBlock(exp.c_str(), exp.length()) != (Q_LONG)exp.length()) {
2321 unlockAll_tempoary(true); 2321 unlockAll_tempoary(true);
2322 f.close(); 2322 f.close();
2323 return e_writeFile; 2323 return e_writeFile;
2324 } 2324 }
2325#else 2325#else
2326 if (f.writeBlock(exp.c_str(), exp.length()) != (long)exp.length()) { 2326 if (f.writeBlock(exp.c_str(), exp.length()) != (long)exp.length()) {
2327 unlockAll_tempoary(true); 2327 unlockAll_tempoary(true);
2328 f.close(); 2328 f.close();
2329 return e_writeFile; 2329 return e_writeFile;
2330 } 2330 }
2331#endif 2331#endif
2332 for (j = 0; j < numEnt; ++j) { 2332 for (j = 0; j < numEnt; ++j) {
2333 exp = "\n-- "; 2333 exp = "\n-- ";
2334 exp += dti.dta[i].d[j].desc; 2334 exp += dti.dta[i].d[j].desc;
2335 exp += " --\n"; 2335 exp += " --\n";
2336 2336
2337 exp += i18n("Username: ").latin1(); 2337 exp += i18n("Username: ").latin1();
2338 exp += dti.dta[i].d[j].name; 2338 exp += dti.dta[i].d[j].name;
2339 exp += "\n"; 2339 exp += "\n";
2340 2340
2341 exp += i18n("Password: ").latin1(); 2341 exp += i18n("Password: ").latin1();
2342 exp += dti.dta[i].d[j].pw; 2342 exp += dti.dta[i].d[j].pw;
2343 exp += "\n"; 2343 exp += "\n";
2344 2344
2345 exp += i18n("Comment: ").latin1(); 2345 exp += i18n("Comment: ").latin1();
2346 exp += dti.dta[i].d[j].comment; 2346 exp += dti.dta[i].d[j].comment;
2347 exp += "\n"; 2347 exp += "\n";
2348 2348
2349 exp += i18n("URL: ").latin1(); 2349 exp += i18n("URL: ").latin1();
2350 exp += dti.dta[i].d[j].url; 2350 exp += dti.dta[i].d[j].url;
2351 exp += "\n"; 2351 exp += "\n";
2352 2352
2353 exp += i18n("Launcher: ").latin1(); 2353 exp += i18n("Launcher: ").latin1();
2354 exp += dti.dta[i].d[j].launcher; 2354 exp += dti.dta[i].d[j].launcher;
2355 exp += "\n"; 2355 exp += "\n";
2356 2356
2357#ifndef PWM_EMBEDDED 2357#ifndef PWM_EMBEDDED
2358 if (f.writeBlock(exp.c_str(), exp.length()) != (Q_LONG)exp.length()) { 2358 if (f.writeBlock(exp.c_str(), exp.length()) != (Q_LONG)exp.length()) {
2359 unlockAll_tempoary(true); 2359 unlockAll_tempoary(true);
2360 f.close(); 2360 f.close();
2361 return e_writeFile; 2361 return e_writeFile;
2362 } 2362 }
2363#else 2363#else
2364 if (f.writeBlock(exp.c_str(), exp.length()) != (long)exp.length()) { 2364 if (f.writeBlock(exp.c_str(), exp.length()) != (long)exp.length()) {
2365 unlockAll_tempoary(true); 2365 unlockAll_tempoary(true);
2366 f.close(); 2366 f.close();
2367 return e_writeFile; 2367 return e_writeFile;
2368 } 2368 }
2369#endif 2369#endif
2370 } 2370 }
2371 } 2371 }
2372 unlockAll_tempoary(true); 2372 unlockAll_tempoary(true);
2373 f.close(); 2373 f.close();
2374 2374
2375 return e_success; 2375 return e_success;
2376} 2376}
2377 2377
2378PwMerror PwMDoc::importFromText(const QString *file, int format) 2378PwMerror PwMDoc::importFromText(const QString *file, int format)
2379{ 2379{
2380 PWM_ASSERT(file); 2380 PWM_ASSERT(file);
2381 if (format == 0) 2381 if (format == 0)
2382 return importText_PwM(file); 2382 return importText_PwM(file);
2383 else if (format == -1) { 2383 else if (format == -1) {
2384 // probe for all formats 2384 // probe for all formats
2385 if (importText_PwM(file) == e_success) 2385 if (importText_PwM(file) == e_success)
2386 return e_success; 2386 return e_success;
2387 dti.clear(); 2387 dti.clear();
2388 emitDataChanged(this); 2388 emitDataChanged(this);
2389 // add next format here... 2389 // add next format here...
2390 return e_fileFormat; 2390 return e_fileFormat;
2391 } 2391 }
2392 return e_invalidArg; 2392 return e_invalidArg;
2393} 2393}
2394 2394
2395PwMerror PwMDoc::importText_PwM(const QString *file) 2395PwMerror PwMDoc::importText_PwM(const QString *file)
2396{ 2396{
2397#ifndef PWM_EMBEDDED 2397#ifndef PWM_EMBEDDED
2398 PWM_ASSERT(file); 2398 PWM_ASSERT(file);
2399 FILE *f; 2399 FILE *f;
2400 int tmp; 2400 int tmp;
2401 ssize_t ret; 2401 ssize_t ret;
2402 string curCat; 2402 string curCat;
2403 unsigned int entriesRead = 0; 2403 unsigned int entriesRead = 0;
2404 PwMDataItem currItem; 2404 PwMDataItem currItem;
2405 f = fopen(file->latin1(), "r"); 2405 f = fopen(file->latin1(), "r");
2406 if (!f) 2406 if (!f)
2407 return e_openFile; 2407 return e_openFile;
2408 size_t ch_tmp_size = 1024; 2408 size_t ch_tmp_size = 1024;
2409 char *ch_tmp = (char*)malloc(ch_tmp_size); 2409 char *ch_tmp = (char*)malloc(ch_tmp_size);
2410 if (!ch_tmp) { 2410 if (!ch_tmp) {
2411 fclose(f); 2411 fclose(f);
2412 return e_outOfMem; 2412 return e_outOfMem;
2413 } 2413 }
2414 2414
2415 // - check header 2415 // - check header
2416 if (getline(&ch_tmp, &ch_tmp_size, f) == -1) // skip first line. 2416 if (getline(&ch_tmp, &ch_tmp_size, f) == -1) // skip first line.
2417 goto formatError; 2417 goto formatError;
2418 // check version-string and return version in "ch_tmp". 2418 // check version-string and return version in "ch_tmp".
2419 if (fscanf(f, "PwM v%s", ch_tmp) != 1) { 2419 if (fscanf(f, "PwM v%s", ch_tmp) != 1) {
2420 // header not recognized as PwM generated header 2420 // header not recognized as PwM generated header
2421 goto formatError; 2421 goto formatError;
2422 } 2422 }
2423 // set filepointer behind version-string-line previously checked 2423 // set filepointer behind version-string-line previously checked
2424 if (getline(&ch_tmp, &ch_tmp_size, f) == -1) 2424 if (getline(&ch_tmp, &ch_tmp_size, f) == -1)
2425 goto formatError; 2425 goto formatError;
2426 // skip next line containing the build-date 2426 // skip next line containing the build-date
2427 if (getline(&ch_tmp, &ch_tmp_size, f) == -1) 2427 if (getline(&ch_tmp, &ch_tmp_size, f) == -1)
2428 goto formatError; 2428 goto formatError;
2429 // read header termination line 2429 // read header termination line
2430 if (getline(&ch_tmp, &ch_tmp_size, f) == -1) 2430 if (getline(&ch_tmp, &ch_tmp_size, f) == -1)
2431 goto formatError; 2431 goto formatError;
2432 if (strcmp(ch_tmp, "==============================\n")) 2432 if (strcmp(ch_tmp, "==============================\n"))
2433 goto formatError; 2433 goto formatError;
2434 2434
2435 // - read entries 2435 // - read entries
2436 do { 2436 do {
2437 // find beginning of next category 2437 // find beginning of next category
2438 do { 2438 do {
2439 tmp = fgetc(f); 2439 tmp = fgetc(f);
2440 } while (tmp == '\n' && tmp != EOF); 2440 } while (tmp == '\n' && tmp != EOF);
2441 if (tmp == EOF) 2441 if (tmp == EOF)
2442 break; 2442 break;
2443 2443
2444 // decrement filepos by one 2444 // decrement filepos by one
2445 fseek(f, -1, SEEK_CUR); 2445 fseek(f, -1, SEEK_CUR);
2446 // read cat-name 2446 // read cat-name
2447 if (getline(&ch_tmp, &ch_tmp_size, f) == -1) 2447 if (getline(&ch_tmp, &ch_tmp_size, f) == -1)
2448 goto formatError; 2448 goto formatError;
2449 // check cat-name format 2449 // check cat-name format
2450 if (memcmp(ch_tmp, "== Category: ", 13) != 0) 2450 if (memcmp(ch_tmp, "== Category: ", 13) != 0)
2451 goto formatError; 2451 goto formatError;
2452 if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " ==", 3) != 0) 2452 if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " ==", 3) != 0)
2453 goto formatError; 2453 goto formatError;
2454 // copy cat-name 2454 // copy cat-name
2455 curCat.assign(ch_tmp + 13, strlen(ch_tmp) - 1 - 16); 2455 curCat.assign(ch_tmp + 13, strlen(ch_tmp) - 1 - 16);
2456 2456
2457 do { 2457 do {
2458 // find beginning of next entry 2458 // find beginning of next entry
2459 do { 2459 do {
2460 tmp = fgetc(f); 2460 tmp = fgetc(f);
2461 } while (tmp == '\n' && tmp != EOF && tmp != '='); 2461 } while (tmp == '\n' && tmp != EOF && tmp != '=');
2462 if (tmp == EOF) 2462 if (tmp == EOF)
2463 break; 2463 break;
2464 if (tmp == '=') { 2464 if (tmp == '=') {
2465 fseek(f, -1, SEEK_CUR); 2465 fseek(f, -1, SEEK_CUR);
2466 break; 2466 break;
2467 } 2467 }
2468 // decrement filepos by one 2468 // decrement filepos by one
2469 fseek(f, -1, SEEK_CUR); 2469 fseek(f, -1, SEEK_CUR);
2470 // read desc-line 2470 // read desc-line
2471 if (getline(&ch_tmp, &ch_tmp_size, f) == -1) 2471 if (getline(&ch_tmp, &ch_tmp_size, f) == -1)
2472 goto formatError; 2472 goto formatError;
2473 // check desc-line format 2473 // check desc-line format
2474 if (memcmp(ch_tmp, "-- ", 3) != 0) 2474 if (memcmp(ch_tmp, "-- ", 3) != 0)
2475 goto formatError; 2475 goto formatError;
2476 if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " --", 3) != 0) 2476 if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " --", 3) != 0)
2477 goto formatError; 2477 goto formatError;
2478 // add desc-line 2478 // add desc-line
2479 currItem.desc.assign(ch_tmp + 3, strlen(ch_tmp) - 1 - 6); 2479 currItem.desc.assign(ch_tmp + 3, strlen(ch_tmp) - 1 - 6);
2480 2480
2481 // read username-line 2481 // read username-line
2482 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1) 2482 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1)
2483 goto formatError; 2483 goto formatError;
2484 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.name)) 2484 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.name))
2485 goto formatError; 2485 goto formatError;
2486 2486
2487 // read pw-line 2487 // read pw-line
2488 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1) 2488 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1)
2489 goto formatError; 2489 goto formatError;
2490 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.pw)) 2490 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.pw))
2491 goto formatError; 2491 goto formatError;
2492 2492
2493 // read comment-line 2493 // read comment-line
2494 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1) 2494 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1)
2495 goto formatError; 2495 goto formatError;
2496 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.comment)) 2496 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.comment))
2497 goto formatError; 2497 goto formatError;
2498 2498
2499 // read URL-line 2499 // read URL-line
2500 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1) 2500 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1)
2501 goto formatError; 2501 goto formatError;
2502 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.url)) 2502 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.url))
2503 goto formatError; 2503 goto formatError;
2504 2504
2505 // read launcher-line 2505 // read launcher-line
2506 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1) 2506 if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1)
2507 goto formatError; 2507 goto formatError;
2508 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.launcher)) 2508 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.launcher))
2509 goto formatError; 2509 goto formatError;
2510 2510
2511 currItem.lockStat = true; 2511 currItem.lockStat = true;
2512 currItem.listViewPos = -1; 2512 currItem.listViewPos = -1;
2513 addEntry(curCat.c_str(), &currItem, true); 2513 addEntry(curCat.c_str(), &currItem, true);
2514 ++entriesRead; 2514 ++entriesRead;
2515 } while (1); 2515 } while (1);
2516 } while (1); 2516 } while (1);
2517 if (!entriesRead) 2517 if (!entriesRead)
2518 goto formatError; 2518 goto formatError;
2519 2519
2520 free(ch_tmp); 2520 free(ch_tmp);
2521 fclose(f); 2521 fclose(f);
2522 flagDirty(); 2522 flagDirty();
2523 return e_success; 2523 return e_success;
2524 2524
2525 formatError: 2525 formatError:
2526 free(ch_tmp); 2526 free(ch_tmp);
2527 fclose(f); 2527 fclose(f);
2528 return e_fileFormat; 2528 return e_fileFormat;
2529#else 2529#else
2530 PWM_ASSERT(file); 2530 PWM_ASSERT(file);
2531 QFile f(file->latin1()); 2531 QFile f(file->latin1());
2532 int tmp; 2532 int tmp;
2533 ssize_t ret; 2533 ssize_t ret;
2534 string curCat; 2534 string curCat;
2535 unsigned int entriesRead = 0; 2535 unsigned int entriesRead = 0;
2536 PwMDataItem currItem; 2536 PwMDataItem currItem;
2537 bool res = f.open(IO_ReadOnly); 2537 bool res = f.open(IO_ReadOnly);
2538 if (res == false) 2538 if (res == false)
2539 return e_openFile; 2539 return e_openFile;
2540 2540
2541 unsigned int ch_tmp_size = 1024; 2541 unsigned int ch_tmp_size = 1024;
2542 char *ch_tmp = (char*)malloc(ch_tmp_size); 2542 char *ch_tmp = (char*)malloc(ch_tmp_size);
2543 if (!ch_tmp) { 2543 if (!ch_tmp) {
2544 f.close(); 2544 f.close();
2545 return e_outOfMem; 2545 return e_outOfMem;
2546 } 2546 }
2547 2547
2548 // - check header 2548 // - check header
2549 if (f.readLine(ch_tmp, ch_tmp_size) == -1) // skip first line. 2549 if (f.readLine(ch_tmp, ch_tmp_size) == -1) // skip first line.
2550 goto formatError; 2550 goto formatError;
2551 2551
2552 //US read fileversion first, then check if ok. 2552 //US read fileversion first, then check if ok.
2553 if (f.readLine(ch_tmp, ch_tmp_size) == -1) 2553 if (f.readLine(ch_tmp, ch_tmp_size) == -1)
2554 goto formatError; 2554 goto formatError;
2555 2555
2556 // check version-string and return version in "ch_tmp". 2556 // check version-string and return version in "ch_tmp".
2557 //US if (fscanf(f, "PwM v%s", ch_tmp) != 1) { 2557 //US if (fscanf(f, "PwM v%s", ch_tmp) != 1) {
2558 //US // header not recognized as PwM generated header 2558 //US // header not recognized as PwM generated header
2559 //US goto formatError; 2559 //US goto formatError;
2560 //US} 2560 //US}
2561 //US set filepointer behind version-string-line previously checked 2561 //US set filepointer behind version-string-line previously checked
2562 //US if (f.readLine(ch_tmp, ch_tmp_size) == -1) 2562 //US if (f.readLine(ch_tmp, ch_tmp_size) == -1)
2563 //US goto formatError; 2563 //US goto formatError;
2564 // skip next line containing the build-date 2564 // skip next line containing the build-date
2565 if (f.readLine(ch_tmp, ch_tmp_size) == -1) 2565 if (f.readLine(ch_tmp, ch_tmp_size) == -1)
2566 goto formatError; 2566 goto formatError;
2567 // read header termination line 2567 // read header termination line
2568 if (f.readLine(ch_tmp, ch_tmp_size) == -1) 2568 if (f.readLine(ch_tmp, ch_tmp_size) == -1)
2569 goto formatError; 2569 goto formatError;
2570 if (strcmp(ch_tmp, "==============================\n")) 2570 if (strcmp(ch_tmp, "==============================\n"))
2571 goto formatError; 2571 goto formatError;
2572 2572
2573 // - read entries 2573 // - read entries
2574 do { 2574 do {
2575 // find beginning of next category 2575 // find beginning of next category
2576 do { 2576 do {
2577 tmp = f.getch(); 2577 tmp = f.getch();
2578 } while (tmp == '\n' && tmp != EOF); 2578 } while (tmp == '\n' && tmp != EOF);
2579 if (tmp == EOF) 2579 if (tmp == EOF)
2580 break; 2580 break;
2581 2581
2582 // decrement filepos by one 2582 // decrement filepos by one
2583 f.at(f.at()-1); 2583 f.at(f.at()-1);
2584 // read cat-name 2584 // read cat-name
2585 if (f.readLine(ch_tmp, ch_tmp_size) == -1) 2585 if (f.readLine(ch_tmp, ch_tmp_size) == -1)
2586 goto formatError; 2586 goto formatError;
2587 // check cat-name format 2587 // check cat-name format
2588 if (memcmp(ch_tmp, "== Category: ", 13) != 0) 2588 if (memcmp(ch_tmp, "== Category: ", 13) != 0)
2589 goto formatError; 2589 goto formatError;
2590 if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " ==", 3) != 0) 2590 if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " ==", 3) != 0)
2591 goto formatError; 2591 goto formatError;
2592 // copy cat-name 2592 // copy cat-name
2593 curCat.assign(ch_tmp + 13, strlen(ch_tmp) - 1 - 16); 2593 curCat.assign(ch_tmp + 13, strlen(ch_tmp) - 1 - 16);
2594 2594
2595 do { 2595 do {
2596 // find beginning of next entry 2596 // find beginning of next entry
2597 do { 2597 do {
2598 tmp = f.getch(); 2598 tmp = f.getch();
2599 } while (tmp == '\n' && tmp != EOF && tmp != '='); 2599 } while (tmp == '\n' && tmp != EOF && tmp != '=');
2600 if (tmp == EOF) 2600 if (tmp == EOF)
2601 break; 2601 break;
2602 if (tmp == '=') { 2602 if (tmp == '=') {
2603 f.at(f.at()-1); 2603 f.at(f.at()-1);
2604 break; 2604 break;
2605 } 2605 }
2606 // decrement filepos by one 2606 // decrement filepos by one
2607 f.at(f.at()-1); 2607 f.at(f.at()-1);
2608 // read desc-line 2608 // read desc-line
2609 if (f.readLine(ch_tmp, ch_tmp_size) == -1) 2609 if (f.readLine(ch_tmp, ch_tmp_size) == -1)
2610 goto formatError; 2610 goto formatError;
2611 // check desc-line format 2611 // check desc-line format
2612 if (memcmp(ch_tmp, "-- ", 3) != 0) 2612 if (memcmp(ch_tmp, "-- ", 3) != 0)
2613 goto formatError; 2613 goto formatError;
2614 if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " --", 3) != 0) 2614 if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " --", 3) != 0)
2615 goto formatError; 2615 goto formatError;
2616 // add desc-line 2616 // add desc-line
2617 currItem.desc.assign(ch_tmp + 3, strlen(ch_tmp) - 1 - 6); 2617 currItem.desc.assign(ch_tmp + 3, strlen(ch_tmp) - 1 - 6);
2618 2618
2619 // read username-line 2619 // read username-line
2620 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1) 2620 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1)
2621 goto formatError; 2621 goto formatError;
2622 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.name)) 2622 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.name))
2623 goto formatError; 2623 goto formatError;
2624 2624
2625 // read pw-line 2625 // read pw-line
2626 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1) 2626 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1)
2627 goto formatError; 2627 goto formatError;
2628 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.pw)) 2628 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.pw))
2629 goto formatError; 2629 goto formatError;
2630 2630
2631 // read comment-line 2631 // read comment-line
2632 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1) 2632 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1)
2633 goto formatError; 2633 goto formatError;
2634 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.comment)) 2634 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.comment))
2635 goto formatError; 2635 goto formatError;
2636 2636
2637 // read URL-line 2637 // read URL-line
2638 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1) 2638 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1)
2639 goto formatError; 2639 goto formatError;
2640 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.url)) 2640 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.url))
2641 goto formatError; 2641 goto formatError;
2642 2642
2643 // read launcher-line 2643 // read launcher-line
2644 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1) 2644 if ((ret = f.readLine(ch_tmp, ch_tmp_size)) == -1)
2645 goto formatError; 2645 goto formatError;
2646 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.launcher)) 2646 if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.launcher))
2647 goto formatError; 2647 goto formatError;
2648 2648
2649 currItem.lockStat = true; 2649 currItem.lockStat = true;
2650 currItem.listViewPos = -1; 2650 currItem.listViewPos = -1;
2651 addEntry(curCat.c_str(), &currItem, true); 2651 addEntry(curCat.c_str(), &currItem, true);
2652 ++entriesRead; 2652 ++entriesRead;
2653 } while (1); 2653 } while (1);
2654 } while (1); 2654 } while (1);
2655 if (!entriesRead) 2655 if (!entriesRead)
2656 goto formatError; 2656 goto formatError;
2657 2657
2658 free(ch_tmp); 2658 free(ch_tmp);
2659 f.close(); 2659 f.close();
2660 flagDirty(); 2660 flagDirty();
2661 return e_success; 2661 return e_success;
2662 2662
2663 formatError: 2663 formatError:
2664 free(ch_tmp); 2664 free(ch_tmp);
2665 f.close(); 2665 f.close();
2666 return e_fileFormat; 2666 return e_fileFormat;
2667 2667
2668#endif 2668#endif
2669 2669
2670} 2670}
2671 2671
2672bool PwMDoc::textExtractEntry_PwM(const char *in, ssize_t in_size, string *out) 2672bool PwMDoc::textExtractEntry_PwM(const char *in, ssize_t in_size, string *out)
2673{ 2673{
2674 PWM_ASSERT(in && out); 2674 PWM_ASSERT(in && out);
2675 ssize_t i = 0, len = in_size - 1; 2675 ssize_t i = 0, len = in_size - 1;
2676 while (i < len) { 2676 while (i < len) {
2677 if (in[i] == ':') 2677 if (in[i] == ':')
2678 break; 2678 break;
2679 ++i; 2679 ++i;
2680 } 2680 }
2681 i += 2; 2681 i += 2;
2682 *out = ""; 2682 *out = "";
2683 out->append(in + i, in_size - i - 1); 2683 out->append(in + i, in_size - i - 1);
2684 return true; 2684 return true;
2685} 2685}
2686 2686
2687PwMerror PwMDoc::exportToGpasman(const QString *file) 2687PwMerror PwMDoc::exportToGpasman(const QString *file)
2688{ 2688{
2689 PWM_ASSERT(file); 2689 PWM_ASSERT(file);
2690 GpasmanFile gp; 2690 GpasmanFile gp;
2691 int ret; 2691 int ret;
2692 2692
2693 if (!unlockAll_tempoary()) 2693 if (!unlockAll_tempoary())
2694 return e_lock; 2694 return e_lock;
2695 2695
2696 QString gpmPassword; 2696 QString gpmPassword;
2697 while (1) { 2697 while (1) {
2698 gpmPassword = requestNewMpw(0); 2698 gpmPassword = requestNewMpw(0);
2699 if (gpmPassword == "") { 2699 if (gpmPassword == "") {
2700 unlockAll_tempoary(true); 2700 unlockAll_tempoary(true);
2701 return e_noPw; 2701 return e_noPw;
2702 } 2702 }
2703 if (gpmPassword.length() < 4) { 2703 if (gpmPassword.length() < 4) {
2704 gpmPwLenErrMsgBox(); 2704 gpmPwLenErrMsgBox();
2705 } else { 2705 } else {
2706 break; 2706 break;
2707 } 2707 }
2708 } 2708 }
2709 2709
2710 ret = gp.save_init(file->latin1(), gpmPassword.latin1()); 2710 ret = gp.save_init(file->latin1(), gpmPassword.latin1());
2711 if (ret != 1) { 2711 if (ret != 1) {
2712 unlockAll_tempoary(true); 2712 unlockAll_tempoary(true);
2713 return e_accessFile; 2713 return e_accessFile;
2714 } 2714 }
2715 2715
2716 char *entry[4]; 2716 char *entry[4];
2717 unsigned int numCat = numCategories(), i; 2717 unsigned int numCat = numCategories(), i;
2718 unsigned int numEntr, j; 2718 unsigned int numEntr, j;
2719 int descLen, nameLen, pwLen, commentLen; 2719 int descLen, nameLen, pwLen, commentLen;
2720 for (i = 0; i < numCat; ++i) { 2720 for (i = 0; i < numCat; ++i) {
2721 numEntr = numEntries(i); 2721 numEntr = numEntries(i);
2722 for (j = 0; j < numEntr; ++j) { 2722 for (j = 0; j < numEntr; ++j) {
2723 descLen = dti.dta[i].d[j].desc.length(); 2723 descLen = dti.dta[i].d[j].desc.length();
2724 nameLen = dti.dta[i].d[j].name.length(); 2724 nameLen = dti.dta[i].d[j].name.length();
2725 pwLen = dti.dta[i].d[j].pw.length(); 2725 pwLen = dti.dta[i].d[j].pw.length();
2726 commentLen = dti.dta[i].d[j].comment.length(); 2726 commentLen = dti.dta[i].d[j].comment.length();
2727 entry[0] = new char[descLen + 1]; 2727 entry[0] = new char[descLen + 1];
2728 entry[1] = new char[nameLen + 1]; 2728 entry[1] = new char[nameLen + 1];
2729 entry[2] = new char[pwLen + 1]; 2729 entry[2] = new char[pwLen + 1];
2730 entry[3] = new char[commentLen + 1]; 2730 entry[3] = new char[commentLen + 1];
2731 strcpy(entry[0], descLen == 0 ? " " : dti.dta[i].d[j].desc.c_str()); 2731 strcpy(entry[0], descLen == 0 ? " " : dti.dta[i].d[j].desc.c_str());
2732 strcpy(entry[1], nameLen == 0 ? " " : dti.dta[i].d[j].name.c_str()); 2732 strcpy(entry[1], nameLen == 0 ? " " : dti.dta[i].d[j].name.c_str());
2733 strcpy(entry[2], pwLen == 0 ? " " : dti.dta[i].d[j].pw.c_str()); 2733 strcpy(entry[2], pwLen == 0 ? " " : dti.dta[i].d[j].pw.c_str());
2734 strcpy(entry[3], commentLen == 0 ? " " : dti.dta[i].d[j].comment.c_str()); 2734 strcpy(entry[3], commentLen == 0 ? " " : dti.dta[i].d[j].comment.c_str());
2735 entry[0][descLen == 0 ? descLen + 1 : descLen] = '\0'; 2735 entry[0][descLen == 0 ? descLen + 1 : descLen] = '\0';
2736 entry[1][nameLen == 0 ? nameLen + 1 : nameLen] = '\0'; 2736 entry[1][nameLen == 0 ? nameLen + 1 : nameLen] = '\0';
2737 entry[2][pwLen == 0 ? pwLen + 1 : pwLen] = '\0'; 2737 entry[2][pwLen == 0 ? pwLen + 1 : pwLen] = '\0';
2738 entry[3][commentLen == 0 ? commentLen + 1 : commentLen] = '\0'; 2738 entry[3][commentLen == 0 ? commentLen + 1 : commentLen] = '\0';
2739 2739
2740 ret = gp.save_entry(entry); 2740 ret = gp.save_entry(entry);
2741 if (ret == -1){ 2741 if (ret == -1){
2742 delete [] entry[0]; 2742 delete [] entry[0];
2743 delete [] entry[1]; 2743 delete [] entry[1];
2744 delete [] entry[2]; 2744 delete [] entry[2];
2745 delete [] entry[3]; 2745 delete [] entry[3];
2746 gp.save_finalize(); 2746 gp.save_finalize();
2747 unlockAll_tempoary(true); 2747 unlockAll_tempoary(true);
2748 return e_writeFile; 2748 return e_writeFile;
2749 } 2749 }
2750 2750
2751 delete [] entry[0]; 2751 delete [] entry[0];
2752 delete [] entry[1]; 2752 delete [] entry[1];
2753 delete [] entry[2]; 2753 delete [] entry[2];
2754 delete [] entry[3]; 2754 delete [] entry[3];
2755 } 2755 }
2756 } 2756 }
2757 unlockAll_tempoary(true); 2757 unlockAll_tempoary(true);
2758 if (gp.save_finalize() == -1) 2758 if (gp.save_finalize() == -1)
2759 return e_writeFile; 2759 return e_writeFile;
2760 2760
2761 return e_success; 2761 return e_success;
2762} 2762}
2763 2763
2764PwMerror PwMDoc::importFromGpasman(const QString *file) 2764PwMerror PwMDoc::importFromGpasman(const QString *file)
2765{ 2765{
2766 PWM_ASSERT(file); 2766 PWM_ASSERT(file);
2767 QString pw = requestMpw(false); 2767 QString pw = requestMpw(false);
2768 if (pw == "") 2768 if (pw == "")
2769 return e_noPw; 2769 return e_noPw;
2770 GpasmanFile gp; 2770 GpasmanFile gp;
2771 int ret, i; 2771 int ret, i;
2772 PwMerror ret2; 2772 PwMerror ret2;
2773 char *entry[4]; 2773 char *entry[4];
2774 PwMDataItem tmpData; 2774 PwMDataItem tmpData;
2775 ret = gp.load_init(file->latin1(), pw.latin1()); 2775 ret = gp.load_init(file->latin1(), pw.latin1());
2776 if (ret != 1) 2776 if (ret != 1)
2777 return e_accessFile; 2777 return e_accessFile;
2778 2778
2779 do { 2779 do {
2780 ret = gp.load_entry(entry); 2780 ret = gp.load_entry(entry);
2781 if(ret != 1) 2781 if(ret != 1)
2782 break; 2782 break;
2783 tmpData.desc = entry[0]; 2783 tmpData.desc = entry[0];
2784 tmpData.name = entry[1]; 2784 tmpData.name = entry[1];
2785 tmpData.pw = entry[2]; 2785 tmpData.pw = entry[2];
2786 tmpData.comment = entry[3]; 2786 tmpData.comment = entry[3];
2787 tmpData.lockStat = true; 2787 tmpData.lockStat = true;
2788 tmpData.listViewPos = -1; 2788 tmpData.listViewPos = -1;
2789 ret2 = addEntry(DEFAULT_CATEGORY, &tmpData, true); 2789 ret2 = addEntry(DEFAULT_CATEGORY, &tmpData, true);
2790 for (i = 0; i < 4; ++i) 2790 for (i = 0; i < 4; ++i)
2791 free(entry[i]); 2791 free(entry[i]);
2792 if (ret2 == e_maxAllowedEntr) { 2792 if (ret2 == e_maxAllowedEntr) {
2793 gp.load_finalize(); 2793 gp.load_finalize();
2794 return e_maxAllowedEntr; 2794 return e_maxAllowedEntr;
2795 } 2795 }
2796 } while (1); 2796 } while (1);
2797 gp.load_finalize(); 2797 gp.load_finalize();
2798 if (isDocEmpty()) 2798 if (isDocEmpty())
2799 return e_wrongPw; // we assume this. 2799 return e_wrongPw; // we assume this.
2800 2800
2801 flagDirty(); 2801 flagDirty();
2802 return e_success; 2802 return e_success;
2803} 2803}
2804 2804
2805
2806//US: we use the stl sort algorythm to sort all elements in the order
2807//of its listViewPos (in the order 1,2,3,5,...,x,-1, -1, -1
2808struct PwMDataItemListViewPosSort
2809{
2810 bool operator()(PwMDataItem* rpStart, PwMDataItem* rpEnd)
2811 {
2812 //qDebug("pwMDoc::PwMDataItemListViewPosSort()");
2813 if ((rpEnd)->listViewPos < 0)
2814 return false;
2815 else
2816 return (rpStart)->listViewPos < (rpEnd)->listViewPos;
2817 }
2818};
2819
2805void PwMDoc::ensureLvp() 2820void PwMDoc::ensureLvp()
2806{ 2821{
2807 if (isDocEmpty()) 2822 if (isDocEmpty())
2808 return; 2823 return;
2809 2824
2810 //US ENH BUG: when using syncronizing, this way of sorting 2825 //US ENH BUG: when using syncronizing, this way of sorting
2811 //is not sufficient, because there might be empty spaces 2826 //is not sufficient, because there might be empty spaces
2812 // at the beginning. But this algorythm only can add elements 2827 // at the beginning. But the old algorythm only can add elements
2813 //to the end.The result are crashes because of listoverflows 2828 //to the end.The result are crashes because of list overflows
2814 //we need something to fill all gaps. 2829 //we need something to fill all gaps.
2815 vector< vector<PwMDataItem>::iterator > undefined; 2830 vector<PwMDataItem*> sorted;
2816 vector< vector<PwMDataItem>::iterator > sorted; 2831 vector< PwMDataItem*>::iterator sortedBegin,
2817 vector< vector<PwMDataItem>::iterator >::iterator undefBegin, 2832 sortedEnd,
2818 undefEnd, 2833 sortedI;
2819 undefI;
2820 vector< vector<PwMDataItem>::iterator >::iterator sortedBegin,
2821 sortedEnd,
2822 sortedI;
2823 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(), 2834 vector<PwMCategoryItem>::iterator catBegin = dti.dta.begin(),
2824 catEnd = dti.dta.end(), 2835 catEnd = dti.dta.end(),
2825 catI = catBegin; 2836 catI = catBegin;
2826 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 2837 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
2827 int lvpTop, tmpLvp; 2838 int lvpTop, tmpLvp;
2828 2839
2840 //qDebug("collect:");
2841
2829 while (catI != catEnd) { 2842 while (catI != catEnd) {
2830 lvpTop = -1; 2843 lvpTop = -1;
2831 undefined.clear(); 2844 sorted.clear();
2832 2845
2833 entrBegin = catI->d.begin(); 2846 entrBegin = catI->d.begin();
2834 entrEnd = catI->d.end(); 2847 entrEnd = catI->d.end();
2835 entrI = entrBegin; 2848 entrI = entrBegin;
2836 2849
2850 //US: we use the stl sort algorythm to sort all elements in the order
2851 //of its listViewPos (in the order 1,2,2,3,5,...,x,-1, -1, -1
2837 while (entrI != entrEnd) { 2852 while (entrI != entrEnd) {
2838 tmpLvp = entrI->listViewPos; 2853 //qDebug("found: %s, pos=%i", (*entrI).desc.c_str(), (*entrI).listViewPos);
2839 if (tmpLvp == -1) 2854 sorted.push_back((PwMDataItem*)&(*entrI));
2840 undefined.push_back(entrI); 2855 ++entrI;
2841 else
2842 sorted[tmpLvp] = entrI;
2843 //US else if (tmpLvp > lvpTop)
2844 //US lvpTop = tmpLvp;
2845 ++entrI;
2846 } 2856 }
2847 2857
2848 //now we have all undefied in the collection. Now insert the existing 2858 sortedBegin = sorted.begin();
2859 sortedEnd = sorted.end();
2860
2861 sort(sortedBegin, sortedEnd, PwMDataItemListViewPosSort());
2862
2863 // qDebug("resort:");
2864 //now we have all sorted in a collection
2865 //Now start with the sorted and reset listviewpos.
2849 sortedBegin = sorted.begin(); 2866 sortedBegin = sorted.begin();
2850 sortedEnd = sorted.end(); 2867 sortedEnd = sorted.end();
2851 sortedI = sortedBegin; 2868 sortedI = sortedBegin;
2852 2869
2853 while (sortedI != sortedEnd) { 2870 while (sortedI != sortedEnd) {
2854 tmpLvp = (*sortedI)->listViewPos; 2871 // qDebug("reset defined: %s, from pos=%i to pos=%i", (*sortedI)->desc.c_str(), (*sortedI)->listViewPos, lvpTop+1);
2855 undefined[tmpLvp] = *sortedI; 2872 (*sortedI)->listViewPos = ++lvpTop;
2856 ++sortedI; 2873 ++sortedI;
2857 } 2874 }
2858 2875
2859 undefBegin = undefined.begin(); 2876 /*/debug
2860 undefEnd = undefined.end(); 2877 entrBegin = catI->d.begin();
2861 undefI = undefBegin; 2878 entrEnd = catI->d.end();
2862 while (undefI != undefEnd) { 2879 entrI = entrBegin;
2863 (*undefI)->listViewPos = ++lvpTop; 2880
2864 ++undefI; 2881 while (entrI != entrEnd) {
2882 qDebug("check: %s, pos=%i", (*entrI).desc.c_str(), (*entrI).listViewPos);
2883 ++entrI;
2865 } 2884 }
2885 */
2886
2866 ++catI; 2887 ++catI;
2867 } 2888 }
2868} 2889}
2869 2890
2870QString PwMDoc::getTitle() 2891QString PwMDoc::getTitle()
2871{ 2892{
2872 /* NOTE: We have to ensure, that the returned title 2893 /* NOTE: We have to ensure, that the returned title
2873 * is unique and not reused somewhere else while 2894 * is unique and not reused somewhere else while
2874 * this document is valid (open). 2895 * this document is valid (open).
2875 */ 2896 */
2876 QString title(getFilename()); 2897 QString title(getFilename());
2877 2898
2878 //US ENH: The whole filename on PDAs is too long. So use only the last characters 2899 //US ENH: The whole filename on PDAs is too long. So use only the last characters
2879 if (QApplication::desktop()->width() < 640) 2900 if (QApplication::desktop()->width() < 640)
2880 { 2901 {
2881 if (title.length() > 30) 2902 if (title.length() > 30)
2882 title = "..." + title.right(30); 2903 title = "..." + title.right(30);
2883 2904
2884 } 2905 }
2885 2906
2886 2907
2887 if (title.isEmpty()) { 2908 if (title.isEmpty()) {
2888 if (unnamedNum == 0) { 2909 if (unnamedNum == 0) {
2889 unnamedNum = PwMDocList::getNewUnnamedNumber(); 2910 unnamedNum = PwMDocList::getNewUnnamedNumber();
2890 PWM_ASSERT(unnamedNum != 0); 2911 PWM_ASSERT(unnamedNum != 0);
2891 } 2912 }
2892 title = DEFAULT_TITLE; 2913 title = DEFAULT_TITLE;
2893 title += " "; 2914 title += " ";
2894 title += tostr(unnamedNum).c_str(); 2915 title += tostr(unnamedNum).c_str();
2895 } 2916 }
2896 return title; 2917 return title;
2897} 2918}
2898 2919
2899bool PwMDoc::tryDelete() 2920bool PwMDoc::tryDelete()
2900{ 2921{
2901 if (deleted) 2922 if (deleted)
2902 return true; 2923 return true;
2903 int ret; 2924 int ret;
2904 if (isDirty()) { 2925 if (isDirty()) {
2905 ret = dirtyAskSave(getTitle()); 2926 ret = dirtyAskSave(getTitle());
2906 if (ret == 0) { // save to disk 2927 if (ret == 0) { // save to disk
2907 if (!saveDocUi(this)) 2928 if (!saveDocUi(this))
2908 goto out_ignore; 2929 goto out_ignore;
2909 } else if (ret == 1) { // don't save and delete 2930 } else if (ret == 1) { // don't save and delete
2910 goto out_accept; 2931 goto out_accept;
2911 } else { // cancel operation 2932 } else { // cancel operation
2912 goto out_ignore; 2933 goto out_ignore;
2913 } 2934 }
2914 } 2935 }
2915out_accept: 2936out_accept:
2916 deleted = true; 2937 deleted = true;
2917 delete this; 2938 delete this;
2918 return true; 2939 return true;
2919out_ignore: 2940out_ignore:
2920 return false; 2941 return false;
2921} 2942}
2922 2943
2923 2944
2924 2945
2925#ifdef PWM_EMBEDDED 2946#ifdef PWM_EMBEDDED
2926//US ENH: this is the magic function that syncronizes the this doc with the remote doc 2947//US ENH: this is the magic function that syncronizes the this doc with the remote doc
2927//US it could have been defined as static, but I did not want to. 2948//US it could have been defined as static, but I did not want to.
2928PwMerror PwMDoc::syncronize(KSyncManager* manager, PwMDoc* syncLocal , PwMDoc* syncRemote, int mode ) 2949PwMerror PwMDoc::syncronize(KSyncManager* manager, PwMDoc* syncLocal , PwMDoc* syncRemote, int mode )
2929{ 2950{
2930 int addedPasswordsLocal = 0; 2951 int addedPasswordsLocal = 0;
2931 int addedPasswordsRemote = 0; 2952 int addedPasswordsRemote = 0;
2932 int deletedPasswordsRemote = 0; 2953 int deletedPasswordsRemote = 0;
2933 int deletedPasswordsLocal = 0; 2954 int deletedPasswordsLocal = 0;
2934 int changedLocal = 0; 2955 int changedLocal = 0;
2935 int changedRemote = 0; 2956 int changedRemote = 0;
2936 2957
2937 PwMSyncItem* syncItemLocal; 2958 PwMSyncItem* syncItemLocal;
2938 PwMSyncItem* syncItemRemote; 2959 PwMSyncItem* syncItemRemote;
2939 2960
2940 QString mCurrentSyncName = manager->getCurrentSyncName(); 2961 QString mCurrentSyncName = manager->getCurrentSyncName();
2941 QString mCurrentSyncDevice = manager->getCurrentSyncDevice(); 2962 QString mCurrentSyncDevice = manager->getCurrentSyncDevice();
2942 2963
2943 bool fullDateRange = false; 2964 bool fullDateRange = false;
2944 int take; 2965 int take;
2945 // local->resetTempSyncStat(); 2966 // local->resetTempSyncStat();
2946 QDateTime mLastSync = QDateTime::currentDateTime(); 2967 QDateTime mLastSync = QDateTime::currentDateTime();
2947 QDateTime modifiedSync = mLastSync; 2968 QDateTime modifiedSync = mLastSync;
2948 2969
2949 unsigned int index; 2970 unsigned int index;
2950 //Step 1. Find syncinfo in Local file and create if not existent. 2971 //Step 1. Find syncinfo in Local file and create if not existent.
2951 bool found = syncLocal->findSyncData(mCurrentSyncDevice, &index); 2972 bool found = syncLocal->findSyncData(mCurrentSyncDevice, &index);
2952 if (found == false) 2973 if (found == false)
2953 { 2974 {
2954 PwMSyncItem newSyncItemLocal; 2975 PwMSyncItem newSyncItemLocal;
2955 newSyncItemLocal.syncName = mCurrentSyncDevice; 2976 newSyncItemLocal.syncName = mCurrentSyncDevice;
2956 newSyncItemLocal.lastSyncDate = mLastSync; 2977 newSyncItemLocal.lastSyncDate = mLastSync;
2957 syncLocal->addSyncDataEntry(&newSyncItemLocal, true); 2978 syncLocal->addSyncDataEntry(&newSyncItemLocal, true);
2958 found = syncLocal->findSyncData(mCurrentSyncDevice, &index); 2979 found = syncLocal->findSyncData(mCurrentSyncDevice, &index);
2959 if (found == false) { 2980 if (found == false) {
2960 qDebug("PwMDoc::syncronize : newly created local sync data could not be found"); 2981 qDebug("PwMDoc::syncronize : newly created local sync data could not be found");
2961 return e_syncError; 2982 return e_syncError;
2962 } 2983 }
2963 } 2984 }
2964 2985
2965 syncItemLocal = syncLocal->getSyncDataEntry(index); 2986 syncItemLocal = syncLocal->getSyncDataEntry(index);
2966 qDebug("Last Sync Local %s ", syncItemLocal->lastSyncDate.toString().latin1()); 2987 qDebug("Last Sync Local %s ", syncItemLocal->lastSyncDate.toString().latin1());
2967 2988
2968 //Step 2. Find syncinfo in remote file and create if not existent. 2989 //Step 2. Find syncinfo in remote file and create if not existent.
2969 found = syncRemote->findSyncData(mCurrentSyncName, &index); 2990 found = syncRemote->findSyncData(mCurrentSyncName, &index);
2970 if (found == false) 2991 if (found == false)
2971 { 2992 {
2972 qDebug("FULLDATE 1"); 2993 qDebug("FULLDATE 1");
2973 fullDateRange = true; 2994 fullDateRange = true;
2974 PwMSyncItem newSyncItemRemote; 2995 PwMSyncItem newSyncItemRemote;
2975 newSyncItemRemote.syncName = mCurrentSyncName; 2996 newSyncItemRemote.syncName = mCurrentSyncName;
2976 newSyncItemRemote.lastSyncDate = mLastSync; 2997 newSyncItemRemote.lastSyncDate = mLastSync;
2977 syncRemote->addSyncDataEntry(&newSyncItemRemote, true); 2998 syncRemote->addSyncDataEntry(&newSyncItemRemote, true);
2978 found = syncRemote->findSyncData(mCurrentSyncName, &index); 2999 found = syncRemote->findSyncData(mCurrentSyncName, &index);
2979 if (found == false) { 3000 if (found == false) {
2980 qDebug("PwMDoc::syncronize : newly created remote sync data could not be found"); 3001 qDebug("PwMDoc::syncronize : newly created remote sync data could not be found");
2981 return e_syncError; 3002 return e_syncError;
2982 } 3003 }
2983 } 3004 }
2984 3005
2985 syncItemRemote = syncRemote->getSyncDataEntry(index); 3006 syncItemRemote = syncRemote->getSyncDataEntry(index);
2986 qDebug("Last Sync Remote %s ", syncItemRemote->lastSyncDate.toString().latin1()); 3007 qDebug("Last Sync Remote %s ", syncItemRemote->lastSyncDate.toString().latin1());
2987 //and remove the found entry here. We will reenter it later again. 3008 //and remove the found entry here. We will reenter it later again.
2988 //US syncRemote->delSyncDataEntry(index, true); 3009 //US syncRemote->delSyncDataEntry(index, true);
2989 3010
2990 3011
2991 if ( syncItemLocal->lastSyncDate == mLastSync ) { 3012 if ( syncItemLocal->lastSyncDate == mLastSync ) {
2992 qDebug("FULLDATE 2"); 3013 qDebug("FULLDATE 2");
2993 fullDateRange = true; 3014 fullDateRange = true;
2994 } 3015 }
2995 3016
2996 if ( ! fullDateRange ) { 3017 if ( ! fullDateRange ) {
2997 if ( syncItemLocal->lastSyncDate != syncItemRemote->lastSyncDate ) { 3018 if ( syncItemLocal->lastSyncDate != syncItemRemote->lastSyncDate ) {
2998 3019
2999 // qDebug("set fulldate to true %s %s" ,syncItemLocal->lastSyncDate.toString().latin1(), syncItemRemote->lastSyncDate.toString().latin1() );
3000 // qDebug("%d %d %d %d ", syncItemLocal->lastSyncDate.time().second(), addresseeLSync->dtStart().time().msec() , addresseeRSync->dtStart().time().second(), addresseeRSync->dtStart().time().msec());
3001 fullDateRange = true; 3020 fullDateRange = true;
3002 qDebug("FULLDATE 3 %s %s", syncItemLocal->lastSyncDate.toString().latin1() , syncItemRemote->lastSyncDate.toString().latin1() ); 3021 qDebug("FULLDATE 3 %s %s", syncItemLocal->lastSyncDate.toString().latin1() , syncItemRemote->lastSyncDate.toString().latin1() );
3003 } 3022 }
3004 } 3023 }
3005 // fullDateRange = true; // debug only! 3024 // fullDateRange = true; // debug only!
3006 if ( fullDateRange ) 3025 if ( fullDateRange )
3007 mLastSync = QDateTime::currentDateTime().addDays( -100*365); 3026 mLastSync = QDateTime::currentDateTime().addDays( -100*365);
3008 else 3027 else
3009 mLastSync = syncItemLocal->lastSyncDate; 3028 mLastSync = syncItemLocal->lastSyncDate;
3010 3029
3011 3030
3012 qDebug("*************************** "); 3031 qDebug("*************************** ");
3013 qDebug("mLastSync %s ",mLastSync.toString().latin1() ); 3032 qDebug("mLastSync %s ",mLastSync.toString().latin1() );
3014 QStringList er = syncRemote->getIDEntryList(); 3033 QStringList er = syncRemote->getIDEntryList();
3015 PwMDataItem* inRemote ;//= er.first(); 3034 PwMDataItem* inRemote ;//= er.first();
3016 PwMDataItem* inLocal; 3035 PwMDataItem* inLocal;
3017 unsigned int catLocal, indexLocal; 3036 unsigned int catLocal, indexLocal;
3018 unsigned int catRemote, indexRemote; 3037 unsigned int catRemote, indexRemote;
3019 3038
3020 QString uid; 3039 QString uid;
3021 manager->showProgressBar(0, i18n("Syncing - close to abort!"), er.count()); 3040 manager->showProgressBar(0, i18n("Syncing - close to abort!"), er.count());
3022 3041
3023 int modulo = (er.count()/10)+1; 3042 int modulo = (er.count()/10)+1;
3024 unsigned int incCounter = 0; 3043 unsigned int incCounter = 0;
3025 while ( incCounter < er.count()) { 3044 while ( incCounter < er.count()) {
3026 if (manager->isProgressBarCanceled()) 3045 if (manager->isProgressBarCanceled())
3027 return e_syncError; 3046 return e_syncError;
3028 if ( incCounter % modulo == 0 ) 3047 if ( incCounter % modulo == 0 )
3029 manager->showProgressBar(incCounter); 3048 manager->showProgressBar(incCounter);
3030 3049
3031 uid = er[ incCounter ]; 3050 uid = er[ incCounter ];
3032 qDebug("sync uid %s from remote file", uid.latin1()); 3051 qDebug("sync uid %s from remote file", uid.latin1());
3033 3052
3034 qApp->processEvents(); 3053 qApp->processEvents();
3035 3054
3036 inLocal = syncLocal->findEntryByID( uid, &catLocal, &indexLocal ); 3055 inLocal = syncLocal->findEntryByID( uid, &catLocal, &indexLocal );
3037 inRemote = syncRemote->findEntryByID( uid, &catRemote, &indexRemote ); 3056 inRemote = syncRemote->findEntryByID( uid, &catRemote, &indexRemote );
3038 PWM_ASSERT(inRemote); 3057 PWM_ASSERT(inRemote);
3039 if ( inLocal != 0 ) { // maybe conflict - same uid in both files 3058 if ( inLocal != 0 ) { // maybe conflict - same uid in both files
3040 if ( (take = takePwMDataItem( inLocal, inRemote, mLastSync, mode, fullDateRange) ) ) { 3059 if ( (take = takePwMDataItem( inLocal, inRemote, mLastSync, mode, fullDateRange) ) ) {
3041 qDebug("take %d %s ", take, inLocal->desc.c_str()); 3060 qDebug("take %d %s ", take, inLocal->desc.c_str());
3042 if ( take == 3 ) 3061 if ( take == 3 )
3043 return e_syncError; 3062 return e_syncError;
3044 if ( take == 1 ) {// take local 3063 if ( take == 1 ) {// take local
3045 //US syncRemote->removeAddressee( inRemote ); 3064 int oldlistpos = inRemote->listViewPos;
3046 (*inRemote) = (*inLocal); 3065 (*inRemote) = (*inLocal);
3047 //US syncRemote->insertAddressee( inRemote , false); 3066 inRemote->listViewPos = oldlistpos;
3048 ++changedRemote; 3067 ++changedRemote;
3049 } else { // take == 2 take remote 3068 } else { // take == 2 take remote
3050 //US syncLocal->removeAddressee( inLocal ); 3069 int oldlistpos = inLocal->listViewPos;
3051 (*inLocal) = (*inRemote); 3070 (*inLocal) = (*inRemote);
3052 //US syncLocal->insertAddressee( inLocal , false ); 3071 inLocal->listViewPos = oldlistpos;
3053 ++changedLocal; 3072 ++changedLocal;
3054 } 3073 }
3055 } 3074 }
3056 } else { // no conflict 3075 } else { // no conflict
3057 if ( inRemote->meta.update > mLastSync || mode == 5 ) { 3076 if ( inRemote->meta.update > mLastSync || mode == 5 ) {
3058 inRemote->meta.update = modifiedSync; 3077 inRemote->meta.update = modifiedSync;
3059 3078
3060 //first check if we have a matching category in the local file 3079 //first check if we have a matching category in the local file
3061 const string* remotecat = syncRemote->getCategory(catRemote); 3080 const string* remotecat = syncRemote->getCategory(catRemote);
3062 //US syncRemote->insertAddressee( inRemote, false ); 3081 //US syncRemote->insertAddressee( inRemote, false );
3063 //US syncLocal->insertAddressee( inRemote, false ); 3082 //US syncLocal->insertAddressee( inRemote, false );
3064 syncLocal->addEntry(remotecat->c_str(), inRemote, true, false); 3083 syncLocal->addEntry(remotecat->c_str(), inRemote, true, false);
3065 3084
3066 ++addedPasswordsLocal; 3085 ++addedPasswordsLocal;
3067 } else { 3086 } else {
3068 // pending checkExternSyncAddressee(addresseeRSyncSharp, inR); 3087 // pending checkExternSyncAddressee(addresseeRSyncSharp, inR);
3069 syncRemote->delEntry(catRemote, indexRemote, true); 3088 syncRemote->delEntry(catRemote, indexRemote, true);
3070 //USsyncRemote->removeAddressee( inRemote ); 3089 //USsyncRemote->removeAddressee( inRemote );
3071 ++deletedPasswordsRemote; 3090 ++deletedPasswordsRemote;
3072 } 3091 }
3073 } 3092 }
3074 3093
3075 ++incCounter; 3094 ++incCounter;
3076 } 3095 }
3077 3096
3078 3097
3079 er.clear(); 3098 er.clear();
3080 QStringList el = syncLocal->getIDEntryList(); 3099 QStringList el = syncLocal->getIDEntryList();
3081 modulo = (el.count()/10)+1; 3100 modulo = (el.count()/10)+1;
3082 3101
3083 manager->showProgressBar(0, i18n("Add / remove addressees"), el.count()); 3102 manager->showProgressBar(0, i18n("Add / remove addressees"), el.count());
3084 incCounter = 0; 3103 incCounter = 0;
3085 while ( incCounter < el.count()) { 3104 while ( incCounter < el.count()) {
3086 qApp->processEvents(); 3105 qApp->processEvents();
3087 if (manager->isProgressBarCanceled()) 3106 if (manager->isProgressBarCanceled())
3088 return e_syncError; 3107 return e_syncError;
3089 if ( incCounter % modulo == 0 ) 3108 if ( incCounter % modulo == 0 )
3090 manager->showProgressBar(incCounter); 3109 manager->showProgressBar(incCounter);
3091 uid = el[ incCounter ]; 3110 uid = el[ incCounter ];
3092 qDebug("sync uid %s from local file", uid.latin1()); 3111 qDebug("sync uid %s from local file", uid.latin1());
3093 3112
3094 inLocal = syncLocal->findEntryByID( uid, &catLocal, &indexLocal ); 3113 inLocal = syncLocal->findEntryByID( uid, &catLocal, &indexLocal );
3095 inRemote = syncRemote->findEntryByID( uid, &catRemote, &indexRemote ); 3114 inRemote = syncRemote->findEntryByID( uid, &catRemote, &indexRemote );
3096 PWM_ASSERT(inLocal); 3115 PWM_ASSERT(inLocal);
3097 3116
3098 if ( inRemote == 0 ) { 3117 if ( inRemote == 0 ) {
3099 if ( inLocal->meta.update < mLastSync && mode != 4 ) { 3118 if ( inLocal->meta.update < mLastSync && mode != 4 ) {
3100 // pending checkExternSyncAddressee(addresseeLSyncSharp, inL); 3119 // pending checkExternSyncAddressee(addresseeLSyncSharp, inL);
3101 syncLocal->delEntry(catLocal, indexLocal, true); 3120 syncLocal->delEntry(catLocal, indexLocal, true);
3102 //USsyncLocal->removeAddressee( inLocal ); 3121 //USsyncLocal->removeAddressee( inLocal );
3103 ++deletedPasswordsLocal; 3122 ++deletedPasswordsLocal;
3104 } else { 3123 } else {
3105 if ( ! manager->mWriteBackExistingOnly ) { 3124 if ( ! manager->mWriteBackExistingOnly ) {
3106 ++addedPasswordsRemote; 3125 ++addedPasswordsRemote;
3107 inLocal->meta.update = modifiedSync; 3126 inLocal->meta.update = modifiedSync;
3108 3127
3109 //first check if we have a matching category in the remote file 3128 //first check if we have a matching category in the remote file
3110 const string* localcat = syncLocal->getCategory(catLocal); 3129 const string* localcat = syncLocal->getCategory(catLocal);
3111 3130
3112 //USsyncLocal->insertAddressee( inLocal, false ); 3131 //USsyncLocal->insertAddressee( inLocal, false );
3113 PwMDataItem newEntry; 3132 PwMDataItem newEntry;
3114 newEntry = *inLocal; 3133 newEntry = *inLocal;
3115 inRemote = &newEntry; 3134 inRemote = &newEntry;
3116 3135
3117 //USsyncRemote->insertAddressee( inRemote, false ); 3136 //USsyncRemote->insertAddressee( inRemote, false );
3118 syncRemote->addEntry(localcat->c_str(), inRemote, true, false); 3137 syncRemote->addEntry(localcat->c_str(), inRemote, true, false);
3119 3138
3120 } 3139 }
3121 } 3140 }
3122 3141
3123 } 3142 }
3124 ++incCounter; 3143 ++incCounter;
3125 } 3144 }
3126 el.clear(); 3145 el.clear();
3127 manager->hideProgressBar(); 3146 manager->hideProgressBar();
3128 3147
3129 // Now write the info back into the sync data space of the files 3148 // Now write the info back into the sync data space of the files
3130 3149
3131 mLastSync = QDateTime::currentDateTime().addSecs( 1 ); 3150 mLastSync = QDateTime::currentDateTime().addSecs( 1 );
3132 // get rid of micro seconds 3151 // get rid of micro seconds
3133 QTime t = mLastSync.time(); 3152 QTime t = mLastSync.time();
3134 mLastSync.setTime( QTime (t.hour (), t.minute (), t.second () ) ); 3153 mLastSync.setTime( QTime (t.hour (), t.minute (), t.second () ) );
3135 3154
3136 3155
3137 syncItemLocal->lastSyncDate = mLastSync; 3156 syncItemLocal->lastSyncDate = mLastSync;
3138 syncItemRemote->lastSyncDate = mLastSync; 3157 syncItemRemote->lastSyncDate = mLastSync;
3139 3158
3140 // addresseeRSync.setRole( i18n("!Remote from: ")+mCurrentSyncName ) ;
3141 // addresseeLSync.setRole(i18n("!Local from: ") + mCurrentSyncName );
3142
3143 //US syncRemote->addSyncDataEntry( syncItemRemote, false );
3144 //US syncLocal->addSyncDataEntry( syncItemLocal, false );
3145 QString mes; 3159 QString mes;
3146 mes .sprintf( i18n("Synchronization summary:\n\n %d items added to local\n %d items added to remote\n %d items updated on local\n %d items updated on remote\n %d items deleted on local\n %d items deleted on remote\n"),addedPasswordsLocal, addedPasswordsRemote, changedLocal, changedRemote, deletedPasswordsLocal, deletedPasswordsRemote ); 3160 mes .sprintf( i18n("Synchronization summary:\n\n %d items added to local\n %d items added to remote\n %d items updated on local\n %d items updated on remote\n %d items deleted on local\n %d items deleted on remote\n"),addedPasswordsLocal, addedPasswordsRemote, changedLocal, changedRemote, deletedPasswordsLocal, deletedPasswordsRemote );
3147 if ( manager->mShowSyncSummary ) { 3161 if ( manager->mShowSyncSummary ) {
3148 KMessageBox::information(0, mes, i18n("PWM/Pi Synchronization") ); 3162 KMessageBox::information(0, mes, i18n("PWM/Pi Synchronization") );
3149 } 3163 }
3150 qDebug( mes ); 3164 qDebug( mes );
3151 return e_success; 3165 return e_success;
3152} 3166}
3153 3167
3154 3168
3155int PwMDoc::takePwMDataItem( PwMDataItem* local, PwMDataItem* remote, QDateTime lastSync, int mode , bool full ) 3169int PwMDoc::takePwMDataItem( PwMDataItem* local, PwMDataItem* remote, QDateTime lastSync, int mode , bool full )
3156{ 3170{
3157 // 0 equal 3171 // 0 equal
3158 // 1 take local 3172 // 1 take local
3159 // 2 take remote 3173 // 2 take remote
3160 // 3 cancel 3174 // 3 cancel
3161 QDateTime localMod = local->meta.update; 3175 QDateTime localMod = local->meta.update;
3162 QDateTime remoteMod = remote->meta.update; 3176 QDateTime remoteMod = remote->meta.update;
3163 3177
3164 //US QString mCurrentSyncDevice = syncManager->getCurrentSyncDevice(); 3178 //US QString mCurrentSyncDevice = syncManager->getCurrentSyncDevice();
3165 3179
3166 if ( localMod == remoteMod ) 3180 if ( localMod == remoteMod )
3167 return 0; 3181 return 0;
3168 3182
3169 qDebug(" %d %d conflict on %s %s ", mode, full, local->desc.c_str(), remote->desc.c_str() ); 3183 qDebug(" %d %d conflict on %s %s ", mode, full, local->desc.c_str(), remote->desc.c_str() );
3170 3184
3171 //qDebug("%s %d %s %d", local->lastModified().toString().latin1() , localMod, remote->lastModified().toString().latin1(), remoteMod); 3185 //qDebug("%s %d %s %d", local->lastModified().toString().latin1() , localMod, remote->lastModified().toString().latin1(), remoteMod);
3172 //qDebug("%d %d %d %d ", local->lastModified().time().second(), local->lastModified().time().msec(), remote->lastModified().time().second(), remote->lastModified().time().msec() ); 3186 //qDebug("%d %d %d %d ", local->lastModified().time().second(), local->lastModified().time().msec(), remote->lastModified().time().second(), remote->lastModified().time().msec() );
3173 full = true; //debug only 3187 //full = true; //debug only
3174 if ( full ) { 3188 if ( full ) {
3175 bool equ = ( (*local) == (*remote) ); 3189 bool equ = ( (*local) == (*remote) );
3176 if ( equ ) { 3190 if ( equ ) {
3177 qDebug("equal "); 3191 //qDebug("equal ");
3178 if ( mode < SYNC_PREF_FORCE_LOCAL ) 3192 if ( mode < SYNC_PREF_FORCE_LOCAL )
3179 return 0; 3193 return 0;
3180 3194
3181 }else //debug only 3195 }//else //debug only
3182 qDebug("not equal %s %s ", local->desc.c_str(), remote->desc.c_str()); 3196 //qDebug("not equal %s %s ", local->desc.c_str(), remote->desc.c_str());
3183 } 3197 }
3184 3198
3185 int result; 3199 int result;
3186 bool localIsNew; 3200 bool localIsNew;
3187 //qDebug("%s -- %s mLastCalendarSync %s lastsync %s --- local %s remote %s ",local->summary().latin1(), remote->summary().latin1(),mLastCalendarSync.toString().latin1() ,lastSync.toString().latin1() , local->lastModified().toString().latin1() , remote->lastModified().toString().latin1() ); 3201 //qDebug("%s -- %s mLastCalendarSync %s lastsync %s --- local %s remote %s ",local->summary().latin1(), remote->summary().latin1(),mLastCalendarSync.toString().latin1() ,lastSync.toString().latin1() , local->lastModified().toString().latin1() , remote->lastModified().toString().latin1() );
3188 3202
3189 if ( full && mode < SYNC_PREF_NEWEST ) 3203 if ( full && mode < SYNC_PREF_NEWEST )
3190 mode = SYNC_PREF_ASK; 3204 mode = SYNC_PREF_ASK;
3191 3205
3192 switch( mode ) { 3206 switch( mode ) {
3193 case SYNC_PREF_LOCAL: 3207 case SYNC_PREF_LOCAL:
3194 if ( lastSync > remoteMod ) 3208 if ( lastSync > remoteMod )
3195 return 1; 3209 return 1;
3196 if ( lastSync > localMod ) 3210 if ( lastSync > localMod )
3197 return 2; 3211 return 2;
3198 return 1; 3212 return 1;
3199 break; 3213 break;
3200 case SYNC_PREF_REMOTE: 3214 case SYNC_PREF_REMOTE:
3201 if ( lastSync > remoteMod ) 3215 if ( lastSync > remoteMod )
3202 return 1; 3216 return 1;
3203 if ( lastSync > localMod ) 3217 if ( lastSync > localMod )
3204 return 2; 3218 return 2;
3205 return 2; 3219 return 2;
3206 break; 3220 break;
3207 case SYNC_PREF_NEWEST: 3221 case SYNC_PREF_NEWEST:
3208 if ( localMod > remoteMod ) 3222 if ( localMod > remoteMod )
3209 return 1; 3223 return 1;
3210 else 3224 else
3211 return 2; 3225 return 2;
3212 break; 3226 break;
3213 case SYNC_PREF_ASK: 3227 case SYNC_PREF_ASK:
3214 //qDebug("lsy %s --- lo %s --- re %s ", lastSync.toString().latin1(), localMod.toString().latin1(), remoteMod.toString().latin1() ); 3228 //qDebug("lsy %s --- lo %s --- re %s ", lastSync.toString().latin1(), localMod.toString().latin1(), remoteMod.toString().latin1() );
3215 if ( lastSync > remoteMod ) 3229 if ( lastSync > remoteMod )
3216 return 1; 3230 return 1;
3217 if ( lastSync > localMod ) 3231 if ( lastSync > localMod )
3218 return 2; 3232 return 2;
3219 localIsNew = localMod >= remoteMod; 3233 localIsNew = localMod >= remoteMod;
3220 //qDebug("conflict! ************************************** "); 3234 //qDebug("conflict! ************************************** ");
3221 { 3235 {
3222 PwMDataItemChooser acd ( *local,*remote, localIsNew , 0/*this*/ ); 3236 PwMDataItemChooser acd ( *local,*remote, localIsNew , 0/*this*/ );
3223 result = acd.executeD(localIsNew); 3237 result = acd.executeD(localIsNew);
3224 return result; 3238 return result;
3225 } 3239 }
3226 break; 3240 break;
3227 case SYNC_PREF_FORCE_LOCAL: 3241 case SYNC_PREF_FORCE_LOCAL:
3228 return 1; 3242 return 1;
3229 break; 3243 break;
3230 case SYNC_PREF_FORCE_REMOTE: 3244 case SYNC_PREF_FORCE_REMOTE:
3231 return 2; 3245 return 2;
3232 break; 3246 break;
3233 3247
3234 default: 3248 default:
3235 // SYNC_PREF_TAKE_BOTH not implemented 3249 // SYNC_PREF_TAKE_BOTH not implemented
3236 break; 3250 break;
3237 } 3251 }
3238 return 0; 3252 return 0;
3239} 3253}
3240 3254
3241 3255
3242 3256
3243 3257
3244//this are the overwritten callbackmethods from the syncinterface 3258//this are the overwritten callbackmethods from the syncinterface
3245bool PwMDoc::sync(KSyncManager* manager, QString filename, int mode) 3259bool PwMDoc::sync(KSyncManager* manager, QString filename, int mode)
3246{ 3260{
3247 QString mCurrentSyncDevice = manager->getCurrentSyncDevice(); 3261 QString mCurrentSyncDevice = manager->getCurrentSyncDevice();
3248 3262
3249 //1) unlock local file first if necessary (ask for password) 3263 //1) unlock local file first if necessary (ask for password)
3250 if (this->isDeepLocked()) { 3264 if (this->isDeepLocked()) {
3251 PwMerror ret = this->deepLock(false); 3265 PwMerror ret = this->deepLock(false);
3252 if (ret != e_success) 3266 if (ret != e_success)
3253 return false; 3267 return false;
3254 } 3268 }
3255 3269
3256 //2) construct and open a new doc on the stack(automatic cleanup of remote file). 3270 //2) construct and open a new doc on the stack(automatic cleanup of remote file).
3257 PwMDoc syncTarget(this, "synctarget"); 3271 PwMDoc syncTarget(this, "synctarget");
3258 PwMDoc* pSyncTarget = &syncTarget; 3272 PwMDoc* pSyncTarget = &syncTarget;
3259 3273
3260 3274
3261 PwMerror err = pSyncTarget->openDoc(&filename, 1 /*== open with all entries locked*/); 3275 PwMerror err = pSyncTarget->openDoc(&filename, 1 /*== open with all entries locked*/);
3262 3276
3263 if (err == e_alreadyOpen) { 3277 if (err == e_alreadyOpen) {
3264 PwMDocList::listItem li; 3278 PwMDocList::listItem li;
3265 if (getOpenDocList()->find(filename.latin1(), &li)) 3279 if (getOpenDocList()->find(filename.latin1(), &li))
3266 pSyncTarget = li.doc; 3280 pSyncTarget = li.doc;
3267 else { 3281 else {
3268 qDebug("PwmDoc::sync: sync failed. Error %i while opening file %s",err, filename.latin1()); 3282 qDebug("PwmDoc::sync: sync failed. Error %i while opening file %s",err, filename.latin1());
3269 return false; 3283 return false;
3270 } 3284 }
3271 } 3285 }
3272 else if (err != e_success) { 3286 else if (err != e_success) {
3273 qDebug("PwmDoc::sync: sync failed. Error %i while opening file %s",err, filename.latin1()); 3287 qDebug("PwmDoc::sync: sync failed. Error %i while opening file %s",err, filename.latin1());
3274 return false; 3288 return false;
3275 } 3289 }
3276 3290
3277 qDebug("PWM file loaded %s,sync mode %d",filename.latin1(), mode ); 3291 qDebug("PWM file loaded %s,sync mode %d",filename.latin1(), mode );
3278 3292
3279 3293
3280 //3) unlock remote file first if necessary (ask for password) 3294 //3) unlock remote file first if necessary (ask for password)
3281 if (pSyncTarget->isDeepLocked()) { 3295 if (pSyncTarget->isDeepLocked()) {
3282 PwMerror ret = pSyncTarget->deepLock(false); 3296 PwMerror ret = pSyncTarget->deepLock(false);
3283 if (ret != e_success) 3297 if (ret != e_success)
3284 return false; 3298 return false;
3285 } 3299 }
3286 3300
3287 3301
3288 err = syncronize(manager, this, pSyncTarget, mode ); 3302 err = syncronize(manager, this, pSyncTarget, mode );
3289 3303
3290 if (err == e_success) { 3304 if (err == e_success) {
3291 if ( manager->mWriteBackFile ){ 3305 if ( manager->mWriteBackFile ){
3292 qDebug("Saving remote PWManager file"); 3306 qDebug("Saving remote PWManager file");
3293 err = pSyncTarget->saveDoc(conf()->confGlobCompression()); 3307 err = pSyncTarget->saveDoc(conf()->confGlobCompression());
3294 if (err != e_success) { 3308 if (err != e_success) {
3295 qDebug("PwmDoc::sync: Sync failed. Error %i while storing file %s",err, filename.latin1()); 3309 qDebug("PwmDoc::sync: Sync failed. Error %i while storing file %s",err, filename.latin1());
3296 return false; 3310 return false;
3297 } 3311 }
3298 } 3312 }
3299 3313
3300 flagDirty(); 3314 flagDirty();
3301 return true; 3315 return true;
3302 } 3316 }
3303 else { 3317 else {
3304 return false; 3318 return false;
3305 } 3319 }
3306} 3320}
3307 3321
3308#endif 3322#endif
3309 3323
3310 3324
3311bool PwMDoc::findSyncData(const QString &syncname, unsigned int *index) 3325bool PwMDoc::findSyncData(const QString &syncname, unsigned int *index)
3312{ 3326{
3313 vector<PwMSyncItem>::iterator i = dti.syncDta.begin(), 3327 vector<PwMSyncItem>::iterator i = dti.syncDta.begin(),
3314 end = dti.syncDta.end(); 3328 end = dti.syncDta.end();
3315 3329
3316 while (i != end) { 3330 while (i != end) {
3317 if ((*i).syncName == syncname.latin1()) { 3331 if ((*i).syncName == syncname.latin1()) {
3318 if (index) { 3332 if (index) {
3319 *index = i - dti.syncDta.begin(); 3333 *index = i - dti.syncDta.begin();
3320 } 3334 }
3321 return true; 3335 return true;
3322 } 3336 }
3323 ++i; 3337 ++i;
3324 } 3338 }
3325 return false; 3339 return false;
3326}; 3340};
3327 3341
3328/** add new syncdataentry */ 3342/** add new syncdataentry */
3329PwMerror PwMDoc::addSyncDataEntry(PwMSyncItem *d, bool dontFlagDirty) 3343PwMerror PwMDoc::addSyncDataEntry(PwMSyncItem *d, bool dontFlagDirty)
3330{ 3344{
3331 PWM_ASSERT(d); 3345 PWM_ASSERT(d);
3332 3346
3333 if (isDeepLocked()) { 3347 if (isDeepLocked()) {
3334 PwMerror ret; 3348 PwMerror ret;
3335 ret = deepLock(false); 3349 ret = deepLock(false);
3336 if (ret != e_success) 3350 if (ret != e_success)
3337 return e_lock; 3351 return e_lock;
3338 } 3352 }
3339 unsigned int index; 3353 unsigned int index;
3340 3354
3341 const QString tmp = d->syncName.c_str(); 3355 const QString tmp = d->syncName.c_str();
3342 bool exists = findSyncData(d->syncName.c_str(), &index); 3356 bool exists = findSyncData(d->syncName.c_str(), &index);
3343 3357
3344 if (exists == true) { 3358 if (exists == true) {
3345 // DOH! We found this entry. 3359 // DOH! We found this entry.
3346 return e_entryExists; 3360 return e_entryExists;
3347 } 3361 }
3348 3362
3349 dti.syncDta.push_back(*d); 3363 dti.syncDta.push_back(*d);
3350 3364
3351 if (!dontFlagDirty) 3365 if (!dontFlagDirty)
3352 flagDirty(); 3366 flagDirty();
3353 return e_success; 3367 return e_success;
3354} 3368}
3355 3369
3356 3370
3357 3371
3358/** delete syncdata entry */ 3372/** delete syncdata entry */
3359bool PwMDoc::delSyncDataEntry(unsigned int index, bool dontFlagDirty) 3373bool PwMDoc::delSyncDataEntry(unsigned int index, bool dontFlagDirty)
3360{ 3374{
3361 if (isDeepLocked()) 3375 if (isDeepLocked())
3362 return false; 3376 return false;
3363 if (index > dti.syncDta.size() - 1) 3377 if (index > dti.syncDta.size() - 1)
3364 return false; 3378 return false;
3365 3379
3366 // delete entry 3380 // delete entry
3367 dti.syncDta.erase(dti.syncDta.begin() + index); 3381 dti.syncDta.erase(dti.syncDta.begin() + index);
3368 3382
3369 if (!dontFlagDirty) 3383 if (!dontFlagDirty)
3370 flagDirty(); 3384 flagDirty();
3371 return true; 3385 return true;
3372} 3386}
3373 3387
3374 3388
3375PwMDataItem* PwMDoc::findEntryByID(const QString &uid, unsigned int *category, unsigned int *index) 3389PwMDataItem* PwMDoc::findEntryByID(const QString &uid, unsigned int *category, unsigned int *index)
3376{ 3390{
3377 vector<PwMCategoryItem>::iterator catcounter = dti.dta.begin(), 3391 vector<PwMCategoryItem>::iterator catcounter = dti.dta.begin(),
3378 catend = dti.dta.end(); 3392 catend = dti.dta.end();
3379 3393
3380 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 3394 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
3381 3395
3382 while (catcounter != catend) { 3396 while (catcounter != catend) {
3383 entrBegin = catcounter->d.begin(); 3397 entrBegin = catcounter->d.begin();
3384 entrEnd = catcounter->d.end(); 3398 entrEnd = catcounter->d.end();
3385 entrI = entrBegin; 3399 entrI = entrBegin;
3386 while (entrI != entrEnd) { 3400 while (entrI != entrEnd) {
3387 if ((*entrI).meta.uniqueid == uid.latin1()) { 3401 if ((*entrI).meta.uniqueid == uid.latin1()) {
3388 if (category) 3402 if (category)
3389 *category = catcounter - dti.dta.begin(); 3403 *category = catcounter - dti.dta.begin();
3390 if (index) 3404 if (index)
3391 *index = entrI - entrBegin; 3405 *index = entrI - entrBegin;
3392 3406
3393 return &(*entrI); 3407 return &(*entrI);
3394 } 3408 }
3395 ++entrI; 3409 ++entrI;
3396 } 3410 }
3397 ++catcounter; 3411 ++catcounter;
3398 } 3412 }
3399 3413
3400 return 0; 3414 return 0;
3401} 3415}
3402 3416
3403QStringList PwMDoc::getIDEntryList() 3417QStringList PwMDoc::getIDEntryList()
3404{ 3418{
3405 QStringList results; 3419 QStringList results;
3406 3420
3407 vector<PwMCategoryItem>::iterator catcounter = dti.dta.begin(), 3421 vector<PwMCategoryItem>::iterator catcounter = dti.dta.begin(),
3408 catend = dti.dta.end(); 3422 catend = dti.dta.end();
3409 3423
3410 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI; 3424 vector<PwMDataItem>::iterator entrBegin, entrEnd, entrI;
3411 3425
3412 while (catcounter != catend) { 3426 while (catcounter != catend) {
3413 entrBegin = catcounter->d.begin(); 3427 entrBegin = catcounter->d.begin();
3414 entrEnd = catcounter->d.end(); 3428 entrEnd = catcounter->d.end();
3415 entrI = entrBegin; 3429 entrI = entrBegin;
3416 while (entrI != entrEnd) { 3430 while (entrI != entrEnd) {
3417 results.append( (*entrI).meta.uniqueid.c_str() ); 3431 results.append( (*entrI).meta.uniqueid.c_str() );
3418 ++entrI; 3432 ++entrI;
3419 } 3433 }
3420 ++catcounter; 3434 ++catcounter;
3421 } 3435 }
3422 3436
3423 return results; 3437 return results;
3424} 3438}
3425 3439
3426 3440
3427 3441
3428 3442
3429 3443
3430#ifndef PWM_EMBEDDED 3444#ifndef PWM_EMBEDDED
3431#include "pwmdoc.moc" 3445#include "pwmdoc.moc"
3432#endif 3446#endif
diff --git a/pwmanager/pwmanager/pwmdoc.h b/pwmanager/pwmanager/pwmdoc.h
index 6a1dd30..535fb92 100644
--- a/pwmanager/pwmanager/pwmdoc.h
+++ b/pwmanager/pwmanager/pwmdoc.h
@@ -1,805 +1,786 @@
1/*************************************************************************** 1/***************************************************************************
2 * * 2 * *
3 * copyright (C) 2003, 2004 by Michael Buesch * 3 * copyright (C) 2003, 2004 by Michael Buesch *
4 * email: mbuesch@freenet.de * 4 * email: mbuesch@freenet.de *
5 * * 5 * *
6 * This program is free software; you can redistribute it and/or modify * 6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License version 2 * 7 * it under the terms of the GNU General Public License version 2 *
8 * as published by the Free Software Foundation. * 8 * as published by the Free Software Foundation. *
9 * * 9 * *
10 ***************************************************************************/ 10 ***************************************************************************/
11 11
12/*************************************************************************** 12/***************************************************************************
13 * copyright (C) 2004 by Ulf Schenk 13 * copyright (C) 2004 by Ulf Schenk
14 * This file is originaly based on version 2.0 of pwmanager 14 * This file is originaly based on version 2.0 of pwmanager
15 * and was modified to run on embedded devices that run microkde 15 * and was modified to run on embedded devices that run microkde
16 * 16 *
17 * $Id$ 17 * $Id$
18 **************************************************************************/ 18 **************************************************************************/
19 19
20#ifndef __PWMDOC_H 20#ifndef __PWMDOC_H
21#define __PWMDOC_H 21#define __PWMDOC_H
22 22
23 #define PWM_FILE_VER (static_cast<char>(0x05)) 23 #define PWM_FILE_VER (static_cast<char>(0x05))
24 24
25 #define PWM_HASH_SHA1 (static_cast<char>(0x01)) 25 #define PWM_HASH_SHA1 (static_cast<char>(0x01))
26 #define PWM_HASH_SHA256 (static_cast<char>(0x02)) 26 #define PWM_HASH_SHA256 (static_cast<char>(0x02))
27 #define PWM_HASH_SHA384 (static_cast<char>(0x03)) 27 #define PWM_HASH_SHA384 (static_cast<char>(0x03))
28 #define PWM_HASH_SHA512 (static_cast<char>(0x04)) 28 #define PWM_HASH_SHA512 (static_cast<char>(0x04))
29 #define PWM_HASH_MD5 (static_cast<char>(0x05)) 29 #define PWM_HASH_MD5 (static_cast<char>(0x05))
30 #define PWM_HASH_RMD160 (static_cast<char>(0x06)) 30 #define PWM_HASH_RMD160 (static_cast<char>(0x06))
31 #define PWM_HASH_TIGER (static_cast<char>(0x07)) 31 #define PWM_HASH_TIGER (static_cast<char>(0x07))
32 32
33 #define PWM_CRYPT_BLOWFISH(static_cast<char>(0x01)) 33 #define PWM_CRYPT_BLOWFISH(static_cast<char>(0x01))
34 #define PWM_CRYPT_AES128(static_cast<char>(0x02)) 34 #define PWM_CRYPT_AES128(static_cast<char>(0x02))
35 #define PWM_CRYPT_AES192(static_cast<char>(0x03)) 35 #define PWM_CRYPT_AES192(static_cast<char>(0x03))
36 #define PWM_CRYPT_AES256(static_cast<char>(0x04)) 36 #define PWM_CRYPT_AES256(static_cast<char>(0x04))
37 #define PWM_CRYPT_3DES (static_cast<char>(0x05)) 37 #define PWM_CRYPT_3DES (static_cast<char>(0x05))
38 #define PWM_CRYPT_TWOFISH(static_cast<char>(0x06)) 38 #define PWM_CRYPT_TWOFISH(static_cast<char>(0x06))
39 #define PWM_CRYPT_TWOFISH128(static_cast<char>(0x07)) 39 #define PWM_CRYPT_TWOFISH128(static_cast<char>(0x07))
40 40
41 #define PWM_COMPRESS_NONE(static_cast<char>(0x00)) 41 #define PWM_COMPRESS_NONE(static_cast<char>(0x00))
42 #define PWM_COMPRESS_GZIP(static_cast<char>(0x01)) 42 #define PWM_COMPRESS_GZIP(static_cast<char>(0x01))
43 #define PWM_COMPRESS_BZIP2(static_cast<char>(0x02)) 43 #define PWM_COMPRESS_BZIP2(static_cast<char>(0x02))
44 44
45 #define DEFAULT_MAX_ENTRIES(~(static_cast<unsigned int>(0))) 45 #define DEFAULT_MAX_ENTRIES(~(static_cast<unsigned int>(0)))
46 #define FILE_ID_HEADER "PWM_PASSWORD_FILE" 46 #define FILE_ID_HEADER "PWM_PASSWORD_FILE"
47 47
48 48
49#include "pwmexception.h" 49#include "pwmexception.h"
50#include "pwmdocui.h" 50#include "pwmdocui.h"
51 51
52#include <qobject.h> 52#include <qobject.h>
53#include <qtimer.h> 53#include <qtimer.h>
54#include <qdatetime.h> 54#include <qdatetime.h>
55 55
56#include <kprocess.h> 56#include <kprocess.h>
57 57
58#ifndef PWM_EMBEDDED 58#ifndef PWM_EMBEDDED
59#include "configuration.h" 59#include "configuration.h"
60#else 60#else
61#include <kapplication.h> 61#include <kapplication.h>
62#include <ksyncmanager.h> 62#include <ksyncmanager.h>
63#endif 63#endif
64 64
65#include <string> 65#include <string>
66#include <vector> 66#include <vector>
67#include <utility> 67#include <utility>
68 68
69using std::vector; 69using std::vector;
70using std::string; 70using std::string;
71using std::pair; 71using std::pair;
72 72
73/* used in findEntry() function */ 73/* used in findEntry() function */
74 #define SEARCH_IN_DESC (1) 74 #define SEARCH_IN_DESC (1)
75 #define SEARCH_IN_NAME (1 << 1) 75 #define SEARCH_IN_NAME (1 << 1)
76 #define SEARCH_IN_PW (1 << 2) 76 #define SEARCH_IN_PW (1 << 2)
77 #define SEARCH_IN_COMMENT(1 << 3) 77 #define SEARCH_IN_COMMENT(1 << 3)
78 #define SEARCH_IN_URL (1 << 4) 78 #define SEARCH_IN_URL (1 << 4)
79 #define SEARCH_IN_LAUNCHER(1 << 5) 79 #define SEARCH_IN_LAUNCHER(1 << 5)
80 #define SEARCH_IN_ALL (SEARCH_IN_DESC | SEARCH_IN_NAME| \ 80 #define SEARCH_IN_ALL (SEARCH_IN_DESC | SEARCH_IN_NAME| \
81 SEARCH_IN_PW | SEARCH_IN_COMMENT| \ 81 SEARCH_IN_PW | SEARCH_IN_COMMENT| \
82 SEARCH_IN_URL| SEARCH_IN_LAUNCHER) 82 SEARCH_IN_URL| SEARCH_IN_LAUNCHER)
83 83
84/** document deeplocked. Data is out for lunch to disk */ 84/** document deeplocked. Data is out for lunch to disk */
85 #define DOC_STAT_DEEPLOCKED (1) 85 #define DOC_STAT_DEEPLOCKED (1)
86/** encrypted document on disk is dirty. data has to go to disk. */ 86/** encrypted document on disk is dirty. data has to go to disk. */
87 #define DOC_STAT_DISK_DIRTY (1 << 1) 87 #define DOC_STAT_DISK_DIRTY (1 << 1)
88/** we are using a chipcard to encrypt the data */ 88/** we are using a chipcard to encrypt the data */
89 #define DOC_STAT_USE_CHIPCARD (1 << 2) 89 #define DOC_STAT_USE_CHIPCARD (1 << 2)
90/** use "currentPw" to unlock. (This flag is set/unset by a timer) */ 90/** use "currentPw" to unlock. (This flag is set/unset by a timer) */
91 #define DOC_STAT_UNLOCK_WITHOUT_PW(1 << 3) 91 #define DOC_STAT_UNLOCK_WITHOUT_PW(1 << 3)
92 92
93class PwMDoc; 93class PwMDoc;
94class PwMView; 94class PwMView;
95class QFile; 95class QFile;
96 96
97/* meta data for a PwMDataItem */ 97/* meta data for a PwMDataItem */
98struct PwMMetaData 98struct PwMMetaData
99{ 99{
100 PwMMetaData() 100 PwMMetaData()
101 : updateInt (0) 101 : updateInt (0)
102 { } 102 { }
103 /** creation date of the PwMDataItem to which 103 /** creation date of the PwMDataItem to which
104 * this meta data belongs. 104 * this meta data belongs.
105 */ 105 */
106 QDateTimecreate; 106 QDateTimecreate;
107 /** becomes valid on this date */ 107 /** becomes valid on this date */
108 QDateTimevalid; 108 QDateTimevalid;
109 /** expire date */ 109 /** expire date */
110 QDateTimeexpire; 110 QDateTimeexpire;
111 /** update date (last updated at this date) */ 111 /** update date (last updated at this date) */
112 QDateTimeupdate; 112 QDateTimeupdate;
113 /** update interval (in minutes). Time since the 113 /** update interval (in minutes). Time since the
114 * last update to remind the user to update the item. 114 * last update to remind the user to update the item.
115 * 0 disables. 115 * 0 disables.
116 */ 116 */
117 unsigned long updateInt; 117 unsigned long updateInt;
118 118
119 //US ENH: enhancements of the filestructure 119 //US ENH: enhancements of the filestructure
120 /* each entry gets a unique id assigned */ 120 /* each entry gets a unique id assigned */
121 string uniqueid; 121 string uniqueid;
122 122
123 123
124 void clear() 124 void clear()
125 { 125 {
126 create = QDateTime(); 126 create = QDateTime();
127 expire = QDateTime(); 127 expire = QDateTime();
128 update = QDateTime(); 128 update = QDateTime();
129 updateInt = 0; 129 updateInt = 0;
130 uniqueid = KApplication::randomString(8); 130 uniqueid = KApplication::randomString(8);
131 } 131 }
132 132
133 inline bool isValid() const 133 inline bool isValid() const
134 { 134 {
135 if (valid.isNull()) 135 if (valid.isNull())
136 return true; 136 return true;
137 return (valid < QDateTime::currentDateTime()); 137 return (valid < QDateTime::currentDateTime());
138 } 138 }
139 inline bool isExpired() const 139 inline bool isExpired() const
140 { 140 {
141 if (expire.isNull()) 141 if (expire.isNull())
142 return false; 142 return false;
143 return (expire < QDateTime::currentDateTime()); 143 return (expire < QDateTime::currentDateTime());
144 } 144 }
145 inline bool isUpdateIntOver() const 145 inline bool isUpdateIntOver() const
146 { 146 {
147 if (updateInt == 0 || 147 if (updateInt == 0 ||
148 update.isNull()) 148 update.isNull())
149 return false; 149 return false;
150 QDateTime d(update); 150 QDateTime d(update);
151 return (d.addSecs(updateInt * 60) < QDateTime::currentDateTime()); 151 return (d.addSecs(updateInt * 60) < QDateTime::currentDateTime());
152 } 152 }
153}; 153};
154 154
155struct PwMDataItem 155struct PwMDataItem
156{ 156{
157 PwMDataItem() 157 PwMDataItem()
158 : lockStat (true) 158 : lockStat (true)
159 , listViewPos (-1) 159 , listViewPos (-1)
160 , binary (false) 160 , binary (false)
161 , rev (0) 161 , rev (0)
162 { } 162 { }
163 163
164 /** password description */ 164 /** password description */
165 stringdesc; 165 stringdesc;
166 /** user-name */ 166 /** user-name */
167 stringname; 167 stringname;
168 /** the password itself */ 168 /** the password itself */
169 stringpw; 169 stringpw;
170 /** some comment */ 170 /** some comment */
171 stringcomment; 171 stringcomment;
172 /** an URL string */ 172 /** an URL string */
173 stringurl; 173 stringurl;
174 /** launcher. Can be executed as a system() command */ 174 /** launcher. Can be executed as a system() command */
175 stringlauncher; 175 stringlauncher;
176 /** locking status. If locked (true), pw is not emitted through getEntry() */ 176 /** locking status. If locked (true), pw is not emitted through getEntry() */
177 boollockStat; 177 boollockStat;
178 /** position of this item in main "list-view" 178 /** position of this item in main "list-view"
179 * If -1, the position is not yet specified and should be appended to the list 179 * If -1, the position is not yet specified and should be appended to the list
180 */ 180 */
181 intlistViewPos; 181 intlistViewPos;
182 /** does this entry contain binary data? */ 182 /** does this entry contain binary data? */
183 bool binary; 183 bool binary;
184 /** meta data for this data item. */ 184 /** meta data for this data item. */
185 PwMMetaData meta; 185 PwMMetaData meta;
186 /** data revision counter. This counter can be used 186 /** data revision counter. This counter can be used
187 * to easily, efficiently determine if this data item 187 * to easily, efficiently determine if this data item
188 * has changed since some time. 188 * has changed since some time.
189 * This counter is incremented on every update. 189 * This counter is incremented on every update.
190 */ 190 */
191 unsigned int rev; 191 unsigned int rev;
192 192
193 void clear(bool clearMeta = true) 193 void clear(bool clearMeta = true)
194 { 194 {
195 /* NOTE: Don't use .clear() here to be 195 /* NOTE: Don't use .clear() here to be
196 * backward compatible with gcc-2 (Debian Woody) 196 * backward compatible with gcc-2 (Debian Woody)
197 */ 197 */
198 desc = ""; 198 desc = "";
199 name = ""; 199 name = "";
200 pw = ""; 200 pw = "";
201 comment = ""; 201 comment = "";
202 url = ""; 202 url = "";
203 launcher = ""; 203 launcher = "";
204 lockStat = true; 204 lockStat = true;
205 listViewPos = -1; 205 listViewPos = -1;
206 binary = false; 206 binary = false;
207 if (clearMeta) 207 if (clearMeta)
208 meta.clear(); 208 meta.clear();
209 } 209 }
210 //US ENH: we need this operator to compare two items if we have no unique ids 210 //US ENH: we need this operator to compare two items if we have no unique ids
211 //available. Generaly this happens before the first sync 211 //available. Generaly this happens before the first sync
212
212 bool PwMDataItem::operator==( const PwMDataItem &a ) const 213 bool PwMDataItem::operator==( const PwMDataItem &a ) const
213 { 214 {
214 qDebug("oper==%s", a.desc.c_str()); 215 //qDebug("oper==%s", a.desc.c_str());
215 if ( desc != a.desc ) return false; 216 if ( desc != a.desc ) return false;
216 if ( name != a.name ) return false; 217 if ( name != a.name ) return false;
217 if ( pw != a.pw ) return false; 218 if ( pw != a.pw ) return false;
218 if ( comment != a.comment ) return false; 219 if ( comment != a.comment ) return false;
219 if ( url != a.url ) return false; 220 if ( url != a.url ) return false;
220 if ( launcher != a.launcher ) return false; 221 if ( launcher != a.launcher ) return false;
221 //all other field will not be checked. 222 //all other field will not be checked.
222 return true; 223 return true;
223 } 224 }
224
225 //US ENH:this operator is used to copy an elements data during syncronization
226 //Attention: listViewPos will not be copied. So the position will stay the same.
227 PwMDataItem& operator = (const PwMDataItem& x)
228 {
229 // qDebug("oper=%s", x.desc.c_str());
230 desc = x.desc;
231 name = x.name;
232 pw = x.pw;
233 comment = x.comment;
234 url = x.url;
235 launcher = x.launcher;
236 lockStat = x.lockStat;
237 //Do not copy listViewPos!!! listViewPos = x.listViewPos;
238 binary = x.binary;
239 meta = x.meta;
240 rev = x.rev;
241 return *this;
242 }
243
244}; 225};
245 226
246struct PwMCategoryItem 227struct PwMCategoryItem
247{ 228{
248 /** all PwMDataItems (all passwords) within this category */ 229 /** all PwMDataItems (all passwords) within this category */
249 vector<PwMDataItem>d; 230 vector<PwMDataItem>d;
250 /** category name/description */ 231 /** category name/description */
251 string name; 232 string name;
252 233
253 void clear() 234 void clear()
254 { 235 {
255 d.clear(); 236 d.clear();
256 name = ""; 237 name = "";
257 } 238 }
258}; 239};
259 240
260struct PwMSyncItem 241struct PwMSyncItem
261{ 242{
262 string syncName; 243 string syncName;
263 QDateTime lastSyncDate; 244 QDateTime lastSyncDate;
264 245
265 void clear() 246 void clear()
266 { 247 {
267 lastSyncDate = QDateTime(); 248 lastSyncDate = QDateTime();
268 syncName = ""; 249 syncName = "";
269 } 250 }
270}; 251};
271 252
272struct PwMItem 253struct PwMItem
273{ 254{
274 vector<PwMCategoryItem> dta; 255 vector<PwMCategoryItem> dta;
275 vector<PwMSyncItem> syncDta; 256 vector<PwMSyncItem> syncDta;
276 257
277 void clear() 258 void clear()
278 { 259 {
279 dta.clear(); 260 dta.clear();
280 syncDta.clear(); 261 syncDta.clear();
281 } 262 }
282}; 263};
283 264
284 265
285/** "Function Object" for sort()ing PwMDataItem::listViewPos */ 266/** "Function Object" for sort()ing PwMDataItem::listViewPos */
286class dta_lvp_greater 267class dta_lvp_greater
287{ 268{
288public: 269public:
289 bool operator() (const pair<unsigned int, unsigned int> &d1, 270 bool operator() (const pair<unsigned int, unsigned int> &d1,
290 const pair<unsigned int, unsigned int> &d2) 271 const pair<unsigned int, unsigned int> &d2)
291 { 272 {
292 return d1.second > d2.second; 273 return d1.second > d2.second;
293 } 274 }
294}; 275};
295 276
296/** list of PwMDoc documents and it's IDs */ 277/** list of PwMDoc documents and it's IDs */
297class PwMDocList 278class PwMDocList
298{ 279{
299public: 280public:
300 struct listItem 281 struct listItem
301 { 282 {
302 /** document filename (known as ID, here) */ 283 /** document filename (known as ID, here) */
303 string docId; 284 string docId;
304 /** pointer to the document class */ 285 /** pointer to the document class */
305 PwMDoc *doc; 286 PwMDoc *doc;
306 }; 287 };
307 288
308 PwMDocList() {} 289 PwMDocList() {}
309 290
310 /** add a new item to the list */ 291 /** add a new item to the list */
311 void add(PwMDoc *doc, const string &id); 292 void add(PwMDoc *doc, const string &id);
312 /** changes the contents of an existing item */ 293 /** changes the contents of an existing item */
313 void edit(PwMDoc *doc, const string &newId); 294 void edit(PwMDoc *doc, const string &newId);
314 /** remove the given item */ 295 /** remove the given item */
315 void del(PwMDoc *doc); 296 void del(PwMDoc *doc);
316 /** get the item at index */ 297 /** get the item at index */
317 listItem getAt(int index) 298 listItem getAt(int index)
318 { return docList[index]; } 299 { return docList[index]; }
319 /** find an entry with this id */ 300 /** find an entry with this id */
320 bool find(const string &id, listItem *ret = 0); 301 bool find(const string &id, listItem *ret = 0);
321 /** returns a copy of the list */ 302 /** returns a copy of the list */
322 const vector<listItem>* getList() const 303 const vector<listItem>* getList() const
323 { return &docList; } 304 { return &docList; }
324 305
325 306
326 /** returns a new unique number to extend the name of 307 /** returns a new unique number to extend the name of
327 * an unnamed document. 308 * an unnamed document.
328 */ 309 */
329 static unsigned int getNewUnnamedNumber() 310 static unsigned int getNewUnnamedNumber()
330 { return unnamedDocCnt++; } 311 { return unnamedDocCnt++; }
331 312
332protected: 313protected:
333 /* Hm, I think we shouldn't really use a "list" here, should we? 314 /* Hm, I think we shouldn't really use a "list" here, should we?
334 * So I decided to actually use a vector. 315 * So I decided to actually use a vector.
335 */ 316 */
336 vector<listItem> docList; 317 vector<listItem> docList;
337 /** This value is used to get a new number for yet unnamed 318 /** This value is used to get a new number for yet unnamed
338 * documents. It is incremented on every request. So it's 319 * documents. It is incremented on every request. So it's
339 * theoretically possible to overflow it, but... :) 320 * theoretically possible to overflow it, but... :)
340 */ 321 */
341 static unsigned int unnamedDocCnt; 322 static unsigned int unnamedDocCnt;
342}; 323};
343 324
344/** implements timers for the document */ 325/** implements timers for the document */
345class DocTimer : public QObject 326class DocTimer : public QObject
346{ 327{
347 Q_OBJECT 328 Q_OBJECT
348public: 329public:
349 enum TimerIDs 330 enum TimerIDs
350 { 331 {
351 id_mpwTimer, 332 id_mpwTimer,
352 id_autoLockTimer, 333 id_autoLockTimer,
353 id_metaCheckTimer 334 id_metaCheckTimer
354 }; 335 };
355 336
356public: 337public:
357 DocTimer(PwMDoc *_doc); 338 DocTimer(PwMDoc *_doc);
358 ~DocTimer(); 339 ~DocTimer();
359 340
360 /** start the timer */ 341 /** start the timer */
361 void start(TimerIDs timer); 342 void start(TimerIDs timer);
362 /** stop the timer */ 343 /** stop the timer */
363 void stop(TimerIDs timer); 344 void stop(TimerIDs timer);
364 /** get the lock for a timer. 345 /** get the lock for a timer.
365 * This lock is a recursive lock. When a lock is 346 * This lock is a recursive lock. When a lock is
366 * held, the timer will be stopped and timeout is 347 * held, the timer will be stopped and timeout is
367 * guaranteed to not happen 348 * guaranteed to not happen
368 */ 349 */
369 void getLock(TimerIDs timer); 350 void getLock(TimerIDs timer);
370 /** put a recursive timer lock */ 351 /** put a recursive timer lock */
371 void putLock(TimerIDs timer); 352 void putLock(TimerIDs timer);
372 353
373protected slots: 354protected slots:
374 /** timeout slot for the mpw timer */ 355 /** timeout slot for the mpw timer */
375 void mpwTimeout(); 356 void mpwTimeout();
376 /** timeout slot for the autoLock timer */ 357 /** timeout slot for the autoLock timer */
377 void autoLockTimeout(); 358 void autoLockTimeout();
378 /** timeout slot for the metaCheck timer */ 359 /** timeout slot for the metaCheck timer */
379 void metaCheckTimeout(); 360 void metaCheckTimeout();
380 361
381protected: 362protected:
382 /** pointer to the document associated with this timer. */ 363 /** pointer to the document associated with this timer. */
383 PwMDoc *doc; 364 PwMDoc *doc;
384 /** timer object for mpw timer */ 365 /** timer object for mpw timer */
385 QTimer *mpwTimer; 366 QTimer *mpwTimer;
386 /** timer object for the autoLock timer */ 367 /** timer object for the autoLock timer */
387 QTimer *autoLockTimer; 368 QTimer *autoLockTimer;
388 /** timer object for the metaCheck timer */ 369 /** timer object for the metaCheck timer */
389 QTimer *metaCheckTimer; 370 QTimer *metaCheckTimer;
390 /** lock counter for the mpw timer */ 371 /** lock counter for the mpw timer */
391 unsigned int mpwLock; 372 unsigned int mpwLock;
392 /** lock counter for the autoLock timer */ 373 /** lock counter for the autoLock timer */
393 unsigned int autoLockLock; 374 unsigned int autoLockLock;
394 /** lock counter for the metaCheck timer */ 375 /** lock counter for the metaCheck timer */
395 unsigned int metaCheckLock; 376 unsigned int metaCheckLock;
396}; 377};
397 378
398/** Document class for PwM */ 379/** Document class for PwM */
399//US ENH: derived from KSyncInterfaces, to get called by PwM when a sync is required. 380//US ENH: derived from KSyncInterfaces, to get called by PwM when a sync is required.
400// But PwMDoc is handling the sync by itself. 381// But PwMDoc is handling the sync by itself.
401class PwMDoc : public PwMDocUi, public KSyncInterface 382class PwMDoc : public PwMDocUi, public KSyncInterface
402 383
403{ 384{
404 Q_OBJECT 385 Q_OBJECT
405 friend class DocTimer; 386 friend class DocTimer;
406 387
407public: 388public:
408 /** construtor */ 389 /** construtor */
409 PwMDoc(QObject* parent = 0, const char *name = 0); 390 PwMDoc(QObject* parent = 0, const char *name = 0);
410 /** destructor */ 391 /** destructor */
411 ~PwMDoc(); 392 ~PwMDoc();
412 393
413 /** returns a pointer to a list of all open documents */ 394 /** returns a pointer to a list of all open documents */
414 static PwMDocList* getOpenDocList() 395 static PwMDocList* getOpenDocList()
415 { return &openDocList; } 396 { return &openDocList; }
416 397
417 /** flag document dirty. dta changed */ 398 /** flag document dirty. dta changed */
418 void flagDirty() 399 void flagDirty()
419 { 400 {
420 setDocStatFlag(DOC_STAT_DISK_DIRTY); 401 setDocStatFlag(DOC_STAT_DISK_DIRTY);
421 emitDataChanged(this); 402 emitDataChanged(this);
422 } 403 }
423 /** modified? */ 404 /** modified? */
424 bool isDirty() 405 bool isDirty()
425 { return getDocStatFlag(DOC_STAT_DISK_DIRTY); } 406 { return getDocStatFlag(DOC_STAT_DISK_DIRTY); }
426 /** save document to disk */ 407 /** save document to disk */
427 PwMerror saveDoc(char compress, const QString *file = 0); 408 PwMerror saveDoc(char compress, const QString *file = 0);
428 /** read document from file. 409 /** read document from file.
429 * "openLocked is must be set to either of these values: 410 * "openLocked is must be set to either of these values:
430 * 0 == open with all entries unlocked 411 * 0 == open with all entries unlocked
431 * 1 == open with all entries locked 412 * 1 == open with all entries locked
432 * 2 == open deep-locked 413 * 2 == open deep-locked
433 */ 414 */
434 PwMerror openDoc(const QString *file, int openLocked); 415 PwMerror openDoc(const QString *file, int openLocked);
435 /** export document to ascii-textfile */ 416 /** export document to ascii-textfile */
436 PwMerror exportToText(const QString *file); 417 PwMerror exportToText(const QString *file);
437 /** export document to gpasman / kpasman file */ 418 /** export document to gpasman / kpasman file */
438 PwMerror exportToGpasman(const QString *file); 419 PwMerror exportToGpasman(const QString *file);
439 /** import document from ascii-textfile */ 420 /** import document from ascii-textfile */
440 PwMerror importFromText(const QString *file, int format = -1); 421 PwMerror importFromText(const QString *file, int format = -1);
441 /** import document from gpasman / kpasman file */ 422 /** import document from gpasman / kpasman file */
442 PwMerror importFromGpasman(const QString *file); 423 PwMerror importFromGpasman(const QString *file);
443 /** add new entry */ 424 /** add new entry */
444 PwMerror addEntry(const QString &category, PwMDataItem *d, 425 PwMerror addEntry(const QString &category, PwMDataItem *d,
445 bool dontFlagDirty = false, bool updateMeta = true); 426 bool dontFlagDirty = false, bool updateMeta = true);
446 /** add new category. This function doesn't flag the document dirty! */ 427 /** add new category. This function doesn't flag the document dirty! */
447 PwMerror addCategory(const QString &category, unsigned int *categoryIndex, 428 PwMerror addCategory(const QString &category, unsigned int *categoryIndex,
448 bool checkIfExist = true); 429 bool checkIfExist = true);
449 /** rename an existing category */ 430 /** rename an existing category */
450 bool renameCategory(const QString &category, const QString &newName); 431 bool renameCategory(const QString &category, const QString &newName);
451 /** rename an existing category */ 432 /** rename an existing category */
452 bool renameCategory(unsigned int category, const QString &newName, 433 bool renameCategory(unsigned int category, const QString &newName,
453 bool dontFlagDirty = false); 434 bool dontFlagDirty = false);
454 /** delete an existing category */ 435 /** delete an existing category */
455 bool delCategory(const QString &category); 436 bool delCategory(const QString &category);
456 /** delete an existing category */ 437 /** delete an existing category */
457 bool delCategory(unsigned int category, bool dontFlagDirty = false); 438 bool delCategory(unsigned int category, bool dontFlagDirty = false);
458 /** returns a list of all category-names */ 439 /** returns a list of all category-names */
459 void getCategoryList(vector<string> *list); 440 void getCategoryList(vector<string> *list);
460 /** returns a list of all category-names */ 441 /** returns a list of all category-names */
461 void getCategoryList(QStringList *list); 442 void getCategoryList(QStringList *list);
462 /** returns a list of all entry-descs in the given category */ 443 /** returns a list of all entry-descs in the given category */
463 void getEntryList(const QString &category, QStringList *list); 444 void getEntryList(const QString &category, QStringList *list);
464 /** returns a list of all entry-descs in the given category */ 445 /** returns a list of all entry-descs in the given category */
465 void getEntryList(const QString &category, vector<string> *list); 446 void getEntryList(const QString &category, vector<string> *list);
466 /** returns a list of all entry-descs in the given category */ 447 /** returns a list of all entry-descs in the given category */
467 void getEntryList(unsigned int category, vector<string> *list); 448 void getEntryList(unsigned int category, vector<string> *list);
468 /** returns a list of all entry-descs in the given category */ 449 /** returns a list of all entry-descs in the given category */
469 void getEntryList(unsigned int category, QStringList *list); 450 void getEntryList(unsigned int category, QStringList *list);
470 /** delete entry */ 451 /** delete entry */
471 bool delEntry(const QString &category, unsigned int index, bool dontFlagDirty = false); 452 bool delEntry(const QString &category, unsigned int index, bool dontFlagDirty = false);
472 /** delete entry */ 453 /** delete entry */
473 bool delEntry(unsigned int category, unsigned int index, bool dontFlagDirty = false); 454 bool delEntry(unsigned int category, unsigned int index, bool dontFlagDirty = false);
474 /** edit entry */ 455 /** edit entry */
475 bool editEntry(const QString &oldCategory, const QString &newCategory, 456 bool editEntry(const QString &oldCategory, const QString &newCategory,
476 unsigned int index, PwMDataItem *d, bool updateMeta = true); 457 unsigned int index, PwMDataItem *d, bool updateMeta = true);
477 /** edit entry */ 458 /** edit entry */
478 bool editEntry(unsigned int oldCategory, const QString &newCategory, 459 bool editEntry(unsigned int oldCategory, const QString &newCategory,
479 unsigned int index, PwMDataItem *d, bool updateMeta = true); 460 unsigned int index, PwMDataItem *d, bool updateMeta = true);
480 /** finds the category with the "name" and return it's index */ 461 /** finds the category with the "name" and return it's index */
481 bool findCategory(const QString &name, unsigned int *index); 462 bool findCategory(const QString &name, unsigned int *index);
482 /** search for an entry "find" and check while searching only for 463 /** search for an entry "find" and check while searching only for
483 * the data-fields specified by "searchIn". To set the "searchIn" 464 * the data-fields specified by "searchIn". To set the "searchIn"
484 * value, we may use one or more of the SEARCH_IN_* defines at 465 * value, we may use one or more of the SEARCH_IN_* defines at
485 * the top of this header-file. It returns the positions of all 466 * the top of this header-file. It returns the positions of all
486 * matched entries in "foundPositions". If "breakAfterFound" is true, 467 * matched entries in "foundPositions". If "breakAfterFound" is true,
487 * the function terminates after the first occurence of the entry 468 * the function terminates after the first occurence of the entry
488 * and doesn't go on searching. So foundPositions->size() is never 469 * and doesn't go on searching. So foundPositions->size() is never
489 * > 1 if breakAfterFound is true. 470 * > 1 if breakAfterFound is true.
490 */ 471 */
491 void findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn, 472 void findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn,
492 vector<unsigned int> *foundPositions, bool breakAfterFound = false, 473 vector<unsigned int> *foundPositions, bool breakAfterFound = false,
493 bool caseSensitive = true, bool exactWordMatch = true, 474 bool caseSensitive = true, bool exactWordMatch = true,
494 bool sortByLvp = false); 475 bool sortByLvp = false);
495 /** see the above funtion. This function allows to set the category by name. */ 476 /** see the above funtion. This function allows to set the category by name. */
496 void findEntry(const QString &category, PwMDataItem find, unsigned int searchIn, 477 void findEntry(const QString &category, PwMDataItem find, unsigned int searchIn,
497 vector<unsigned int> *foundPositions, bool breakAfterFound = false, 478 vector<unsigned int> *foundPositions, bool breakAfterFound = false,
498 bool caseSensitive = true, bool exactWordMatch = true, 479 bool caseSensitive = true, bool exactWordMatch = true,
499 bool sortByLvp = false); 480 bool sortByLvp = false);
500 /** returns number of entries */ 481 /** returns number of entries */
501 unsigned int numEntries(const QString &category); 482 unsigned int numEntries(const QString &category);
502 unsigned int numEntries(unsigned int category) 483 unsigned int numEntries(unsigned int category)
503 { return dti.dta[category].d.size(); } 484 { return dti.dta[category].d.size(); }
504 /** returns number of categories */ 485 /** returns number of categories */
505 unsigned int numCategories() 486 unsigned int numCategories()
506 { return dti.dta.size(); } 487 { return dti.dta.size(); }
507 /** returns the name of the category at "index" */ 488 /** returns the name of the category at "index" */
508 const string* getCategory(unsigned int index) 489 const string* getCategory(unsigned int index)
509 { return (&(dti.dta[index].name)); } 490 { return (&(dti.dta[index].name)); }
510 491
511 /** returns the data of item at "index". 492 /** returns the data of item at "index".
512 * It unlocks the entry if it's locked and unlockIfLocked is true. 493 * It unlocks the entry if it's locked and unlockIfLocked is true.
513 * If the entry is locked, but unlockIfLocked is false, it'll not return 494 * If the entry is locked, but unlockIfLocked is false, it'll not return
514 * the pw. 495 * the pw.
515 */ 496 */
516 bool getEntry(const QString &category, unsigned int index, 497 bool getEntry(const QString &category, unsigned int index,
517 PwMDataItem *d, bool unlockIfLocked = false); 498 PwMDataItem *d, bool unlockIfLocked = false);
518 bool getEntry(unsigned int category, unsigned int index, 499 bool getEntry(unsigned int category, unsigned int index,
519 PwMDataItem *d, bool unlockIfLocked = false); 500 PwMDataItem *d, bool unlockIfLocked = false);
520 /** returns the comment-string by looking at the category 501 /** returns the comment-string by looking at the category
521 * and the listViewPos 502 * and the listViewPos
522 */ 503 */
523 PwMerror getCommentByLvp(const QString &category, int listViewPos, 504 PwMerror getCommentByLvp(const QString &category, int listViewPos,
524 string *foundComment); 505 string *foundComment);
525 /** checks if a password is already available. (currentPw) */ 506 /** checks if a password is already available. (currentPw) */
526 bool isPwAvailable() 507 bool isPwAvailable()
527 { return (currentPw != ""); } 508 { return (currentPw != ""); }
528 /** un/lock entry at "index". If needed, ask for password. */ 509 /** un/lock entry at "index". If needed, ask for password. */
529 bool lockAt(const QString &category, unsigned int index, 510 bool lockAt(const QString &category, unsigned int index,
530 bool lock = true); 511 bool lock = true);
531 bool lockAt(unsigned int category, unsigned int index, 512 bool lockAt(unsigned int category, unsigned int index,
532 bool lock = true); 513 bool lock = true);
533 /** returns the lock-status at "index" */ 514 /** returns the lock-status at "index" */
534 bool isLocked(const QString &category, unsigned int index); 515 bool isLocked(const QString &category, unsigned int index);
535 bool isLocked(unsigned int category, unsigned int index) 516 bool isLocked(unsigned int category, unsigned int index)
536 { return dti.dta[category].d[index].lockStat; } 517 { return dti.dta[category].d[index].lockStat; }
537 /** returns the deeplock status */ 518 /** returns the deeplock status */
538 bool isDeepLocked() 519 bool isDeepLocked()
539 { return getDocStatFlag(DOC_STAT_DEEPLOCKED); } 520 { return getDocStatFlag(DOC_STAT_DEEPLOCKED); }
540 /** (un)lock all entries */ 521 /** (un)lock all entries */
541 bool lockAll(bool lock); 522 bool lockAll(bool lock);
542 /** unlocks all entries tempoarly. 523 /** unlocks all entries tempoarly.
543 * 1st NOTE: Be very careful with this function! :) 524 * 1st NOTE: Be very careful with this function! :)
544 * 2nd NOTE: After you have called unlockAll_Tempoary(); , 525 * 2nd NOTE: After you have called unlockAll_Tempoary(); ,
545 * please DON'T forget to call unlockAll_Tempoary(true); 526 * please DON'T forget to call unlockAll_Tempoary(true);
546 * _before_ the user (or someone else) is able to change 527 * _before_ the user (or someone else) is able to change
547 * the document! 528 * the document!
548 * 3rd NOTE: Please DON'T change "dta" while the data is tempoary 529 * 3rd NOTE: Please DON'T change "dta" while the data is tempoary
549 * unlocked! This will cause corruption. 530 * unlocked! This will cause corruption.
550 */ 531 */
551 bool unlockAll_tempoary(bool revert = false); 532 bool unlockAll_tempoary(bool revert = false);
552 /** deep-(un)locks the document. 533 /** deep-(un)locks the document.
553 * deep-locking writes all data to the file, deletes all data 534 * deep-locking writes all data to the file, deletes all data
554 * in memory, but doesn't close the document. 535 * in memory, but doesn't close the document.
555 * deep-locking is only available, if the user previously saved 536 * deep-locking is only available, if the user previously saved
556 * the doc to a file (with a password). 537 * the doc to a file (with a password).
557 * If "saveToFile" is false, it does NOT write the data to the file! 538 * If "saveToFile" is false, it does NOT write the data to the file!
558 */ 539 */
559 PwMerror deepLock(bool lock = true, bool saveToFile = true); 540 PwMerror deepLock(bool lock = true, bool saveToFile = true);
560 /** is unlockable without pw? */ 541 /** is unlockable without pw? */
561 bool unlockWoPw() 542 bool unlockWoPw()
562 { return getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); } 543 { return getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); }
563 /** get the "currentPassword" */ 544 /** get the "currentPassword" */
564 const QString& getCurrentPw() 545 const QString& getCurrentPw()
565 { return currentPw; } 546 { return currentPw; }
566 /** open a window and request the user to change the mpw */ 547 /** open a window and request the user to change the mpw */
567 void changeCurrentPw(); 548 void changeCurrentPw();
568 /** set the "listViewPos" variable of "dta" */ 549 /** set the "listViewPos" variable of "dta" */
569 void setListViewPos(const QString &category, unsigned int index, 550 void setListViewPos(const QString &category, unsigned int index,
570 int pos); 551 int pos);
571 /** set the "listViewPos" variable of "dta" */ 552 /** set the "listViewPos" variable of "dta" */
572 void setListViewPos(unsigned int category, unsigned int index, 553 void setListViewPos(unsigned int category, unsigned int index,
573 int pos); 554 int pos);
574 /** get the "listViewPos" variable of "dta" */ 555 /** get the "listViewPos" variable of "dta" */
575 int getListViewPos(const QString &category, unsigned int index); 556 int getListViewPos(const QString &category, unsigned int index);
576 /** set the maximum number of entries allowed */ 557 /** set the maximum number of entries allowed */
577 void setMaxNumEntries(unsigned int num = DEFAULT_MAX_ENTRIES) 558 void setMaxNumEntries(unsigned int num = DEFAULT_MAX_ENTRIES)
578 { maxEntries = num; } 559 { maxEntries = num; }
579 /** get the maximum number of entries allowed */ 560 /** get the maximum number of entries allowed */
580 unsigned int getMaxNumEntries() 561 unsigned int getMaxNumEntries()
581 { return maxEntries; } 562 { return maxEntries; }
582 /** ensure all listViewPos of all dta items are set. (are ! -1). 563 /** ensure all listViewPos of all dta items are set. (are ! -1).
583 * If there are some undefined entries, add them to the end of 564 * If there are some undefined entries, add them to the end of
584 * the listViewPos(itions). */ 565 * the listViewPos(itions). */
585 void ensureLvp(); 566 void ensureLvp();
586 /** execute the "launcher" of this entry */ 567 /** execute the "launcher" of this entry */
587 bool execLauncher(const QString &category, unsigned int entryIndex); 568 bool execLauncher(const QString &category, unsigned int entryIndex);
588 /** see above */ 569 /** see above */
589 bool execLauncher(unsigned int category, unsigned int entryIndex); 570 bool execLauncher(unsigned int category, unsigned int entryIndex);
590 /** open a browser with the URL-section of the given entry */ 571 /** open a browser with the URL-section of the given entry */
591 bool goToURL(const QString &category, unsigned int entryIndex); 572 bool goToURL(const QString &category, unsigned int entryIndex);
592 /** see above */ 573 /** see above */
593 bool goToURL(unsigned int category, unsigned int entryIndex); 574 bool goToURL(unsigned int category, unsigned int entryIndex);
594 /** returns true if there is no entry present in the document. 575 /** returns true if there is no entry present in the document.
595 * Note: The "default" Category is present everytime, so 576 * Note: The "default" Category is present everytime, so
596 * it's checked for it's entries. 577 * it's checked for it's entries.
597 */ 578 */
598 bool isDocEmpty() 579 bool isDocEmpty()
599 { 580 {
600 if (numCategories() > 1) 581 if (numCategories() > 1)
601 return false; 582 return false;
602 if (numEntries(0)) 583 if (numEntries(0))
603 return false; 584 return false;
604 return true; 585 return true;
605 } 586 }
606 /** returns the filename of this doc */ 587 /** returns the filename of this doc */
607 const QString& getFilename() 588 const QString& getFilename()
608 { return filename; } 589 { return filename; }
609 /** returns the title of the doc */ 590 /** returns the title of the doc */
610 QString getTitle(); 591 QString getTitle();
611 /** sets the list-view-pointer hold in the doc */ 592 /** sets the list-view-pointer hold in the doc */
612 void setListViewPointer(PwMView *_listView) 593 void setListViewPointer(PwMView *_listView)
613 { listView = _listView; } 594 { listView = _listView; }
614 /** returns the list-view-pointer */ 595 /** returns the list-view-pointer */
615 PwMView * getListViewPointer() 596 PwMView * getListViewPointer()
616 { return listView; } 597 { return listView; }
617 /** try to delete the doc. The user may be asked to save 598 /** try to delete the doc. The user may be asked to save
618 * the data. The user may cancel the whole operation. 599 * the data. The user may cancel the whole operation.
619 * false is returned, then. 600 * false is returned, then.
620 */ 601 */
621 bool tryDelete(); 602 bool tryDelete();
622 /** is the doc deleted? (with tryDelete() ) */ 603 /** is the doc deleted? (with tryDelete() ) */
623 bool isDeleted() 604 bool isDeleted()
624 { return deleted; } 605 { return deleted; }
625 /** returns the document timer object */ 606 /** returns the document timer object */
626 DocTimer * timer() 607 DocTimer * timer()
627 { return _timer; } 608 { return _timer; }
628 /** get a lock on the dataChanged signal. 609 /** get a lock on the dataChanged signal.
629 * If someone is holding a lock, the signal is not emitted. 610 * If someone is holding a lock, the signal is not emitted.
630 */ 611 */
631 void getDataChangedLock() 612 void getDataChangedLock()
632 { ++dataChangedLock; } 613 { ++dataChangedLock; }
633 /** put the dataChanged lock */ 614 /** put the dataChanged lock */
634 void putDataChangedLock() 615 void putDataChangedLock()
635 { --dataChangedLock; } 616 { --dataChangedLock; }
636 /** returns the revision count of the item at cat/index */ 617 /** returns the revision count of the item at cat/index */
637 unsigned int getEntryRevCnt(unsigned int category, unsigned int index) 618 unsigned int getEntryRevCnt(unsigned int category, unsigned int index)
638 { return dti.dta[category].d[index].rev; } 619 { return dti.dta[category].d[index].rev; }
639 /** returns a const pointer to the entries meta */ 620 /** returns a const pointer to the entries meta */
640 const PwMMetaData * getEntryMeta(unsigned int category, unsigned int index) 621 const PwMMetaData * getEntryMeta(unsigned int category, unsigned int index)
641 { return &(dti.dta[category].d[index].meta); } 622 { return &(dti.dta[category].d[index].meta); }
642 /** is the entry at "category" "index" a binary entry? */ 623 /** is the entry at "category" "index" a binary entry? */
643 bool isBinEntry(unsigned int category, unsigned int index) 624 bool isBinEntry(unsigned int category, unsigned int index)
644 { return dti.dta[category].d[index].binary; } 625 { return dti.dta[category].d[index].binary; }
645 626
646public slots: 627public slots:
647 /** wrapper for PwMTray */ 628 /** wrapper for PwMTray */
648 void _deepUnlock(); 629 void _deepUnlock();
649 630
650signals: 631signals:
651 /** the data of the document has changed and must be updated 632 /** the data of the document has changed and must be updated
652 * in all views. 633 * in all views.
653 * NOTE: use emitDataChanged(PwMDoc *document) to emit this signal! 634 * NOTE: use emitDataChanged(PwMDoc *document) to emit this signal!
654 */ 635 */
655 void dataChanged(PwMDoc *document); 636 void dataChanged(PwMDoc *document);
656 /** the document class is going to close. This signal may be 637 /** the document class is going to close. This signal may be
657 * used to nofify all views, that the user closed the document, 638 * used to nofify all views, that the user closed the document,
658 * so the views can go down, too. 639 * so the views can go down, too.
659 */ 640 */
660 void docClosed(PwMDoc *document); 641 void docClosed(PwMDoc *document);
661 /** somebody just opened the document */ 642 /** somebody just opened the document */
662 void docOpened(PwMDoc *document); 643 void docOpened(PwMDoc *document);
663 /** this document object just got created */ 644 /** this document object just got created */
664 void docCreated(PwMDoc *document); 645 void docCreated(PwMDoc *document);
665 646
666public: 647public:
667 /** emit the dataChanged signal after checking for a lock */ 648 /** emit the dataChanged signal after checking for a lock */
668 void emitDataChanged(PwMDoc *document) 649 void emitDataChanged(PwMDoc *document)
669 { 650 {
670 if (!dataChangedLock) 651 if (!dataChangedLock)
671 emit dataChanged(document); 652 emit dataChanged(document);
672 } 653 }
673 654
674protected: 655protected:
675 /** current file for this doc */ 656 /** current file for this doc */
676 QString filename; 657 QString filename;
677//US ENH: we need a place where we keep the syncentries. So I invented 658//US ENH: we need a place where we keep the syncentries. So I invented
678// struct PwMItem, that has a vector of PwMCategoryItem and vector of PwMSyncItem 659// struct PwMItem, that has a vector of PwMCategoryItem and vector of PwMSyncItem
679 /** holds all data */ 660 /** holds all data */
680 PwMItem dti; 661 PwMItem dti;
681 /** maximum number of entries */ 662 /** maximum number of entries */
682 unsigned int maxEntries; 663 unsigned int maxEntries;
683 /** currently used password to encrypt data */ 664 /** currently used password to encrypt data */
684 QString currentPw; 665 QString currentPw;
685 /** current global document status flags */ 666 /** current global document status flags */
686 unsigned int curDocStat; 667 unsigned int curDocStat;
687 /** browser process for goToURL() */ 668 /** browser process for goToURL() */
688 KProcess browserProc; 669 KProcess browserProc;
689 /** pointer to the list-view, using this document. 670 /** pointer to the list-view, using this document.
690 * As there can only be one list-view per doc, we 671 * As there can only be one list-view per doc, we
691 * don't need a list here. 672 * don't need a list here.
692 */ 673 */
693 PwMView *listView; 674 PwMView *listView;
694 /** unnamedNum is used to store the "unnamed counter" 675 /** unnamedNum is used to store the "unnamed counter"
695 * for this document, while it's unnamed. If it's 0, 676 * for this document, while it's unnamed. If it's 0,
696 * we have to get a new unique one. 677 * we have to get a new unique one.
697 */ 678 */
698 unsigned int unnamedNum; 679 unsigned int unnamedNum;
699 /** is this doc going to be deleted (executing in destructor context) */ 680 /** is this doc going to be deleted (executing in destructor context) */
700 bool deleted; 681 bool deleted;
701 /** document timer */ 682 /** document timer */
702 DocTimer *_timer; 683 DocTimer *_timer;
703 /** lock counter for the "dataChanged" signal */ 684 /** lock counter for the "dataChanged" signal */
704 unsigned int dataChangedLock; 685 unsigned int dataChangedLock;
705 686
706 /** list of all open documents */ 687 /** list of all open documents */
707 static PwMDocList openDocList; 688 static PwMDocList openDocList;
708 689
709protected: 690protected:
710 /** serialize "dta" and return it in "d". */ 691 /** serialize "dta" and return it in "d". */
711 bool serializeDta(string *d); 692 bool serializeDta(string *d);
712 /** de-serialize "d" and overwrite "dta" */ 693 /** de-serialize "d" and overwrite "dta" */
713 bool deSerializeDta(const string *d, bool entriesLocked); 694 bool deSerializeDta(const string *d, bool entriesLocked);
714 /** write header to file */ 695 /** write header to file */
715 PwMerror writeFileHeader(char keyHash, char dataHash, char crypt, char compress, 696 PwMerror writeFileHeader(char keyHash, char dataHash, char crypt, char compress,
716 QString *pw, QFile *f); 697 QString *pw, QFile *f);
717 /** write data-hash to file */ 698 /** write data-hash to file */
718 PwMerror writeDataHash(char dataHash, string *d, QFile *f); 699 PwMerror writeDataHash(char dataHash, string *d, QFile *f);
719 /** check header. Read header info and verify key-hash and filever. 700 /** check header. Read header info and verify key-hash and filever.
720 * returns length of header in "headerLength" */ 701 * returns length of header in "headerLength" */
721 PwMerror checkHeader(char *cryptAlgo, QString *pw, char *compress, 702 PwMerror checkHeader(char *cryptAlgo, QString *pw, char *compress,
722 unsigned int *headerLength, char *dataHashType, 703 unsigned int *headerLength, char *dataHashType,
723 string *dataHash, QFile *f); 704 string *dataHash, QFile *f);
724 /** check the data-hash */ 705 /** check the data-hash */
725 PwMerror checkDataHash(char dataHashType, const string *dataHash, const string *dataStream); 706 PwMerror checkDataHash(char dataHashType, const string *dataHash, const string *dataStream);
726 /** encrypt data "d" and write to "filename" */ 707 /** encrypt data "d" and write to "filename" */
727 PwMerror encrypt(string *d, const QString *pw, QFile *f, char algo); 708 PwMerror encrypt(string *d, const QString *pw, QFile *f, char algo);
728 /** read data from file beginning at "pos", decrypt and return it */ 709 /** read data from file beginning at "pos", decrypt and return it */
729 PwMerror decrypt(string *d, unsigned int pos, const QString *pw, char algo, QFile *f); 710 PwMerror decrypt(string *d, unsigned int pos, const QString *pw, char algo, QFile *f);
730 /** compress the data */ 711 /** compress the data */
731 bool compressDta(string *d, char algo); 712 bool compressDta(string *d, char algo);
732 /** uncompress the data */ 713 /** uncompress the data */
733 bool decompressDta(string *d, char algo); 714 bool decompressDta(string *d, char algo);
734 /** internal import function for a text-file generated by PwM. 715 /** internal import function for a text-file generated by PwM.
735 * If this is not a valid PwM-exported file, it returns e_fileFormat */ 716 * If this is not a valid PwM-exported file, it returns e_fileFormat */
736 PwMerror importText_PwM(const QString *file); 717 PwMerror importText_PwM(const QString *file);
737 /** PwM-text-import helper function to extract the name/pw/comment out 718 /** PwM-text-import helper function to extract the name/pw/comment out
738 * of one entry-line */ 719 * of one entry-line */
739 bool textExtractEntry_PwM(const char *in, ssize_t in_size, string *out); 720 bool textExtractEntry_PwM(const char *in, ssize_t in_size, string *out);
740 /** compare two strings */ 721 /** compare two strings */
741 bool compareString(const string &s1, const string &s2, bool caseSensitive, 722 bool compareString(const string &s1, const string &s2, bool caseSensitive,
742 bool exactWordMatch); 723 bool exactWordMatch);
743 /** clears all document-data */ 724 /** clears all document-data */
744 void clearDoc(); 725 void clearDoc();
745 /** delete all empty categories */ 726 /** delete all empty categories */
746 void delAllEmptyCat(bool dontFlagDirty); 727 void delAllEmptyCat(bool dontFlagDirty);
747 /** set a document status flag */ 728 /** set a document status flag */
748 void setDocStatFlag(unsigned int statFlag) 729 void setDocStatFlag(unsigned int statFlag)
749 { curDocStat |= statFlag; } 730 { curDocStat |= statFlag; }
750 /** unset a document status flag */ 731 /** unset a document status flag */
751 void unsetDocStatFlag(unsigned int statFlag) 732 void unsetDocStatFlag(unsigned int statFlag)
752 { curDocStat &= ~statFlag; } 733 { curDocStat &= ~statFlag; }
753 /** get a document status flag */ 734 /** get a document status flag */
754 bool getDocStatFlag(unsigned int statFlag) const 735 bool getDocStatFlag(unsigned int statFlag) const
755 { return (curDocStat & statFlag); } 736 { return (curDocStat & statFlag); }
756 /** set the "currentPassword" */ 737 /** set the "currentPassword" */
757 void setCurrentPw(const QString &pw) 738 void setCurrentPw(const QString &pw)
758 { 739 {
759 currentPw = pw; 740 currentPw = pw;
760 setDocStatFlag(DOC_STAT_DISK_DIRTY); 741 setDocStatFlag(DOC_STAT_DISK_DIRTY);
761 } 742 }
762 /** make a backup-copy of the given file */ 743 /** make a backup-copy of the given file */
763 bool backupFile(const QString &filePath); 744 bool backupFile(const QString &filePath);
764 /** copy a file from src to dst */ 745 /** copy a file from src to dst */
765 bool copyFile(const QString &src, const QString &dst); 746 bool copyFile(const QString &src, const QString &dst);
766 747
767 748
768 public: 749 public:
769#ifdef PWM_EMBEDDED 750#ifdef PWM_EMBEDDED
770 //US ENH: this is the magic function that syncronizes the local doc with the remote doc. 751 //US ENH: this is the magic function that syncronizes the local doc with the remote doc.
771 PwMerror syncronize(KSyncManager* manager, PwMDoc* syncLocal, PwMDoc* syncRemote, int mode ); 752 PwMerror syncronize(KSyncManager* manager, PwMDoc* syncLocal, PwMDoc* syncRemote, int mode );
772 753
773 //takePwMDataItem returns the following values 754 //takePwMDataItem returns the following values
774 // 0 equal 755 // 0 equal
775 // 1 take local 756 // 1 take local
776 // 2 take remote 757 // 2 take remote
777 // 3 cancel 758 // 3 cancel
778 int takePwMDataItem( PwMDataItem* local, PwMDataItem* remote, QDateTime lastSync, int mode , bool full ); 759 int takePwMDataItem( PwMDataItem* local, PwMDataItem* remote, QDateTime lastSync, int mode , bool full );
779 760
780 //the following methods are the overwritten callbackmethods from the syncinterface 761 //the following methods are the overwritten callbackmethods from the syncinterface
781 virtual bool sync(KSyncManager* manager, QString filename, int mode); 762 virtual bool sync(KSyncManager* manager, QString filename, int mode);
782 763
783#endif 764#endif
784 private: 765 private:
785 //US ENH: helpermethods to access the sync data for a certain syncname. 766 //US ENH: helpermethods to access the sync data for a certain syncname.
786 // It returns the syncdatas index 767 // It returns the syncdatas index
787 bool findSyncData(const QString &syncname, unsigned int *index); 768 bool findSyncData(const QString &syncname, unsigned int *index);
788 769
789 /** add new syncdataentry */ 770 /** add new syncdataentry */
790 PwMerror addSyncDataEntry(PwMSyncItem *d, bool dontFlagDirty = false); 771 PwMerror addSyncDataEntry(PwMSyncItem *d, bool dontFlagDirty = false);
791 772
792 /** returns a pointer to the syncdata */ 773 /** returns a pointer to the syncdata */
793 PwMSyncItem* getSyncDataEntry(unsigned int index) 774 PwMSyncItem* getSyncDataEntry(unsigned int index)
794 { return &(dti.syncDta[index]); } 775 { return &(dti.syncDta[index]); }
795 776
796 /** delete entry */ 777 /** delete entry */
797 bool delSyncDataEntry(unsigned int index, bool dontFlagDirty = false); 778 bool delSyncDataEntry(unsigned int index, bool dontFlagDirty = false);
798 779
799 PwMDataItem* findEntryByID(const QString &uid, unsigned int *category, unsigned int *index); 780 PwMDataItem* findEntryByID(const QString &uid, unsigned int *category, unsigned int *index);
800 781
801 QStringList getIDEntryList(); 782 QStringList getIDEntryList();
802 783
803}; 784};
804 785
805#endif 786#endif