/*
* Copyright (C) 2004, 2003, 2004 Mads Martin Joergensen <mmj at mmj.dk>
- * Copyright (C) 2022 Baptiste Daroussin <bapt@FreeBSD.org>
+ * Copyright (C) 2022-2023 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 <sys/types.h>
#include <stdbool.h>
+#include <stdio.h>
+#include "mlmmj.h"
struct mail {
const char *from;
const char *to;
const char *replyto;
+ FILE *fp;
char *map;
size_t size;
char *hdrs;
bool addtohdr;
};
+int newsmtp(struct ml *ml);
int initsmtp(int *sockfd, const char *relayhost, unsigned short port, const char *heloname);
int endsmtp(int *sockfd);
int send_mail(int sockfd, struct mail *mail, int listfd, int ctrlfd, bool bounce);
#include "find_email_adr.h"
#include "gethdrline.h"
#include "utils.h"
+#include "send_mail.h"
+static void
+save_queue(const char *queuefilename, const char *from, const char *to)
+{
+ char *tmpstr;
+ int fd;
+ xasprintf(&tmpstr, "%s.mailfrom", queuefilename);
+ fd = open(tmpstr, O_WRONLY|O_CREAT|O_EXCL|O_SYNC, S_IRUSR|S_IWUSR);
+ if (fd == -1)
+ return;
+ dprintf(fd, "%s", from);
+ close(fd);
+ free(tmpstr);
+ xasprintf(&tmpstr, "%s.recripto", queuefilename);
+ fd = open(tmpstr, O_WRONLY|O_CREAT|O_EXCL|O_SYNC, S_IRUSR|S_IWUSR);
+ if (fd == -1)
+ return;
+ dprintf(fd, "%s", to);
+ close(fd);
+ free(tmpstr);
+}
-void do_probe(struct ml *ml, const char *mlmmjsend, const char *addr)
+void do_probe(struct ml *ml, const char *addr)
{
text *txt;
file_lines_state *fls;
char *probefile;
int fd;
time_t t;
+ struct mail mail;
+ int sockfd;
+ memset(&mail, 0, sizeof(mail));
myaddr = lowercase(addr);
gen_addr_cookie(from, ml, "bounces-probe-", myaddr)
else
if (dprintf(fd, "%ld", (long int)t) < 0)
log_error(LOG_ARGS, "Could not write time in probe");
-
free(probefile);
- exec_or_die(mlmmjsend, "-l", "5", "-L", ml->dir, "-T", myaddr,
- "-F", from, "-m", queuefilename, NULL);
+ mail.to = myaddr;
+ mail.from = from;
+ mail.fp = fopen(queuefilename, "r");
+ sockfd = newsmtp(ml);
+ if (sockfd == -1)
+ exit(EXIT_FAILURE);
+ if (send_mail(sockfd, &mail, ml->fd, ml->ctrlfd, false)) {
+ close(sockfd);
+ save_queue(queuefilename, mail.from, mail.to);
+ exit(EXIT_FAILURE);
+ }
+ fclose(mail.fp);
+ endsmtp(&sockfd);
+ exit(EXIT_SUCCESS);
}
static void print_help(const char *prg)
int opt, dsnbounce = 0;
char *address = NULL, *number = NULL;
const char *thisaddr;
- char *bindir, *mlmmjsend, *a;
+ char *a;
const char *mailname = NULL;
bool probe = false;
bounce_t bret;
struct ml ml;
log_set_name(argv[0]);
-
- CHECKFULLPATH(argv[0]);
ml_init(&ml);
- bindir = mydirname(argv[0]);
- xasprintf(&mlmmjsend, "%s/mlmmj-send", bindir);
- free(bindir);
-
while ((opt = getopt(argc, argv, "hdVL:a:n:m:p")) != -1) {
switch(opt) {
case 'L':
if (probe) {
/* send out a probe */
- do_probe(&ml, mlmmjsend, thisaddr);
+ do_probe(&ml, thisaddr);
/* do_probe() will never return */
exit(EXIT_FAILURE);
}
if (bret == BOUNCE_OK && mailname != NULL)
unlink(mailname);
- free(mlmmjsend);
return (bret == BOUNCE_FAIL ? EXIT_FAILURE : EXIT_SUCCESS);
}
char *relayhost = NULL, *archivefilename = NULL, *tmpstr;
const char *subddirname = NULL;
char listctrl = 0;
- char *probefile, *a;
char *verp = NULL;
char *verpfrom;
char *reply, *smtphelo, *requeuefilename;
switch(listctrl) {
case '1': /* A single mail is to be sent, do nothing */
+ break;
case '5':
+ err(EXIT_FAILURE, "5 is not supported anymore");
break;
case '2': /* Moderators */
if((subfd = openat(ml.ctrlfd, "moderators", O_RDONLY)) < 0) {
}
break;
case '5': /* bounceprobe - handle relayhost local users bouncing*/
- initsmtp(&sockfd, relayhost, smtpport, smtphelo);
- mail.from = bounceaddr;
- if(send_mail(sockfd, &mail, ml.fd, ml.ctrlfd, false)) {
- close(sockfd);
- sockfd = -1;
- /* error, so remove the probefile */
- tmpstr = xstrdup(mail.to);
- a = strchr(tmpstr, '@');
- MY_ASSERT(a);
- *a = '=';
- probefile = concatstr(4, ml.dir, "/bounce/", tmpstr,
- "-probe");
- unlink(probefile);
- free(probefile);
- free(tmpstr);
- } else {
- endsmtp(&sockfd);
- }
break;
case '7':
digest = 1;
/*
* Copyright (C) 2004, 2003, 2004 Mads Martin Joergensen <mmj at mmj.dk>
- * Copyright (C) 2022 Baptiste Daroussin <bapt@FreeBSD.org>
+ * Copyright (C) 2022-2023 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 "log_error.h"
#include "init_sockfd.h"
#include "mlmmj.h"
+#include "strgen.h"
#include "xmalloc.h"
+#include "ctrlvalue.h"
int
initsmtp(int *sockfd, const char *relayhost, unsigned short port, const char *heloname)
log_error(LOG_ARGS, "No body or headers");
return (0);
}
- } else {
+ } else if (mail->fp == NULL) {
if (mail->size == 0 || mail->map == NULL) {
log_error(LOG_ARGS, "No mmap mail");
return (0);
log_error(LOG_ARGS, "Could not write mailbody.\n");
return retval;
}
+ } else if (mail->fp != NULL) {
+ int c, next;
+ bool addhdr = true;
+ while ((c = fgetc(mail->fp)) != EOF) {
+ if (c != '\n') {
+ dprintf(sockfd, "%c", c);
+ continue;
+ }
+ next = fgetc(mail->fp);
+ if (next == '.') {
+ dprintf(sockfd, "\r\n.");
+ }
+ if (addhdr && mail->addtohdr && next == '\n') {
+ dprintf(sockfd, "To: %s\r\n", mail->to);
+ addhdr = false;
+ }
+ ungetc(c, mail->fp);
+ }
} else {
retval = write_mailbody_from_map(sockfd, mail->map, mail->size,
mail->addtohdr ? mail->to : NULL);
return 0;
}
+
+int
+newsmtp(struct ml *ml)
+{
+ int sockfd;
+ char *relayhost, *smtphelo;
+ unsigned short smtpport = ctrlushort(ml->ctrlfd, "smtpport", 25);
+
+ relayhost = ctrlvalue(ml->ctrlfd, "relayhost");
+ if (relayhost == NULL)
+ relayhost = xstrdup(RELAYHOST);
+ smtphelo = ctrlvalue(ml->ctrlfd, "smtphelo");
+ if (smtphelo == NULL)
+ smtphelo = hostnamestr();
+ if (initsmtp(&sockfd, relayhost, smtpport, smtphelo) != 0)
+ return (-1);
+ return (sockfd);
+}
close_text(txt);
}
+ATF_TC_BODY(do_probe)
+{
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, random_int);