File indexing completed on 2024-06-02 05:28:05

0001 /*
0002     SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
0003     SPDX-FileContributor: Volker Krause <volker.krause@kdab.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "response.h"
0009 #include "kmanagersieve_debug.h"
0010 
0011 void KManageSieve::Response::clear()
0012 {
0013     m_type = None;
0014     m_key.clear();
0015     m_value.clear();
0016     m_extra.clear();
0017     m_quantity = 0;
0018 }
0019 
0020 QByteArray KManageSieve::Response::action() const
0021 {
0022     return m_key;
0023 }
0024 
0025 QByteArray KManageSieve::Response::extra() const
0026 {
0027     return m_extra;
0028 }
0029 
0030 QByteArray KManageSieve::Response::key() const
0031 {
0032     return m_key;
0033 }
0034 
0035 QByteArray KManageSieve::Response::value() const
0036 {
0037     return m_value;
0038 }
0039 
0040 uint KManageSieve::Response::quantity() const
0041 {
0042     return m_quantity;
0043 }
0044 
0045 KManageSieve::Response::Type KManageSieve::Response::type() const
0046 {
0047     return m_type;
0048 }
0049 
0050 static uint parseQuantity(const QByteArray &line, int start, bool *ok = nullptr)
0051 {
0052     // expecting {quantity} at start
0053     int end = line.indexOf("+}", start + 1);
0054     // some older versions of Cyrus enclose the literal size just in { } instead of { +}
0055     if (end == -1) {
0056         end = line.indexOf('}', start + 1);
0057     }
0058 
0059     return line.mid(start + 1, end - start - 1).toUInt(ok);
0060 }
0061 
0062 bool KManageSieve::Response::parseResponse(const QByteArray &line)
0063 {
0064     clear();
0065 
0066     switch (line.at(0)) {
0067     case '{': {
0068         m_type = Quantity;
0069         bool ok = false;
0070         m_quantity = parseQuantity(line, 0, &ok);
0071         return ok;
0072     }
0073     case '"':
0074         // expecting "key" "value" pairs
0075         m_type = KeyValuePair;
0076         break;
0077     default: {
0078         // expecting single string
0079         m_type = Action;
0080         m_key = line;
0081 
0082         // Sometimes NO is followed by a quantity (multiline error message). Ex:
0083         // S:  "NO {62}"
0084         // S:  "script errors:"
0085         // S:  line 17: syntax error, unexpected $undefined
0086         const int bracePos = line.indexOf('{');
0087         if (bracePos > 0) {
0088             m_quantity = parseQuantity(line, bracePos);
0089         }
0090         return true;
0091     }
0092     }
0093 
0094     int start = 0;
0095     int end = line.indexOf('"', start + 1);
0096     if (end == -1) {
0097         qCDebug(KMANAGERSIEVE_LOG) << "Invalid protocol in:" << line;
0098         m_key = line.right(line.length() - start);
0099         return true;
0100     }
0101     m_key = line.mid(start + 1, end - start - 1);
0102 
0103     start = line.indexOf('"', end + 1);
0104     if (start == -1) {
0105         if (line.length() > end) {
0106             // skip " and space
0107             m_extra = line.right(line.length() - end - 2);
0108         }
0109         return true;
0110     }
0111 
0112     end = line.indexOf('"', start + 1);
0113     if (end == -1) {
0114         qCDebug(KMANAGERSIEVE_LOG) << "Invalid protocol in:" << line;
0115         m_value = line.right(line.length() - start);
0116         return true;
0117     }
0118 
0119     m_value = line.mid(start + 1, end - start - 1);
0120     return true;
0121 }
0122 
0123 KManageSieve::Response::Result KManageSieve::Response::operationResult() const
0124 {
0125     if (m_type == Action) {
0126         const QByteArray response = m_key.left(2);
0127         if (response == "OK") {
0128             return Ok;
0129         } else if (response == "NO") {
0130             return No;
0131         } else if (response == "BY" /*E*/) {
0132             return Bye;
0133         }
0134     }
0135     return Other;
0136 }
0137 
0138 bool KManageSieve::Response::operationSuccessful() const
0139 {
0140     return operationResult() == Ok;
0141 }