File indexing completed on 2024-05-12 05:17:25
0001 /* 0002 Copyright (c) 2009 Andras Mantia <amantia@kde.org> 0003 0004 This library is free software; you can redistribute it and/or modify it 0005 under the terms of the GNU Library General Public License as published by 0006 the Free Software Foundation; either version 2 of the License, or (at your 0007 option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, but WITHOUT 0010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 0012 License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to the 0016 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0017 02110-1301, USA. 0018 */ 0019 0020 #include "setmetadatajob.h" 0021 0022 #include "kimap_debug.h" 0023 0024 #include "metadatajobbase_p.h" 0025 #include "message_p.h" 0026 #include "session_p.h" 0027 #include "rfccodecs.h" 0028 0029 namespace KIMAP2 0030 { 0031 class SetMetaDataJobPrivate : public MetaDataJobBasePrivate 0032 { 0033 public: 0034 SetMetaDataJobPrivate(Session *session, const QString &name) : MetaDataJobBasePrivate(session, name), metaDataErrors(Q_NULLPTR), maxAcceptedSize(-1) { } 0035 ~SetMetaDataJobPrivate() { } 0036 0037 QMap<QByteArray, QByteArray> entries; 0038 QMap<QByteArray, QByteArray>::ConstIterator entriesIt; 0039 QByteArray entryName; 0040 SetMetaDataJob::MetaDataErrors metaDataErrors; 0041 qint64 maxAcceptedSize; 0042 }; 0043 } 0044 0045 using namespace KIMAP2; 0046 0047 SetMetaDataJob::SetMetaDataJob(Session *session) 0048 : MetaDataJobBase(*new SetMetaDataJobPrivate(session, "SetMetaData")) 0049 { 0050 } 0051 0052 SetMetaDataJob::~SetMetaDataJob() 0053 { 0054 } 0055 0056 void SetMetaDataJob::doStart() 0057 { 0058 Q_D(SetMetaDataJob); 0059 QByteArray parameters; 0060 parameters = '\"' + KIMAP2::encodeImapFolderName(d->mailBox.toUtf8()) + "\" "; 0061 d->entriesIt = d->entries.constBegin(); 0062 0063 QByteArray command = "SETMETADATA"; 0064 bool bSimpleData = true; 0065 0066 if (d->serverCapability == Annotatemore) { 0067 command = "SETANNOTATION"; 0068 parameters += '\"' + d->entryName + "\" "; 0069 } else { 0070 for (; d->entriesIt != d->entries.constEnd(); ++d->entriesIt) { 0071 if (d->entriesIt.value().contains('\r') || d->entriesIt.value().contains('\n')) { 0072 bSimpleData = false; 0073 break; 0074 } 0075 } 0076 d->entriesIt = d->entries.constBegin(); 0077 } 0078 0079 parameters += '('; 0080 if (bSimpleData == true) { 0081 for ( ; d->entriesIt != d->entries.constEnd(); ++d->entriesIt ) { 0082 parameters += '\"' + d->entriesIt.key() + "\" "; 0083 if (d->entriesIt.value().isEmpty()) { 0084 parameters += "NIL"; 0085 } else { 0086 parameters += "\"" + d->entriesIt.value() + "\""; 0087 } 0088 parameters += " "; 0089 0090 } 0091 parameters[parameters.length() - 1] = ')'; 0092 } else { 0093 if (!d->entries.isEmpty()) { 0094 parameters += '\"' + d->entriesIt.key() + "\""; 0095 int size = d->entriesIt.value().size(); 0096 parameters += " {" + QByteArray::number( size==0 ? 3 : size ) + '}'; 0097 } 0098 } 0099 0100 if (d->entries.isEmpty()) { 0101 parameters += ')'; 0102 } 0103 0104 d->sendCommand(command, parameters); 0105 // qCDebug(KIMAP2_LOG) << "SENT: " << command << " " << parameters; 0106 } 0107 0108 void SetMetaDataJob::handleResponse(const Message &response) 0109 { 0110 Q_D(SetMetaDataJob); 0111 0112 //TODO: Test if a server can really return more then one untagged NO response. If not, no need to OR the error codes 0113 if (!response.content.isEmpty() && 0114 d->tags.contains(response.content.first().toString())) { 0115 if (response.content[1].toString() == "NO") { 0116 setError(UserDefinedError); 0117 setErrorText(QString("%1 failed, server replied: %2").arg(d->m_name).arg(QLatin1String(response.toString().constData()))); 0118 if (response.content[2].toString() == "[ANNOTATEMORE TOOMANY]" || 0119 response.content[2].toString() == "[METADATA TOOMANY]") { 0120 d->metaDataErrors |= TooMany; 0121 } else if (response.content[2].toString() == "[ANNOTATEMORE TOOBIG]" || 0122 response.content[2].toString().startsWith("[METADATA MAXSIZE")) { //krazy:exclude=strings 0123 d->metaDataErrors |= TooBig; 0124 d->maxAcceptedSize = -1; 0125 if (response.content[2].toString().startsWith("[METADATA MAXSIZE")) { //krazy:exclude=strings 0126 QByteArray max = response.content[2].toString(); 0127 max.replace("[METADATA MAXSIZE", ""); //krazy:exclude=doublequote_chars 0128 max.replace("]", ""); //krazy:exclude=doublequote_chars 0129 d->maxAcceptedSize = max.toLongLong(); 0130 } 0131 } else if (response.content[2].toString() == "[METADATA NOPRIVATE]") { 0132 d->metaDataErrors |= NoPrivate; 0133 } 0134 } else if (response.content.size() < 2) { 0135 setErrorText(QString("%1 failed, malformed reply from the server.").arg(d->m_name)); 0136 } else if (response.content[1].toString() != "OK") { 0137 setError(UserDefinedError); 0138 setErrorText(QString("%1 failed, server replied: %2").arg(d->m_name).arg(QLatin1String(response.toString().constData()))); 0139 } 0140 emitResult(); 0141 } else if (d->serverCapability == Metadata && response.content[0].toString() == "+") { 0142 QByteArray content = ""; 0143 if (d->entriesIt.value().isEmpty()) { 0144 content += "NIL"; 0145 } else { 0146 content += d->entriesIt.value(); 0147 } 0148 ++d->entriesIt; 0149 if (d->entriesIt == d->entries.constEnd()) { 0150 content += ')'; 0151 } else { 0152 content += " \"" + d->entriesIt.key() + '\"'; 0153 int size = d->entriesIt.value().size(); 0154 content += " {" + QByteArray::number( size==0 ? 3 : size ) + '}'; 0155 } 0156 // qCDebug(KIMAP2_LOG) << "SENT: " << content; 0157 d->sessionInternal()->sendData(content); 0158 } 0159 } 0160 0161 void SetMetaDataJob::addMetaData(const QByteArray &name, const QByteArray &value) 0162 { 0163 Q_D(SetMetaDataJob); 0164 if (d->serverCapability == Annotatemore && (name.startsWith("/shared") || name.startsWith("/private"))) { 0165 const QByteArray &attribute = d->getAttribute(name); 0166 d->entries[attribute] = value; 0167 d->entryName = d->removePrefix(name); 0168 } else { 0169 d->entries[name] = value; 0170 } 0171 } 0172 0173 void SetMetaDataJob::setEntry(const QByteArray &entry) 0174 { 0175 Q_D(SetMetaDataJob); 0176 d->entryName = entry; 0177 } 0178 0179 SetMetaDataJob::MetaDataErrors SetMetaDataJob::metaDataErrors() const 0180 { 0181 Q_D(const SetMetaDataJob); 0182 return d->metaDataErrors; 0183 }