Coverage Report

Created: 2026-05-30 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pigeonhole/src/testsuite/testsuite-smtp.c
Line
Count
Source
1
/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file
2
 */
3
4
#include "lib.h"
5
#include "array.h"
6
#include "ostream.h"
7
#include "unlink-directory.h"
8
9
#include "sieve-common.h"
10
#include "sieve-error.h"
11
#include "sieve-interpreter.h"
12
13
#include "testsuite-message.h"
14
#include "testsuite-common.h"
15
#include "testsuite-smtp.h"
16
17
#include <unistd.h>
18
#include <fcntl.h>
19
#include <sys/stat.h>
20
#include <sys/types.h>
21
22
struct testsuite_smtp_message {
23
  const struct smtp_address *envelope_from, *envelope_to;
24
  const char *file;
25
};
26
27
static pool_t testsuite_smtp_pool;
28
static const char *testsuite_smtp_tmp;
29
static ARRAY(struct testsuite_smtp_message) testsuite_smtp_messages;
30
31
/*
32
 * Initialize
33
 */
34
35
void testsuite_smtp_init(void)
36
0
{
37
0
  pool_t pool;
38
39
0
  testsuite_smtp_pool = pool =
40
0
    pool_alloconly_create("testsuite_smtp", 8192);
41
42
0
  testsuite_smtp_tmp = p_strconcat(
43
0
    pool, testsuite_tmp_dir_get(), "/smtp", NULL);
44
45
0
  if (mkdir(testsuite_smtp_tmp, 0700) < 0) {
46
0
    i_fatal("failed to create temporary directory '%s': %m.",
47
0
      testsuite_smtp_tmp);
48
0
  }
49
50
0
  p_array_init(&testsuite_smtp_messages, pool, 16);
51
0
}
52
53
void testsuite_smtp_deinit(void)
54
0
{
55
0
  const char *error;
56
57
0
  if (unlink_directory(testsuite_smtp_tmp, UNLINK_DIRECTORY_FLAG_RMDIR,
58
0
           &error) < 0) {
59
0
    i_warning("failed to remove temporary directory '%s': %s.",
60
0
      testsuite_smtp_tmp, error);
61
0
  }
62
0
  pool_unref(&testsuite_smtp_pool);
63
0
}
64
65
void testsuite_smtp_reset(void)
66
0
{
67
0
  testsuite_smtp_deinit();
68
0
  testsuite_smtp_init();
69
0
}
70
71
/*
72
 * Simulated SMTP out
73
 */
74
75
struct testsuite_smtp {
76
  char *msg_file;
77
  struct smtp_address *mail_from;
78
  struct ostream *output;
79
};
80
81
void *testsuite_smtp_start(const struct sieve_script_env *senv ATTR_UNUSED,
82
         const struct smtp_address *mail_from)
83
0
{
84
0
  struct testsuite_smtp *smtp;
85
0
  unsigned int smtp_count = array_count(&testsuite_smtp_messages);
86
0
  int fd;
87
88
0
  smtp = i_new(struct testsuite_smtp, 1);
89
90
0
  smtp->msg_file = i_strdup_printf("%s/%d.eml", testsuite_smtp_tmp,
91
0
           smtp_count);
92
0
  smtp->mail_from = smtp_address_clone(default_pool, mail_from);
93
94
0
  fd = open(smtp->msg_file, O_WRONLY | O_CREAT, 0600);
95
0
  if (fd < 0) {
96
0
    i_fatal("failed create tmp file for SMTP simulation: "
97
0
      "open(%s) failed: %m", smtp->msg_file);
98
0
  }
99
100
0
  smtp->output = o_stream_create_fd_autoclose(&fd, (size_t)-1);
101
102
0
  return smtp;
103
0
}
104
105
void testsuite_smtp_add_rcpt(const struct sieve_script_env *senv ATTR_UNUSED,
106
           void *handle, const struct smtp_address *rcpt_to)
107
0
{
108
0
  struct testsuite_smtp *smtp = (struct testsuite_smtp *)handle;
109
0
  struct testsuite_smtp_message *msg;
110
111
0
  msg = array_append_space(&testsuite_smtp_messages);
112
113
0
  msg->file = p_strdup(testsuite_smtp_pool, smtp->msg_file);
114
0
  msg->envelope_from = smtp_address_clone(testsuite_smtp_pool,
115
0
            smtp->mail_from);
116
0
  msg->envelope_to = smtp_address_clone(testsuite_smtp_pool, rcpt_to);
117
0
}
118
119
struct ostream *
120
testsuite_smtp_send(const struct sieve_script_env *senv ATTR_UNUSED,
121
        void *handle)
122
0
{
123
0
  struct testsuite_smtp *smtp = (struct testsuite_smtp *)handle;
124
125
0
  return smtp->output;
126
0
}
127
128
void testsuite_smtp_abort(const struct sieve_script_env *senv ATTR_UNUSED,
129
        void *handle)
130
0
{
131
0
  struct testsuite_smtp *smtp = (struct testsuite_smtp *)handle;
132
133
0
  o_stream_ignore_last_errors(smtp->output);
134
0
  o_stream_unref(&smtp->output);
135
0
  i_unlink(smtp->msg_file);
136
0
  i_free(smtp->msg_file);
137
0
  i_free(smtp->mail_from);
138
0
  i_free(smtp);
139
0
}
140
141
int testsuite_smtp_finish(const struct sieve_script_env *senv ATTR_UNUSED,
142
        void *handle, const char **error_r ATTR_UNUSED)
143
0
{
144
0
  struct testsuite_smtp *smtp = (struct testsuite_smtp *)handle;
145
0
  int ret = 1;
146
147
0
  if (o_stream_finish(smtp->output) < 0) {
148
0
    i_error("write(%s) failed: %s", smtp->msg_file,
149
0
      o_stream_get_error(smtp->output));
150
0
    ret = -1;
151
0
  }
152
0
  o_stream_unref(&smtp->output);
153
0
  i_free(smtp->msg_file);
154
0
  i_free(smtp->mail_from);
155
0
  i_free(smtp);
156
0
  return ret;
157
0
}
158
159
/*
160
 * Access
161
 */
162
163
bool testsuite_smtp_get(const struct sieve_runtime_env *renv,
164
      unsigned int index)
165
0
{
166
0
  const struct testsuite_smtp_message *smtp_msg;
167
168
0
  if (index >= array_count(&testsuite_smtp_messages))
169
0
    return FALSE;
170
171
0
  smtp_msg = array_idx(&testsuite_smtp_messages, index);
172
173
0
  testsuite_message_set_file(renv, smtp_msg->file);
174
0
  testsuite_envelope_set_sender_address(renv, smtp_msg->envelope_from);
175
0
  testsuite_envelope_set_recipient_address(renv, smtp_msg->envelope_to);
176
0
  return TRUE;
177
0
}