Coverage Report

Created: 2023-06-07 06:15

/src/neomutt/attach/lib.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * @file
3
 * Attachment helper functions
4
 *
5
 * @authors
6
 * Copyright (C) 2022 David Purton <dcpurton@marshwiggle.net>
7
 *
8
 * @copyright
9
 * This program is free software: you can redistribute it and/or modify it under
10
 * the terms of the GNU General Public License as published by the Free Software
11
 * Foundation, either version 2 of the License, or (at your option) any later
12
 * version.
13
 *
14
 * This program is distributed in the hope that it will be useful, but WITHOUT
15
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17
 * details.
18
 *
19
 * You should have received a copy of the GNU General Public License along with
20
 * this program.  If not, see <http://www.gnu.org/licenses/>.
21
 */
22
23
/**
24
 * @page attach_lib Attachment library
25
 *
26
 * Attachment helper functions
27
 */
28
29
#include "config.h"
30
#include <stddef.h>
31
#include <stdbool.h>
32
#include "mutt/lib.h"
33
#include "email/lib.h"
34
35
/**
36
 * attach_body_count - Count bodies
37
 * @param  body    Body to start counting from
38
 * @param  recurse Whether to recurse into groups or not
39
 * @retval num     Number of bodies
40
 * @retval -1      Failure
41
 * */
42
int attach_body_count(struct Body *body, bool recurse)
43
0
{
44
0
  if (!body)
45
0
    return -1;
46
47
0
  int bodies = 0;
48
49
0
  for (struct Body *b = body; b; b = b->next)
50
0
  {
51
0
    bodies++;
52
0
    if (recurse)
53
0
    {
54
0
      if (b->parts)
55
0
        bodies += attach_body_count(b->parts, true);
56
0
    }
57
0
  }
58
59
0
  return bodies;
60
0
}
61
62
/**
63
 * attach_body_parent - Find the parent of a body
64
 * @param[in]  start        Body to start search from
65
 * @param[in]  start_parent Parent of start Body pointer (or NULL if none)
66
 * @param[in]  body         Body to find parent of
67
 * @param[out] body_parent  Body Parent if found
68
 * @retval     true         Parent body found
69
 * @retval     false        Parent body not found
70
 */
71
bool attach_body_parent(struct Body *start, struct Body *start_parent,
72
                        struct Body *body, struct Body **body_parent)
73
0
{
74
0
  if (!start || !body)
75
0
    return false;
76
77
0
  struct Body *b = start;
78
79
0
  if (b->parts)
80
0
  {
81
0
    if (b->parts == body)
82
0
    {
83
0
      *body_parent = b;
84
0
      return true;
85
0
    }
86
0
  }
87
0
  while (b)
88
0
  {
89
0
    if (b == body)
90
0
    {
91
0
      *body_parent = start_parent;
92
0
      if (start_parent)
93
0
        return true;
94
0
      else
95
0
        return false;
96
0
    }
97
0
    if (b->parts)
98
0
    {
99
0
      if (attach_body_parent(b->parts, b, body, body_parent))
100
0
        return true;
101
0
    }
102
0
    b = b->next;
103
0
  }
104
105
0
  return false;
106
0
}
107
108
/**
109
 * attach_body_ancestor - Find the ancestor of a body with specified subtype
110
 * @param[in] start   Body to start search from
111
 * @param[in] body    Body to find ancestor of
112
 * @param[in] subtype Mime subtype of ancestor to find
113
 * @retval ptr  Body ancestor if found
114
 * @retval NULL If ancestor body not found
115
 */
116
struct Body *attach_body_ancestor(struct Body *start, struct Body *body, const char *subtype)
117
0
{
118
0
  if (!start || !body)
119
0
    return false;
120
121
0
  struct Body *b = body;
122
0
  struct Body *b_parent = NULL;
123
124
0
  while (attach_body_parent(start, NULL, b, &b_parent))
125
0
  {
126
0
    if (mutt_str_equal(subtype, b_parent->subtype))
127
0
      return b_parent;
128
0
    b = b_parent;
129
0
  }
130
131
0
  return NULL;
132
0
}
133
134
/**
135
 * attach_body_previous - Find the previous body of a body
136
 * @param[in]  start    Body to start search from
137
 * @param[in]  body     Body to find previous body of
138
 * @param[out] previous Previous Body if found
139
 * @retval     true     Previous body found
140
 * @retval     false    Previous body not found
141
 */
142
bool attach_body_previous(struct Body *start, struct Body *body, struct Body **previous)
143
0
{
144
0
  if (!start || !body)
145
0
    return false;
146
147
0
  struct Body *b = start;
148
149
0
  while (b)
150
0
  {
151
0
    if (b->next == body)
152
0
    {
153
0
      *previous = b;
154
0
      return true;
155
0
    }
156
0
    if (b->parts)
157
0
    {
158
0
      if (attach_body_previous(b->parts, body, previous))
159
0
        return true;
160
0
    }
161
0
    b = b->next;
162
0
  }
163
164
0
  return false;
165
0
}