• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

proftpd / proftpd / 28259826111

26 Jun 2026 07:20PM UTC coverage: 93.032% (+0.6%) from 92.469%
28259826111

push

github

51363 of 55210 relevant lines covered (93.03%)

200.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.68
/tests/api/display.c
1
/*
2
 * ProFTPD - FTP server testsuite
3
 * Copyright (c) 2015-2026 The ProFTPD Project team
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
17
 *
18
 * As a special exemption, The ProFTPD Project team and other respective
19
 * copyright holders give permission to link this program with OpenSSL, and
20
 * distribute the resulting executable, without including the source code for
21
 * OpenSSL in the source distribution.
22
 */
23

24
/* Display API tests
25
 */
26

27
#include "tests.h"
28

29
extern pr_response_t *resp_list, *resp_err_list;
30

31
static pool *p = NULL;
32

33
static const char *display_test_file = "/tmp/prt-display.txt";
34

35
static const char *display_lines[] = {
36
  "Hello, %U\n",
37
  "Environment: %{env:FOO} (%{env:NO_FOO})\n",
38
  "Variable: %{BAR}\n",
39
  "Time: %{time:%Y%m%d}\n",
40
  NULL
41
};
42

43
/* Fixtures */
44

45
static void set_up(void) {
46
  (void) unlink(display_test_file);
2✔
47

2✔
48
  if (p == NULL) {
49
    p = session.pool = permanent_pool = make_sub_pool(NULL);
2✔
50
  }
2✔
51

52
  init_dirtree();
53
  init_fs();
2✔
54
  init_netio();
2✔
55
  init_inet();
2✔
56

2✔
57
  if (getenv("TEST_VERBOSE") != NULL) {
58
    pr_trace_set_levels("netio", 1, 20);
2✔
59
    pr_trace_set_levels("response", 1, 20);
2✔
60
  }
2✔
61
}
62

2✔
63
static void tear_down(void) {
64
  pr_response_register_handler(NULL);
2✔
65

2✔
66
  if (session.c != NULL) {
67
    pr_inet_close(p, session.c);
2✔
68
    session.c = NULL;
×
69
  }
×
70

71
  pr_unregister_netio(PR_NETIO_STRM_CTRL);
72

2✔
73
  if (getenv("TEST_VERBOSE") != NULL) {
74
    pr_trace_set_levels("netio", 0, 0);
2✔
75
    pr_trace_set_levels("response", 0, 0);
2✔
76
  }
2✔
77

78
  (void) unlink(display_test_file);
79

2✔
80
  if (p) {
81
    destroy_pool(p);
2✔
82
    p = session.pool = permanent_pool = NULL;
2✔
83
  }
2✔
84
}
85

2✔
86
static int write_file(const char *path, const char **lines,
87
    unsigned int nlines) {
2✔
88
  register unsigned int i;
89
  FILE *fh;
2✔
90
  int res;
2✔
91

2✔
92
  /* Write out a test Display file. */
93
  fh = fopen(path, "w+");
94
  if (fh == NULL) {
2✔
95
    return -1;
2✔
96
  }
97

98
  for (i = 0; i < nlines; i++) {
99
    const char *line;
10✔
100
    size_t line_len;
8✔
101

8✔
102
    line = lines[i];
103
    line_len = strlen(line);
8✔
104
    fwrite(line, line_len, 1, fh);
8✔
105
  }
8✔
106

107
  res = fclose(fh);
108
  return res;
2✔
109
}
2✔
110

111
/* Tests */
112

113
START_TEST (display_file_test) {
114
  int res;
1✔
115
  const char *path = NULL, *resp_code = NULL;
1✔
116
  const char *last_resp_code = NULL, *last_resp_msg = NULL;
1✔
117
  pr_class_t *conn_class;
1✔
118

1✔
119
  res = pr_display_file(NULL, NULL, NULL, 0);
120
  ck_assert_msg(res < 0, "Failed to handle null arguments");
1✔
121
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
122
    strerror(errno), errno);
1✔
123

124
  path = display_test_file;
125
  res = pr_display_file(path, NULL, NULL, 0);
1✔
126
  ck_assert_msg(res < 0, "Failed to handle null resp_code argument");
1✔
127
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
128
    strerror(errno), errno);
1✔
129

