libgnunetchat

library for GNUnet Messenger
Log | Files | Refs | README | LICENSE

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 }