1 /* $NetBSD: bounce_notify_util_tester.c,v 1.2 2022/10/08 16:12:45 christos Exp $ */
2
3 /*
4 * System library.
5 */
6 #include <sys_defs.h>
7 #include <stdlib.h>
8 #include <sys/stat.h>
9
10 /*
11 * Utility library.
12 */
13 #include <msg.h>
14 #include <vstream.h>
15 #include <vstring.h>
16
17 /*
18 * Global library.
19 */
20 #include <dsn_mask.h>
21 #include <mail_params.h>
22 #include <record.h>
23 #include <rec_type.h>
24 #include <hfrom_format.h>
25
26 /*
27 * Bounce service.
28 */
29 #include <bounce_service.h>
30 #include <bounce_template.h>
31
32 /*
33 * Testing library.
34 */
35 #include <test_main.h>
36
37 #define TEST_ENCODING "7bit"
38 #define NO_SMTPUTF8 (0)
39 #define TEST_DSN_ENVID "TEST-ENVID"
40 #define TEST_RECIPIENT "test-recipient"
41
42 #define STR(x) vstring_str(x)
43 #define LEN(x) VSTRING_LEN(x)
44
45 /* test_driver - test driver */
46
test_driver(int argc,char ** argv)47 static void test_driver(int argc, char **argv)
48 {
49 BOUNCE_TEMPLATES *bounce_templates;
50 BOUNCE_INFO *bounce_info;
51 VSTRING *message_buf;
52 VSTREAM *message_stream;
53 VSTRING *rec_buf;
54 int rec_type;
55
56 /*
57 * Sanity checks.
58 */
59 if (argc != 4)
60 msg_fatal("usage: %s [options] service queue_name queue_id", argv[0]);
61
62 if (chdir(var_queue_dir) < 0)
63 msg_fatal("chdir %s: %m", var_queue_dir);
64
65 bounce_hfrom_format =
66 hfrom_format_parse(VAR_HFROM_FORMAT, var_hfrom_format);
67
68 /*
69 * Write one message to VSTRING.
70 */
71 message_buf = vstring_alloc(100);
72 if ((message_stream = vstream_memopen(message_buf, O_WRONLY)) == 0)
73 msg_fatal("vstream_memopen O_WRONLY: %m");
74 bounce_templates = bounce_templates_create();
75 bounce_info = bounce_mail_init(argv[1], argv[2], argv[3],
76 TEST_ENCODING, NO_SMTPUTF8, TEST_DSN_ENVID,
77 bounce_templates->failure);
78 if (bounce_header(message_stream, bounce_info, TEST_RECIPIENT,
79 NO_POSTMASTER_COPY) < 0)
80 msg_fatal("bounce_header: %m");
81 if (bounce_diagnostic_log(message_stream, bounce_info,
82 DSN_NOTIFY_OVERRIDE) <= 0)
83 msg_fatal("bounce_diagnostic_log: %m");
84 if (bounce_header_dsn(message_stream, bounce_info) != 0)
85 msg_fatal("bounce_header_dsn: %m");
86 if (bounce_diagnostic_dsn(message_stream, bounce_info,
87 DSN_NOTIFY_OVERRIDE) <= 0)
88 msg_fatal("bounce_diagnostic_dsn: %m");
89 bounce_original(message_stream, bounce_info, DSN_RET_FULL);
90 if (vstream_fclose(message_stream) != 0)
91 msg_fatal("vstream_fclose: %m");
92 bounce_mail_free(bounce_info);
93
94 /*
95 * Render the bounce message in human-readable form.
96 */
97 if ((message_stream = vstream_memopen(message_buf, O_RDONLY)) == 0)
98 msg_fatal("vstream_memopen O_RDONLY: %m");
99 rec_buf = vstring_alloc(100);
100 while ((rec_type = rec_get(message_stream, rec_buf, 0)) > 0) {
101 switch (rec_type) {
102 case REC_TYPE_CONT:
103 vstream_printf("%.*s", (int) LEN(rec_buf), STR(rec_buf));
104 break;
105 case REC_TYPE_NORM:
106 vstream_printf("%.*s\n", (int) LEN(rec_buf), STR(rec_buf));
107 break;
108 default:
109 msg_panic("unexpected message record type %d", rec_type);
110 }
111 vstream_fflush(VSTREAM_OUT);
112 }
113 if (vstream_fclose(message_stream) != 0)
114 msg_fatal("vstream_fclose: %m");
115 vstring_free(rec_buf);
116
117 /*
118 * Clean up.
119 */
120 exit(0);
121 }
122
123 int var_bounce_limit;
124 int var_max_queue_time;
125 int var_delay_warn_time;
126 char *var_notify_classes;
127 char *var_bounce_rcpt;
128 char *var_2bounce_rcpt;
129 char *var_delay_rcpt;
130 char *var_bounce_tmpl;
131 bool var_threaded_bounce;
132 char *var_hfrom_format; /* header_from_format */
133
134 int bounce_hfrom_format;
135
main(int argc,char ** argv)136 int main(int argc, char **argv)
137 {
138 static const CONFIG_INT_TABLE int_table[] = {
139 VAR_BOUNCE_LIMIT, DEF_BOUNCE_LIMIT, &var_bounce_limit, 1, 0,
140 0,
141 };
142 static const CONFIG_TIME_TABLE time_table[] = {
143 VAR_MAX_QUEUE_TIME, DEF_MAX_QUEUE_TIME, &var_max_queue_time, 0, 8640000,
144 VAR_DELAY_WARN_TIME, DEF_DELAY_WARN_TIME, &var_delay_warn_time, 0, 0,
145 0,
146 };
147 static const CONFIG_STR_TABLE str_table[] = {
148 VAR_NOTIFY_CLASSES, DEF_NOTIFY_CLASSES, &var_notify_classes, 0, 0,
149 VAR_BOUNCE_RCPT, DEF_BOUNCE_RCPT, &var_bounce_rcpt, 1, 0,
150 VAR_2BOUNCE_RCPT, DEF_2BOUNCE_RCPT, &var_2bounce_rcpt, 1, 0,
151 VAR_DELAY_RCPT, DEF_DELAY_RCPT, &var_delay_rcpt, 1, 0,
152 VAR_BOUNCE_TMPL, DEF_BOUNCE_TMPL, &var_bounce_tmpl, 0, 0,
153 VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0,
154 0,
155 };
156 static const CONFIG_NBOOL_TABLE nbool_table[] = {
157 VAR_THREADED_BOUNCE, DEF_THREADED_BOUNCE, &var_threaded_bounce,
158 0,
159 };
160
161 test_main(argc, argv, test_driver,
162 CA_TEST_MAIN_INT_TABLE(int_table),
163 CA_TEST_MAIN_STR_TABLE(str_table),
164 CA_TEST_MAIN_TIME_TABLE(time_table),
165 CA_TEST_MAIN_NBOOL_TABLE(nbool_table),
166 0);
167
168 exit(0);
169 }
170