File indexing completed on 2024-04-28 16:59:41
0001 /* 0002 Copyright (C) 2019 Andreas Hartmetz <ahartmetz@gmail.com> 0003 0004 This library is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU Library General Public 0006 License as published by the Free Software Foundation; either 0007 version 2 of the License, or (at your option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 Library General Public 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.LGPL. If not, write to 0016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0017 Boston, MA 02110-1301, USA. 0018 0019 Alternatively, this file is available under the Mozilla Public License 0020 Version 1.1. You may obtain a copy of the License at 0021 http://www.mozilla.org/MPL/ 0022 */ 0023 0024 static Message createEavesdropMessage(const char *messageType) 0025 { 0026 Message ret = Message::createCall("/org/freedesktop/DBus", "org.freedesktop.DBus", "AddMatch"); 0027 ret.setDestination("org.freedesktop.DBus"); 0028 Arguments::Writer writer; 0029 std::string str = "eavesdrop=true,type="; 0030 str += messageType; 0031 writer.writeString(cstring(str.c_str())); 0032 ret.setArguments(writer.finish()); 0033 return ret; 0034 } 0035 0036 enum SetupEavesdroppingResult 0037 { 0038 OldStyleEavesdropping = 0, 0039 NewStyleEavesdropping, 0040 FailedEavesdropping 0041 }; 0042 0043 static SetupEavesdroppingResult setupEavesdropping(Connection *connection) 0044 { 0045 { 0046 // new way to request eavesdropping / monitoring, not yet universally available 0047 Message msg = Message::createCall("/org/freedesktop/DBus", "org.freedesktop.DBus.Monitoring", 0048 "BecomeMonitor"); 0049 msg.setDestination("org.freedesktop.DBus"); 0050 Arguments::Writer writer; 0051 writer.beginArray(Arguments::Writer::WriteTypesOfEmptyArray); 0052 writer.writeString(cstring()); 0053 writer.endArray(); 0054 writer.writeUint32(0); 0055 msg.setArguments(writer.finish()); 0056 PendingReply pendingReply = connection->send(std::move(msg)); 0057 while (!pendingReply.isFinished()) { 0058 connection->eventDispatcher()->poll(); 0059 } 0060 if (!pendingReply.isError()) { 0061 return NewStyleEavesdropping; 0062 } 0063 } 0064 0065 { 0066 // old way to request eavesdropping / monitoring, now disabled in some distributions 0067 static const int messageTypeCount = 4; 0068 const char *messageType[messageTypeCount] = { 0069 "signal", 0070 "method_call", 0071 "method_return", 0072 "error" 0073 }; 0074 0075 std::vector<PendingReply> pendingReplies; 0076 pendingReplies.reserve(messageTypeCount); 0077 for (int i = 0; i < messageTypeCount; i++) { 0078 pendingReplies.emplace_back(connection->send(createEavesdropMessage(messageType[i]))); 0079 } 0080 0081 bool done = false; 0082 while (!done) { 0083 connection->eventDispatcher()->poll(); 0084 done = true; 0085 for (const PendingReply &PR : pendingReplies) { 0086 done = done && PR.isFinished(); 0087 if (PR.isError()) { 0088 // ### this error detection doesn't seem to work - on my test system with Kubuntu 19.10, 0089 // eavesdropping failed silently(!) 0090 return FailedEavesdropping; 0091 } 0092 } 0093 } 0094 } 0095 return OldStyleEavesdropping; 0096 }