gnunet_chat_contact_intern.c (4217B)
1 /* 2 This file is part of GNUnet. 3 Copyright (C) 2021--2024 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 28 #include <gnunet/gnunet_common.h> 29 #include <gnunet/gnunet_messenger_service.h> 30 #include <gnunet/gnunet_util_lib.h> 31 #include <stdlib.h> 32 33 #define GNUNET_UNUSED __attribute__ ((unused)) 34 35 struct GNUNET_CHAT_ContactFindRoom 36 { 37 int member_count; 38 struct GNUNET_MESSENGER_Room *room; 39 }; 40 41 enum GNUNET_GenericReturnValue 42 it_contact_find_room (void *cls, 43 struct GNUNET_MESSENGER_Room *room, 44 GNUNET_UNUSED const struct GNUNET_MESSENGER_Contact *member) 45 { 46 GNUNET_assert((cls) && (room)); 47 48 const int member_count = GNUNET_MESSENGER_iterate_members(room, NULL, NULL); 49 50 struct GNUNET_CHAT_ContactFindRoom *find = cls; 51 52 if ((find->member_count <= 0) || 53 ((member_count >= 1) && (member_count < find->member_count))) 54 { 55 find->member_count = member_count; 56 find->room = room; 57 } 58 59 return GNUNET_YES; 60 } 61 62 struct GNUNET_CHAT_ContactFindTag 63 { 64 const struct GNUNET_HashCode *hash; 65 }; 66 67 enum GNUNET_GenericReturnValue 68 it_contact_find_tag (void *cls, 69 struct GNUNET_CHAT_Message *message) 70 { 71 GNUNET_assert((cls) && (message)); 72 73 struct GNUNET_CHAT_ContactFindTag *find = cls; 74 75 if ((GNUNET_YES != message_has_msg(message)) || 76 (message->flags & GNUNET_MESSENGER_FLAG_DELETE)) 77 return GNUNET_YES; 78 79 if (message->flags & GNUNET_MESSENGER_FLAG_SENT) 80 { 81 find->hash = &(message->hash); 82 return GNUNET_NO; 83 } 84 85 return GNUNET_YES; 86 } 87 88 struct GNUNET_CHAT_ContactIterateUniqueTag 89 { 90 struct GNUNET_CONTAINER_MultiHashMap *tags; 91 GNUNET_CHAT_ContactTagCallback callback; 92 void *cls; 93 }; 94 95 enum GNUNET_GenericReturnValue 96 it_contact_iterate_unique_tag (void *cls, 97 struct GNUNET_CHAT_Contact *contact, 98 const char *tag) 99 { 100 GNUNET_assert((cls) && (contact) && (tag)); 101 102 struct GNUNET_CHAT_ContactIterateUniqueTag *it = cls; 103 104 struct GNUNET_HashCode hash; 105 GNUNET_CRYPTO_hash(tag, strlen(tag), &hash); 106 107 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(it->tags, &hash)) 108 return GNUNET_YES; 109 110 if (GNUNET_OK != GNUNET_CONTAINER_multihashmap_put(it->tags, 111 &hash, NULL, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)) 112 return GNUNET_YES; 113 114 if (it->callback) 115 return it->callback(it->cls, contact, tag); 116 else 117 return GNUNET_YES; 118 } 119 120 struct GNUNET_CHAT_ContactIterateTag 121 { 122 struct GNUNET_CHAT_Contact *contact; 123 GNUNET_CHAT_ContactTagCallback callback; 124 void *cls; 125 }; 126 127 enum GNUNET_GenericReturnValue 128 it_contact_iterate_tag (void *cls, 129 struct GNUNET_CHAT_Message *message) 130 { 131 GNUNET_assert((cls) && (message)); 132 133 struct GNUNET_CHAT_ContactIterateTag *it = cls; 134 135 if ((GNUNET_YES != message_has_msg(message)) || 136 (message->flags & GNUNET_MESSENGER_FLAG_DELETE)) 137 return GNUNET_YES; 138 139 if ((message->flags & GNUNET_MESSENGER_FLAG_SENT) && 140 (it->callback) && (message->msg->body.tag.tag)) 141 return it->callback( 142 it->cls, 143 it->contact, 144 message->msg->body.tag.tag 145 ); 146 else 147 return GNUNET_YES; 148 } 149 150 enum GNUNET_GenericReturnValue 151 it_free_join_hashes (void *cls, 152 const struct GNUNET_HashCode *key, 153 void *value) 154 { 155 GNUNET_assert((key) && (value)); 156 157 struct GNUNET_HashCode *hash = value; 158 GNUNET_free(hash); 159 return GNUNET_YES; 160 }