130
  mark_point();
131
  resp_code = R_200;
1✔
132
  path = "/";
1✔
133
  res = pr_display_file(path, NULL, resp_code, 0);
1✔
134
  ck_assert_msg(res < 0, "Failed to handle directory");
1✔
135
  ck_assert_msg(errno == EISDIR, "Expected EISDIR (%d), got %s (%d)", EISDIR,
1✔
136
    strerror(errno), errno);
1✔
137

138
  mark_point();
139
  path = display_test_file;
1✔
140
  res = pr_display_file(path, NULL, resp_code, 0);
1✔
141
  ck_assert_msg(res < 0, "Failed to handle nonexistent file");
1✔
142
  ck_assert_msg(errno == ENOENT, "Expected ENOENT (%d), got %s (%d)", ENOENT,
1✔
143
    strerror(errno), errno);
1✔
144

145
  res = write_file(path, display_lines, 4);
146
  ck_assert_msg(res == 0, "Failed to write display file: %s", strerror(errno));
1✔
147

1✔
148
  pr_response_set_pool(p);
149

1✔
150
  conn_class = pcalloc(p, sizeof(pr_class_t));
151
  conn_class->cls_pool = p;
1✔
152
  conn_class->cls_name = "foo.bar";
1✔
153
  session.conn_class = conn_class;
1✔
154

1✔
155
  mark_point();
156
  res = pr_display_file(path, NULL, resp_code, 0);
1✔
157
  ck_assert_msg(res == 0, "Failed to display file: %s", strerror(errno));
1✔
158

1✔
159
  mark_point();
160
  res = pr_response_get_last(p, &last_resp_code, &last_resp_msg);
1✔
161
  ck_assert_msg(res == 0, "Failed to get last response values: %s (%d)",
1✔
162
    strerror(errno), errno);
1✔
163

164
  ck_assert_msg(last_resp_code != NULL,
165
    "Last response code is unexpectedly null");
1✔
166
  ck_assert_msg(strcmp(last_resp_code, resp_code) == 0,
167
    "Expected response code '%s', got '%s'", resp_code, last_resp_code);
1✔
168

169
  ck_assert_msg(last_resp_msg != NULL,
170
    "Last response message is unexpectedly null");
1✔
171

172
  /* Send the display file NOW */
173
  mark_point();
174
  res = pr_display_file(path, NULL, resp_code, PR_DISPLAY_FL_SEND_NOW);
1✔
175
  ck_assert_msg(res == 0, "Failed to display file: %s", strerror(errno));
1✔
176

1✔
177
  mark_point();
178
  res = pr_response_get_last(p, &last_resp_code, &last_resp_msg);
1✔
179
  ck_assert_msg(res == 0, "Failed to get last response values: %s (%d)",
1✔
180
    strerror(errno), errno);
1✔
181

182
  ck_assert_msg(last_resp_code != NULL,
183
    "Last response code is unexpectedly null");
1✔
184
  ck_assert_msg(strcmp(last_resp_code, resp_code) == 0,
185
    "Expected response code '%s', got '%s'", resp_code, last_resp_code);
1✔
186

187
  ck_assert_msg(last_resp_msg != NULL,
188
    "Last response message is unexpectedly null");
1✔
189

190
  /* Send the display file NOW, with no EOM */
191

192
  mark_point();
193
  res = pr_display_file(path, NULL, resp_code,
1✔
194
    PR_DISPLAY_FL_SEND_NOW|PR_DISPLAY_FL_NO_EOM);
1✔
195
  ck_assert_msg(res == 0, "Failed to display file: %s", strerror(errno));
196

1✔
197
  mark_point();
198
  res = pr_response_get_last(p, &last_resp_code, &last_resp_msg);
1✔
199
  ck_assert_msg(res == 0, "Failed to get last response values: %s (%d)",
1✔
200
    strerror(errno), errno);
1✔
201

202
  ck_assert_msg(last_resp_code != NULL,
203
    "Last response code is unexpectedly null");
1✔
204
  ck_assert_msg(strcmp(last_resp_code, resp_code) == 0,
205
    "Expected response code '%s', got '%s'", resp_code, last_resp_code);
1✔
206

207
  ck_assert_msg(last_resp_msg != NULL,
208
    "Last response message is unexpectedly null");
