Download raw body.
calendar(1): introduce RECIPIENT_EMAIL
On Mon, 03 Feb 2025 11:53:53 +0100,
Vitaliy Makkoveev <mvs@openbsd.org> wrote:
>
> On Sat, Feb 01, 2025 at 11:18:40PM +0100, Kirill A. Korinsky wrote:
> > tech@
> >
> > Here a patch which introduced a special variable RECIPIENT_EMAIL in
> > calendar(1).
> >
> > By default it sends daily emails to a user and it can be forwarded via
> > ~/.forward to desire destination. But here no way to send calendar's email
> > to other email.
> >
> > My patch introduced a variable RECIPIENT_EMAIL which can be used to override
> > the destination email in calendar file.
> >
> > Feedback? Ok?
> >
>
> Do we need extra checks to be sure `recipient' contains valid email
> address?
>
Good point, thnaks. Right now mallformed email leads to a error:
sendmail: command failed: 501 5.1.3 Recipient address syntax error
which won't be delivered to the user.
Thus, implementing here a custom email validation smeels wrong as well.
The clean solution that I see is implemeting -bv at sendmail.
So, here quite trivial diff for sendmail wrapper, which is followed by
updated version of the diff for calendar.
Index: usr.sbin/smtpd/enqueue.c
===================================================================
RCS file: /home/cvs/src/usr.sbin/smtpd/enqueue.c,v
diff -u -p -r1.126 enqueue.c
--- usr.sbin/smtpd/enqueue.c 21 Nov 2024 13:26:25 -0000 1.126
+++ usr.sbin/smtpd/enqueue.c 3 Feb 2025 12:41:22 -0000
@@ -172,7 +172,7 @@ qp_encoded_write(FILE *fp, char *buf)
int
enqueue(int argc, char *argv[], FILE *ofp)
{
- int i, ch, tflag = 0;
+ int i, ch, tflag = 0, validate_rcpt = 0;
char *fake_from = NULL, *buf = NULL;
struct passwd *pw;
FILE *fp = NULL, *fout;
@@ -220,10 +220,13 @@ enqueue(int argc, char *argv[], FILE *of
case 'V':
msg.dsn_envid = optarg;
break;
+ case 'b':
+ if (optarg[0] == 'v')
+ validate_rcpt = 1;
+ break;
/* all remaining: ignored, sendmail compat */
case 'A':
case 'B':
- case 'b':
case 'E':
case 'e':
case 'i:'
@@ -340,6 +343,9 @@ enqueue(int argc, char *argv[], FILE *of
if (!get_responses(fout, 1))
goto fail;
}
+
+ if (validate_rcpt)
+ exit(EX_OK);
if (!send_line(fout, verbose, "DATA\r\n"))
goto fail;
Index: usr.bin/calendar/calendar.1
===================================================================
RCS file: /home/cvs/src/usr.bin/calendar/calendar.1,v
diff -u -p -r1.44 calendar.1
--- usr.bin/calendar/calendar.1 29 Jan 2019 22:28:30 -0000 1.44
+++ usr.bin/calendar/calendar.1 1 Feb 2025 22:03:35 -0000
@@ -107,6 +107,10 @@ Use
.Dq CALENDAR=
to return to the default (Gregorian).
.Pp
+The
+.Dq RECIPIENT_EMAIL
+variable can be used to specify recipient of daily mails.
+.Pp
To enforce special date calculation mode for Cyrillic calendars
you should specify
.Dq LANG=<local_name>
Index: usr.bin/calendar/io.c
===================================================================
RCS file: /home/cvs/src/usr.bin/calendar/io.c,v
diff -u -p -r1.51 io.c
--- usr.bin/calendar/io.c 7 Dec 2021 14:00:33 -0000 1.51
+++ usr.bin/calendar/io.c 3 Feb 2025 13:45:51 -0000
@@ -51,6 +51,9 @@
#include "calendar.h"
+char *recipient = NULL;
+
+
struct iovec header[] = {
{ "From: ", 6 },
{ NULL, 0 },
@@ -66,11 +69,12 @@ struct iovec header[] = {
void
cal(void)
{
- int ch, l, i, bodun = 0, bodun_maybe = 0, var, printing;
+ int ch, l, i, bodun = 0, bodun_maybe = 0, var, printing, status;
struct event *events, *cur_evt, *ev1, *tmp;
char buf[2048 + 1], *prefix = NULL, *p;
struct match *m;
FILE *fp;
+ pid_t pid = -1;
events = NULL;
cur_evt = NULL;
@@ -123,6 +127,29 @@ cal(void)
if ((prefix = strdup(buf + 6)) == NULL)
err(1, NULL);
continue;
+ } else if (strncmp(buf, "RECIPIENT_EMAIL=", 16) == 0) {
+ free(recipient);
+ if ((recipient = strdup(buf + 16)) == NULL)
+ err(1, NULL);
+
+ switch ((pid = vfork())) {
+ case -1:
+ err(1, "vfork");
+ case 0:
+ close(STDIN_FILENO);
+ close(STDOUT_FILENO);
+ close(STDERR_FILENO);
+ execl(_PATH_SENDMAIL, "sendmail",
+ "-bv", recipient, (char *)NULL);
+ warn(_PATH_SENDMAIL);
+ _exit(1);
+ }
+ if (waitpid(pid, &status, 0) == -1 ||
+ !WIFEXITED(status) ||
+ WEXITSTATUS(status))
+ err(1, "Mallformed recipient email: %s",
+ recipient);
+ continue;
}
/* User defined names for special events */
if ((p = strchr(buf, '='))) {
@@ -408,7 +435,7 @@ closecal(FILE *fp)
}
(void)close(pdes[1]);
execl(_PATH_SENDMAIL, "sendmail", "-i", "-t", "-F",
- "\"Reminder Service\"", (char *)NULL);
+ "\"Reminder Service\"", recipient, (char *)NULL);
warn(_PATH_SENDMAIL);
_exit(1);
}
--
wbr, Kirill
calendar(1): introduce RECIPIENT_EMAIL