* Copyright (C) 2004 Mads Martin Joergensen <mmj at mmj.dk>
* Copyright (C) 2007 Morten K. Poulsen <morten at afdelingp.dk>
* Copyright (C) 2011 Ben Schmidt <mail_ben_schmidt at yahoo.com.au>
- * Copyright (C) 2023 Baptiste Daroussin <bapt@FreeBSD.org>
+ * Copyright (C) 2023-2025 Baptiste Daroussin <bapt@FreeBSD.org>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
#include "mlmmj.h"
#include "unistr.h"
#include "xstring.h"
+#include "do_all_the_voodoo_here.h"
struct substitution {
char *token;
char truncate;
char *line;
size_t linecap;
+ char *formatted_str;
+ void *data;
};
return (s);
}
+file_lines_state *
+init_file_lines_data(int fd, char truncate, void *data)
+{
+ file_lines_state *s;
+
+ s = init_file_lines_fd(fd, truncate);
+ if (s == NULL)
+ return (NULL);
+ s->data = data;
+ return (s);
+}
void rewind_file_lines(void *state)
{
return s->line;
}
+const char *
+get_msgid_line(void *state)
+{
+ file_lines_state *s = (file_lines_state *)state;
+ const char *id = get_file_line(state);
+ if (id == NULL)
+ return (NULL);
+ if (s->data == NULL) {
+ return (id);
+ }
+ struct ml *m = (struct ml *)s->data;
+ struct mailhdr readhdrs[] = {
+ { "Message-ID", 0, NULL },
+ { NULL, 0, NULL }
+ };
+ int archive_fd = openat(m->fd, "archive", O_DIRECTORY|O_RDONLY);
+ if (archive_fd == -1)
+ return (id);
+ int msgfd = openat(archive_fd, id, O_RDONLY);
+ close(archive_fd);
+ if (msgfd == -1)
+ return (id);
+ FILE *f = fdopen(msgfd, "r");
+ scan_headers(f, readhdrs, NULL, NULL);
+ fclose(f);
+ if (readhdrs[0].valuecount == 0)
+ return (id);
+ free(s->formatted_str);
+ xasprintf(&s->formatted_str, "%s, %s%s",
+ id, readhdrs[0].token, readhdrs[0].values[0]);
+ return (s->formatted_str);
+}
+
void finish_file_lines(file_lines_state *s)
{
if (s == NULL) return;
- if (s->line != NULL) free(s->line);
+ free(s->line);
+ free(s->formatted_str);
if (s->fp != NULL) fclose(s->fp);
if (s->filename != NULL) free(s->filename);
free(s);
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
+#include <signal.h>
#include "atf-c/macros.h"
#include "atf-c/utils.h"
ATF_TC_WITHOUT_HEAD(gethdrline);
ATF_TC_WITHOUT_HEAD(readlf);
ATF_TC_WITHOUT_HEAD(mod_get_addr_type);
+ATF_TC_WITHOUT_HEAD(send_probe_no_probefile);
+ATF_TC_WITHOUT_HEAD(send_probe_arobase);
ATF_TC_WITHOUT_HEAD(send_probe);
+ATF_TC_WITHOUT_HEAD(send_probe_archive);
ATF_TC_WITHOUT_HEAD(parse_content_type);
ATF_TC_WITHOUT_HEAD(find_in_list);
ATF_TC_WITHOUT_HEAD(do_access);
atf_utils_wait(p, 1, "", "");
}
-ATF_TC_BODY(send_probe, tc)
+ATF_TC_BODY(send_probe_no_probefile, tc)
{
init_ml(true);
struct ml ml;
atf_utils_cat_file("mailout.txt", "");
atf_tc_fail("invalid file");
}
+}
- p = atf_utils_fork();
+ATF_TC_BODY(send_probe_arobase, tc)
+{
+ init_ml(true);
+ struct ml ml;
+ ml_init(&ml);
+ ml.dir = "list";
+ ml_open(&ml, false);
+ setup_listtext(tc);
+ atf_utils_create_file("list/control/smtpport", "25678");
+ atf_utils_create_file("list/control/smtphelo", "heloname");
+ int smtppipe[2];
+ ATF_REQUIRE(socketpair(AF_UNIX, SOCK_STREAM, 0, smtppipe) >= 0);
+ pid_t p = atf_utils_fork();
if (p == 0) {
if (send_probe(&ml, "bapt@freebsd.org"))
exit(0);
exit(1);
}
atf_utils_wait(p, 1, "", "");
+}
- atf_utils_create_file("list/bounce/bapt=freebsd.org", "1234:blabla\n");
- p2 = single_mail_reception(smtppipe[1]);
+ATF_TC_BODY(send_probe, tc)
+{
+ init_ml(true);
+ struct ml ml;
+ ml_init(&ml);
+ ml.dir = "list";
+ ml_open(&ml, false);
+ setup_listtext(tc);
+ atf_utils_create_file("list/control/smtpport", "25678");
+ atf_utils_create_file("list/control/smtphelo", "heloname");
+ int smtppipe[2];
+ ATF_REQUIRE(socketpair(AF_UNIX, SOCK_STREAM, 0, smtppipe) >= 0);
+ pid_t p2 = single_mail_reception(smtppipe[1]);
atf_utils_readline(smtppipe[0]);
- p = atf_utils_fork();
+
+ atf_utils_create_file("list/bounce/bapt=freebsd.org", "1234:blabla\n32:qftgd\n");
+ pid_t p = atf_utils_fork();
+ if (p == 0) {
+ if (send_probe(&ml, "bapt=freebsd.org"))
+ exit(0);
+ exit(1);
+ }
+ atf_utils_wait(p2, 0, "save:mailout.txt", "");
+ atf_utils_wait(p, 0, "", "");
+
+ if (!atf_utils_grep_file("1234\r", "mailout.txt")) {
+ atf_utils_cat_file("mailout.txt", ">");
+ atf_tc_fail("invalid mail sent");
+ }
+}
+
+ATF_TC_BODY(send_probe_archive, tc)
+{
+ init_ml(true);
+ struct ml ml;
+ ml_init(&ml);
+ ml.dir = "list";
+ ml_open(&ml, false);
+ setup_listtext(tc);
+ atf_utils_create_file("list/control/smtpport", "25678");
+ atf_utils_create_file("list/control/smtphelo", "heloname");
+ int smtppipe[2];
+ ATF_REQUIRE(socketpair(AF_UNIX, SOCK_STREAM, 0, smtppipe) >= 0);
+ pid_t p2 = single_mail_reception(smtppipe[1]);
+ atf_utils_readline(smtppipe[0]);
+
+ atf_utils_create_file("list/bounce/bapt=freebsd.org", "1234:blabla\n21:hey\n32:ertt\n");
+ atf_utils_create_file("list/archive/1234", "From: bob@test\nMessage-ID: <msgid>\nX-None: bla\n\nContent\n");
+ atf_utils_create_file("list/archive/21", "From: bob@test\nMessage-ID: <msgid2>\nX-None: bla\n\nContent\n");
+ pid_t p = atf_utils_fork();
if (p == 0) {
if (send_probe(&ml, "bapt=freebsd.org"))
exit(0);
}
atf_utils_wait(p2, 0, "save:mailout.txt", "");
atf_utils_wait(p, 0, "", "");
- if (!atf_utils_grep_file("1234", "mailout.txt")) {
+
+ if (!atf_utils_grep_file("- 1234, Message-ID: <msgid>\r", "mailout.txt")) {
+ atf_utils_cat_file("mailout.txt", ">");
+ atf_tc_fail("invalid mail sent");
+ }
+ if (!atf_utils_grep_file("- 21, Message-ID: <msgid2>\r", "mailout.txt")) {
+ atf_utils_cat_file("mailout.txt", ">");
+ atf_tc_fail("invalid mail sent");
+ }
+ if (!atf_utils_grep_file("- 32\r", "mailout.txt")) {
atf_utils_cat_file("mailout.txt", ">");
atf_tc_fail("invalid mail sent");
}
ATF_TP_ADD_TC(tp, gethdrline);
ATF_TP_ADD_TC(tp, readlf);
ATF_TP_ADD_TC(tp, mod_get_addr_type);
+ ATF_TP_ADD_TC(tp, send_probe_no_probefile);
+ ATF_TP_ADD_TC(tp, send_probe_arobase);
ATF_TP_ADD_TC(tp, send_probe);
+ ATF_TP_ADD_TC(tp, send_probe_archive);
ATF_TP_ADD_TC(tp, parse_content_type);
ATF_TP_ADD_TC(tp, find_in_list);
ATF_TP_ADD_TC(tp, do_access);