1✔
209

210
  /* With MultilineRFC2228 on */
211
  mark_point();
212
  res = pr_display_file(path, NULL, resp_code,
1✔
213
    PR_DISPLAY_FL_SEND_NOW|PR_DISPLAY_FL_NO_EOM);
1✔
214
  ck_assert_msg(res == 0, "Failed to display file: %s", strerror(errno));
215

1✔
216
  mark_point();
217
  res = pr_display_file(path, NULL, resp_code, PR_DISPLAY_FL_SEND_NOW);
1✔
218
  ck_assert_msg(res == 0, "Failed to display file: %s", strerror(errno));
1✔
219

1✔
220
  /* With session.auth_mech */
221
  session.auth_mech = "testsuite";
222

1✔
223
  mark_point();
224
  res = pr_display_file(path, NULL, resp_code,
1✔
225
    PR_DISPLAY_FL_SEND_NOW|PR_DISPLAY_FL_NO_EOM);
1✔
226
  ck_assert_msg(res == 0, "Failed to display file: %s", strerror(errno));
227

1✔
228
  mark_point();
229
  res = pr_display_file(path, NULL, resp_code, PR_DISPLAY_FL_SEND_NOW);
1✔
230
  ck_assert_msg(res == 0, "Failed to display file: %s", strerror(errno));
1✔
231
}
1✔
232
END_TEST
1✔
233

234
START_TEST (display_fh_test) {
235
  pr_fh_t *fh;
1✔
236
  int res;
1✔
237
  const char *path = NULL, *resp_code = NULL;
1✔
238
  const char *last_resp_code = NULL, *last_resp_msg = NULL;
1✔
239

1✔
240
  res = pr_display_fh(NULL, NULL, NULL, 0);
241
  ck_assert_msg(res < 0, "Failed to handle null arguments");
1✔
242
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
243
    strerror(errno), errno);
1✔
244

245
  (void) unlink(display_test_file);
246
  res = write_file(display_test_file, display_lines, 4);
1✔
247
  ck_assert_msg(res == 0, "Failed to write display file: %s", strerror(errno));
1✔
248

1✔
249
  path = display_test_file;
250
  fh = pr_fsio_open(path, O_RDONLY);
1✔
251
  ck_assert_msg(fh != NULL, "Failed to open '%s': %s", path, strerror(errno));
1✔
252

1✔
253
  mark_point();
254
  res = pr_display_fh(fh, NULL, NULL, 0);
1✔
255
  ck_assert_msg(res < 0, "Failed to handle null resp_code argument");
1✔
256
  ck_assert_msg(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
1✔
257
    strerror(errno), errno);
1✔
258

259
  resp_code = R_200;
260
  pr_response_set_pool(p);
1✔
261

1✔
262
  mark_point();
263
  res = pr_display_fh(fh, NULL, resp_code, 0);
1✔
264
  ck_assert_msg(res == 0, "Failed to display file: %s", strerror(errno));
1✔
265

1✔
266
  mark_point();
267
  res = pr_response_get_last(p, &last_resp_code, &last_resp_msg);
1✔
268
  ck_assert_msg(res == 0, "Failed to get last response values: %s (%d)",
1✔
269
    strerror(errno), errno);
1✔
270

271
  ck_assert_msg(last_resp_code != NULL,
272
    "Last response code is unexpectedly null");
1✔
273
  ck_assert_msg(strcmp(last_resp_code, resp_code) == 0,
274
    "Expected response code '%s', got '%s'", resp_code, last_resp_code);
1✔
275

276
  ck_assert_msg(last_resp_msg != NULL,
277
    "Last response message is unexpectedly null");
1✔
278
}
279
END_TEST
1✔
280

281
Suite *tests_get_display_suite(void) {
282
  Suite *suite;
890✔
283
  TCase *testcase;
890✔
284

890✔
285
  suite = suite_create("display");
286

890✔
287
  testcase = tcase_create("base");
288
  tcase_add_checked_fixture(testcase, set_up, tear_down);
890✔
289

890✔
290
  tcase_add_test(testcase, display_file_test);
291
  tcase_add_test(testcase, display_fh_test);
890✔
292

890✔
293
  suite_add_tcase(suite, testcase);
294
  return suite;
890✔
295
}
890✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc