libgnunetchat

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

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 }