libgnunetchat

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

gnunet_chat_discourse_intern.c (2628B)


      1 /*
      2    This file is part of GNUnet.
      3    Copyright (C) 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_discourse_intern.c
     23  */
     24 
     25 #include "gnunet_chat_context.h"
     26 #include "gnunet_chat_discourse.h"
     27 #include "gnunet_chat_util.h"
     28 
     29 #include <unistd.h>
     30 
     31 #define GNUNET_UNUSED __attribute__ ((unused))
     32 
     33 #define MAX_WRITE_SIZE (    \
     34   GNUNET_MAX_MESSAGE_SIZE - \
     35   GNUNET_MIN_MESSAGE_SIZE - \
     36   sizeof (struct GNUNET_MESSENGER_Message))
     37 
     38 static void
     39 cb_read_discourse_pipe (void *cls);
     40 
     41 void
     42 cb_reinit_discourse_pipe (void *cls)
     43 {
     44   struct GNUNET_CHAT_Discourse *discourse = cls;
     45 
     46   GNUNET_assert(discourse);
     47 
     48   discourse->pipe_task = NULL;
     49 
     50   if (-1 == discourse->pipe[0])
     51     return;
     52 
     53   struct GNUNET_NETWORK_FDSet *rs = GNUNET_NETWORK_fdset_create();
     54 
     55   GNUNET_NETWORK_fdset_set_native(rs, discourse->pipe[0]);
     56 
     57   discourse->pipe_task = GNUNET_SCHEDULER_add_select(
     58     GNUNET_SCHEDULER_PRIORITY_DEFAULT,
     59     GNUNET_TIME_UNIT_FOREVER_REL,
     60     rs,
     61     NULL,
     62     cb_read_discourse_pipe,
     63     discourse
     64   );
     65 
     66   GNUNET_NETWORK_fdset_destroy(rs);
     67 }
     68 
     69 static void
     70 cb_read_discourse_pipe (void *cls)
     71 {
     72   struct GNUNET_CHAT_Discourse *discourse = cls;
     73 
     74   GNUNET_assert((discourse) && (-1 != discourse->pipe[0]));
     75 
     76   discourse->pipe_task = NULL;
     77 
     78   struct GNUNET_MESSENGER_Message msg;
     79   memset(&msg, 0, sizeof(msg));
     80 
     81   msg.header.kind = GNUNET_MESSENGER_KIND_TALK;
     82 
     83   util_shorthash_from_discourse_id(
     84     &(discourse->id),
     85     &(msg.body.talk.discourse)
     86   );
     87 
     88   char data [MAX_WRITE_SIZE];
     89   ssize_t len;
     90 
     91   do
     92   {
     93     len = read(discourse->pipe[0], data, MAX_WRITE_SIZE);
     94 
     95     if (len <= 0)
     96       break;
     97 
     98     msg.body.talk.data = data;
     99     msg.body.talk.length = (uint16_t) len;
    100 
    101     GNUNET_MESSENGER_send_message(discourse->context->room, &msg, NULL);
    102   }
    103   while (MAX_WRITE_SIZE == len);
    104 
    105   if (len < 0)
    106     return;
    107 
    108   discourse->pipe_task = GNUNET_SCHEDULER_add_now(
    109     cb_reinit_discourse_pipe, discourse
    110   );
    111 }