LCOV - code coverage report
Current view: top level - src/domain/write - forward.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 72.5 % 51 37
Test Date: 2026-04-20 19:54:22 Functions: 100.0 % 2 2

            Line data    Source code
       1              : /* SPDX-License-Identifier: GPL-3.0-or-later */
       2              : /* Copyright 2026 Peter Csaszar */
       3              : 
       4              : /**
       5              :  * @file domain/write/forward.c
       6              :  * @brief messages.forwardMessages (US-P5-06).
       7              :  */
       8              : 
       9              : #include "domain/write/forward.h"
      10              : 
      11              : #include "tl_serial.h"
      12              : #include "tl_registry.h"
      13              : #include "mtproto_rpc.h"
      14              : #include "crypto.h"
      15              : #include "logger.h"
      16              : 
      17              : #include <string.h>
      18              : 
      19              : #define CRC_messages_forwardMessages 0xc661bbc4u
      20              : 
      21            6 : static int write_input_peer(TlWriter *w, const HistoryPeer *p) {
      22            6 :     switch (p->kind) {
      23            3 :     case HISTORY_PEER_SELF:
      24            3 :         tl_write_uint32(w, TL_inputPeerSelf);    return 0;
      25            3 :     case HISTORY_PEER_USER:
      26            3 :         tl_write_uint32(w, TL_inputPeerUser);
      27            3 :         tl_write_int64 (w, p->peer_id);
      28            3 :         tl_write_int64 (w, p->access_hash);      return 0;
      29            0 :     case HISTORY_PEER_CHAT:
      30            0 :         tl_write_uint32(w, TL_inputPeerChat);
      31            0 :         tl_write_int64 (w, p->peer_id);          return 0;
      32            0 :     case HISTORY_PEER_CHANNEL:
      33            0 :         tl_write_uint32(w, TL_inputPeerChannel);
      34            0 :         tl_write_int64 (w, p->peer_id);
      35            0 :         tl_write_int64 (w, p->access_hash);      return 0;
      36            0 :     default: return -1;
      37              :     }
      38              : }
      39              : 
      40            5 : int domain_forward_messages(const ApiConfig *cfg,
      41              :                              MtProtoSession *s, Transport *t,
      42              :                              const HistoryPeer *from,
      43              :                              const HistoryPeer *to,
      44              :                              const int32_t *ids, int n_ids,
      45              :                              RpcError *err) {
      46            5 :     if (!cfg || !s || !t || !from || !to || !ids || n_ids <= 0 || n_ids > 100)
      47            2 :         return -1;
      48              : 
      49            3 :     TlWriter w; tl_writer_init(&w);
      50            3 :     tl_write_uint32(&w, CRC_messages_forwardMessages);
      51            3 :     tl_write_uint32(&w, 0);                        /* flags = 0 */
      52            3 :     if (write_input_peer(&w, from) != 0) { tl_writer_free(&w); return -1; }
      53            3 :     tl_write_uint32(&w, TL_vector);                /* id vector */
      54            3 :     tl_write_uint32(&w, (uint32_t)n_ids);
      55            8 :     for (int i = 0; i < n_ids; i++) tl_write_int32(&w, ids[i]);
      56            3 :     tl_write_uint32(&w, TL_vector);                /* random_id vector */
      57            3 :     tl_write_uint32(&w, (uint32_t)n_ids);
      58            8 :     for (int i = 0; i < n_ids; i++) {
      59              :         uint8_t rnd[8];
      60            5 :         int64_t rid = 0;
      61            5 :         if (crypto_rand_bytes(rnd, 8) == 0) memcpy(&rid, rnd, 8);
      62            5 :         tl_write_int64(&w, rid);
      63              :     }
      64            3 :     if (write_input_peer(&w, to) != 0) { tl_writer_free(&w); return -1; }
      65              : 
      66              :     uint8_t query[2048];
      67            3 :     if (w.len > sizeof(query)) { tl_writer_free(&w); return -1; }
      68            3 :     memcpy(query, w.data, w.len);
      69            3 :     size_t qlen = w.len;
      70            3 :     tl_writer_free(&w);
      71              : 
      72            3 :     uint8_t resp[4096]; size_t resp_len = 0;
      73            3 :     if (api_call(cfg, s, t, query, qlen, resp, sizeof(resp), &resp_len) != 0) {
      74            0 :         logger_log(LOG_ERROR, "forward: api_call failed");
      75            0 :         return -1;
      76              :     }
      77            3 :     if (resp_len < 4) return -1;
      78              : 
      79              :     uint32_t top;
      80            3 :     memcpy(&top, resp, 4);
      81            3 :     if (top == TL_rpc_error) {
      82            0 :         if (err) rpc_parse_error(resp, resp_len, err);
      83            0 :         return -1;
      84              :     }
      85            3 :     if (top == TL_updates || top == TL_updatesCombined
      86            1 :         || top == TL_updateShort) {
      87            3 :         return 0;
      88              :     }
      89            0 :     logger_log(LOG_WARN, "forward: unexpected top 0x%08x", top);
      90            0 :     return 0;
      91              : }
        

Generated by: LCOV version 2.0-1