Download raw body.
mail(1) patches (UPDATE)
Yesterday I ran into a problem that I didn't remember, that under Linux
gethostname() returns only the hostname. This means that the diff below
as well as the second from the three versions I posted before, since the
idea was to make them portable, are useless.
So, to generate Message-ID and Date headers, OpenSMTP uses "hand
written" functions. Using libc (strftime()) wasn't convenient in this
case because of OpenBSD limitation with locales. Is detecting UTF-8
characters a different case in this matter? This is what I was
suggested to use instead of my hand written UTF-8 parser:
https://marc.info/?l=openbsd-tech&m=169530140424607&w=2
But mblen(3) also depends on locales. So far, at least under Linux,
using mblen(3) I got the same behavior that under OpenBSD but given my
short experience as a C programmer, hence my limited knowledge of the
"context", contrary to my hand written function which I'm sure is 100%
portable and do NOT depend on locales, I'm not sure to which extent I
can trust on the "portability" of the code using mblen(3).
At least, this is how things look from my ignorant point of view.
Years ago I used to write web applications in PHP for my clients. I
didn't use already written functions, I wrote my own code, trying to use
the most basics. To filter user input I wrote my own regular
expressions. This way my applications were secure, portable and *I
didn't have to rewrite them for each new version of PHP*. I understand
that this worked for me because I worked alone, and that PHP is not C,
but the analogy is still valid to some extent.
>
>
> Index: extern.h
> ===================================================================
> RCS file: /cvs/src/usr.bin/mail/extern.h,v
> diff -u -p -r1.30 extern.h
> --- extern.h 21 May 2024 05:00:48 -0000 1.30
> +++ extern.h 6 Aug 2024 06:51:15 -0000
> @@ -176,6 +176,7 @@ void mesedit(FILE *, int);
> void mespipe(FILE *, char *);
> int messize(void *);
> int metamess(int, int);
> +const char* month(int num);
> int more(void *);
> int newfileinfo(int);
> int next(void *);
> @@ -253,7 +254,9 @@ void vfree(char *);
> int visual(void *);
> int wait_child(pid_t);
> int wait_command(int);
> +const char* wday(int num);
> int writeback(FILE *);
> +const char* zone(int num);
>
> extern char *__progname;
> extern char *tmpdir;
> Index: send.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/mail/send.c,v
> diff -u -p -r1.26 send.c
> --- send.c 8 Mar 2023 04:43:11 -0000 1.26
> +++ send.c 6 Aug 2024 06:51:15 -0000
> @@ -516,15 +516,28 @@ puthead(struct header *hp, FILE *fo, int
> {
> int gotcha;
> char *from;
> + time_t t = time(NULL);
> + struct tm lt = *localtime(&t);
> + char host[1024];
> + int h = gethostname(host, 1023);
>
> gotcha = 0;
> from = hp->h_from ? hp->h_from : value("from");
> if (from != NULL)
> fprintf(fo, "From: %s\n", from), gotcha++;
> + if (fo != stdout)
> + fprintf(fo, "Date: %s, %d %s %d %02d:%02d:%02d %s\n",
> + wday(lt.tm_wday), lt.tm_mday, month(lt.tm_mon),
> + lt.tm_year + 1900, lt.tm_hour, lt.tm_min, lt.tm_sec,
> + zone(lt.tm_gmtoff)), gotcha++;
> if (hp->h_to != NULL && w & GTO)
> fmt("To:", hp->h_to, fo, w&GCOMMA), gotcha++;
> if (hp->h_subject != NULL && w & GSUBJECT)
> fprintf(fo, "Subject: %s\n", hp->h_subject), gotcha++;
> + if (fo != stdout && h == 0)
> + fprintf(fo, "Message-ID: <%d%02d%02d.%02d%02d%02d@%s>\n",
> + lt.tm_year + 1900, lt.tm_mon + 1, lt.tm_mday, lt.tm_hour,
> + lt.tm_min, lt.tm_sec, host), gotcha++;
> if (hp->h_cc != NULL && w & GCC)
> fmt("Cc:", hp->h_cc, fo, w&GCOMMA), gotcha++;
> if (hp->h_bcc != NULL && w & GBCC)
> Index: util.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/mail/util.c,v
> diff -u -p -r1.2 util.c
> --- util.c 26 Dec 2022 19:16:01 -0000 1.2
> +++ util.c 6 Aug 2024 06:51:15 -0000
> @@ -641,3 +641,34 @@ clearnew(void)
> }
> }
> }
> +
> +const char*
> +wday(int num)
> +{
> + const char *week[] = {"Sun", "Mon", "Tue", "Wed", "Thu",
> + "Fri", "Sat"};
> + return(week[num]);
> +}
> +
> +const char*
> +month(int num)
> +{
> + const char *month[] = {"Jan","Feb","Mar","Apr","May","Jun",
> + "Jul","Aug","Sep","Oct","Nov","Dec"};
> + return(month[num]);
> +}
> +
> +const char*
> +zone(int num)
> +{
> + static char buf[6];
> + size_t r;
> +
> + r = snprintf(buf, sizeof(buf), "%c%02d%02d", num >= 0 ? '+' : '-',
> + abs((int)num / 3600), abs((int)num % 3600) / 60);
> +
> + if (r < 0 || r >= sizeof(buf))
> + errx(1, "zone: snprintf");
> +
> + return(buf);
> +}
>
--
Walter
mail(1) patches (UPDATE)