gnunet_chat_contact_intern.c (4597B)
1 /* 2 This file is part of GNUnet. 3 Copyright (C) 2021--2024, 2026 GNUnet e.V. 4 5 GNUnet is free software: you can redistribute it and/or modify it 6 under the terms of the GNU Affero General Public License as published 7 by the Free Software Foundation, either version 3 of the License, 8 or (at your option) any later version. 9 10 GNUnet is distributed in the hope that it will be useful, but 11 WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Affero General Public License for more details. 14 15 You should have received a copy of the GNU Affero General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 SPDX-License-Identifier: AGPL3.0-or-later 19 */ 20 /* 21 * @author Tobias Frisch 22 * @file gnunet_chat_contact_intern.c 23 */ 24 25 #include "gnunet_chat_context.h" 26 #include "gnunet_chat_message.h" 27 #include "gnunet_chat_util.h" 28 29 #include <gnunet/gnunet_common.h> 30 #include <gnunet/gnunet_messenger_service.h> 31 #include <gnunet/gnunet_util_lib.h> 32 33 #define GNUNET_UNUSED __attribute__ ((unused)) 34 35 struct GNUNET_CHAT_ContactFindRoom 36 { 37 struct GNUNET_CONTAINER_MultiHashMap *contexts; 38 struct GNUNET_MESSENGER_Room *room; 39 int member_count; 40 }; 41 42 enum GNUNET_GenericReturnValue 43 it_contact_find_room (void *cls, 44 struct GNUNET_MESSENGER_Room *room, 45 GNUNET_UNUSED const struct GNUNET_MESSENGER_Contact *member) 46 { 47 GNUNET_assert((cls) && (room)); 48 49 const int member_count = GNUNET_MESSENGER_iterate_members(room, NULL, NULL); 50 51 struct GNUNET_CHAT_ContactFindRoom *find = cls; 52 struct GNUNET_CHAT_Context *context; 53 54 if ((member_count == 1) && (find->member_count == 1)) 55 context = GNUNET_CONTAINER_multihashmap_get( 56 find->contexts, 57 GNUNET_MESSENGER_room_get_key(room) 58 ); 59 else 60 context = NULL; 61 62 if ((find->member_count <= 0) || 63 ((member_count >= 1) && (member_count < find->member_count)) || 64 ((context) && (context->type == GNUNET_CHAT_CONTEXT_TYPE_CONTACT))) 65 { 66 find->room = room; 67 find->member_count = member_count; 68 } 69 70 return GNUNET_YES; 71 } 72 73 struct GNUNET_CHAT_ContactFindTag 74 { 75 const struct GNUNET_HashCode *hash; 76 }; 77 78 enum GNUNET_GenericReturnValue 79 it_contact_find_tag (void *cls, 80 struct GNUNET_CHAT_Message *message) 81 { 82 GNUNET_assert((cls) && (message)); 83 84 struct GNUNET_CHAT_ContactFindTag *find = cls; 85 86 if ((GNUNET_YES != message_has_msg(message)) || 87 (message->flags & GNUNET_MESSENGER_FLAG_DELETE)) 88 return GNUNET_YES; 89 90 if (message->flags & GNUNET_MESSENGER_FLAG_SENT) 91 { 92 find->hash = &(message->hash); 93 return GNUNET_NO; 94 } 95 96 return GNUNET_YES; 97 } 98 99 struct GNUNET_CHAT_ContactIterateUniqueTag 100 { 101 struct GNUNET_CONTAINER_MultiHashMap *tags; 102 GNUNET_CHAT_ContactTagCallback callback; 103 void *cls; 104 }; 105 106 enum GNUNET_GenericReturnValue 107 it_contact_iterate_unique_tag (void *cls, 108 struct GNUNET_CHAT_Contact *contact, 109 const char *tag) 110 { 111 GNUNET_assert((cls) && (contact) && (tag)); 112 113 struct GNUNET_CHAT_ContactIterateUniqueTag *it = cls; 114 115 struct GNUNET_HashCode hash; 116 GNUNET_CRYPTO_hash(tag, strlen(tag), &hash); 117 118 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(it->tags, &hash)) 119 return GNUNET_YES; 120 121 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(it->tags, 122 &hash, NULL, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) 123 return GNUNET_YES; 124 125 if (it->callback) 126 return it->callback(it->cls, contact, tag); 127 else 128 return GNUNET_YES; 129 } 130 131 struct GNUNET_CHAT_ContactIterateTag 132 { 133 struct GNUNET_CHAT_Contact *contact; 134 GNUNET_CHAT_ContactTagCallback callback; 135 void *cls; 136 }; 137 138 enum GNUNET_GenericReturnValue 139 it_contact_iterate_tag (void *cls, 140 struct GNUNET_CHAT_Message *message) 141 { 142 GNUNET_assert((cls) && (message)); 143 144 struct GNUNET_CHAT_ContactIterateTag *it = cls; 145 146 if ((GNUNET_YES != message_has_msg(message)) || 147 (message->flags & GNUNET_MESSENGER_FLAG_DELETE)) 148 return GNUNET_YES; 149 150 if ((message->flags & GNUNET_MESSENGER_FLAG_SENT) && 151 (it->callback) && (message->msg->body.tag.tag)) 152 return it->callback( 153 it->cls, 154 it->contact, 155 message->msg->body.tag.tag 156 ); 157 else 158 return GNUNET_YES; 159 } 160 161 enum GNUNET_GenericReturnValue 162 it_free_join_hashes (void *cls, 163 const struct GNUNET_HashCode *key, 164 void *value) 165 { 166 GNUNET_assert((key) && (value)); 167 168 struct GNUNET_HashCode *hash = value; 169 GNUNET_free(hash); 170 return GNUNET_YES; 171 }