nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 7026ed6493da9c906e69b027da805edd3b0b44d6
parent a5b343fbe3bd347fe5d43277b7b807c4ad0c9066
Author: Ellenor Malik <ellenor@umbrellix.net>
Date:   Fri, 10 Sep 2021 17:20:13 -0700

more scaffolding

Diffstat:
MMakefile | 8++++----
Mconf-qmail | 9++++++---
Ainclude/pronouns.h | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Rqmail-send.service.in -> mxf-send.service.in | 0
Msrc/commands.c | 18++++++++++++++----
Asrc/libmxf/Makefile | 0
Asrc/libmxf/Makefile.common | 0
Asrc/libmxf/include/mxfevent/event.h | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/libmxf/mxfevent/NOTES.mxfevent | 14++++++++++++++
Asrc/libmxf/mxfevent/bsdq.c | 14++++++++++++++
Asrc/libmxf/mxfevent/common.c | 11+++++++++++
Asrc/libmxf/mxfevent/poll.c | 37+++++++++++++++++++++++++++++++++++++
Asrc/mxfmilter/include/milterproto.h | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/qmail-smtpd.c | 3++-
Msrc/str_chr.c | 1+
15 files changed, 310 insertions(+), 12 deletions(-)

diff --git a/Makefile b/Makefile @@ -1425,11 +1425,11 @@ include/qmail.h include/substdio.h include/qsutil.h include/prioq.h include/date include/fmtqfn.h include/readsubdir.h include/direntry.h ./compile src/qmail-send.c -qmail-send.service: \ -qmail-send.service.in conf-qmail - cat qmail-send.service.in \ +mxf-send.service: \ +mxf-send.service.in conf-qmail + cat mxf-send.service.in \ | sed s}QMAILHOME}"`head -n 1 conf-qmail`"}g \ - > qmail-send.service + > mxf-send.service qmail-showctl: \ load src/qmail-showctl.o src/control.o src/open.a src/getln.a src/stralloc.a \ diff --git a/conf-qmail b/conf-qmail @@ -1,7 +1,10 @@ -/var/qmail +/var/net.umbrellix.mail.mxf -This is the qmail home directory. It must be a local directory, not -shared among machines. This is where qmail queues all mail messages. +This is the mxf home directory. It must be a local directory, not +shared among machines*. This is where mxf queues all mail messages. + +* Caveat: Binaries can be shared between machines with identical +operating systems. The queue (except for bounce message contents) is crashproof, if the filesystem guarantees that single-byte writes are atomic and that diff --git a/include/pronouns.h b/include/pronouns.h @@ -0,0 +1,51 @@ +/* + * include/mxf/pronouns.h - replacements for mentions of "he," "him," and "his" in the MXF code + * This file is part of MXF. See doc/LICENCE.mxf. +Copyright 2021 Ellenor et al Bjornsdottir, and the MXF Contributors. All Rights Reserved. +Copyright 1997 disclaimed in 2007 by Professor Daniel Bernstein. + +Your licence to this software is governed under the laws of BC, Canada, except as required by applicable laws where you may reside. + +This is software, and it is NOT Open Source software, +per https://opensource.org/faq#avoid-unapproved-licenses . + +The source is available to you and your assigns provided that you and they follow the terms in doc/LICENCE.mxf. If they are onerous, speak to the Initial Developer(s) and the Contributor(s) and/or their heirs or assigns, and you may be able to obtain special dispensation to use and redistribute the software under other licence terms. + +You should have received a copy of the Umbrellix Softare Licence, or other special licence you may have negotiated, with this programme. + */ + +/* + * Dan Bernstein is from a time and culture where + * the singular epicene pronoun was 'he'. + * + * In MXF, we offer the ability but not the requirement + * to change this to any pronouns you like at compile time. + * We default to singular they, but allow reversion to he + * via C preprocessor command line options. You may also + * opt to use ey, co, thon, or xe. + */ + +#ifndef _WITH_PRONOUNS_H +#define _WITH_PRONOUNS_H + +#ifndef PRONOUN_THEY +#define PRONOUN_THEY "they" +#endif + +#ifndef PRONOUN_THEM +#define PRONOUN_THEM "them" +#endif + +#ifndef PRONOUN_THEIR +#define PRONOUN_THEIR "their" +#endif + +#ifndef PRONOUN_THEIRS +#define PRONOUN_THEIRS "theirs" +#endif + +#ifndef PRONOUN_IS_SINGULAR +#define PRONOUN_IS_PLURAL +#endif + +#endif diff --git a/qmail-send.service.in b/mxf-send.service.in diff --git a/src/commands.c b/src/commands.c @@ -7,14 +7,24 @@ static stralloc cmd = {0}; -int commands(ss,c) -substdio *ss; -struct commands *c; -{ +int commands ( + substdio *ss, + struct commands *c +) { unsigned int i; char *arg; for (;;) { + /* This isn't very optimized for the modern world. + It's basically a spinlock, only protected from + going insane on your CPU by the fact that the + socket is blocking. + + Even if we are only handling one socket in smtpd, + that was 1997. This is 2021. We aren't doing that + anymore. smtpd has to do iauth and, if it's running + on the submission port, it has to do SASL too. + ~ Amelia */ if (!stralloc_copys(&cmd,"")) return -1; for (;;) { diff --git a/src/libmxf/Makefile b/src/libmxf/Makefile diff --git a/src/libmxf/Makefile.common b/src/libmxf/Makefile.common diff --git a/src/libmxf/include/mxfevent/event.h b/src/libmxf/include/mxfevent/event.h @@ -0,0 +1,59 @@ +/* + * libmxf/include/mxfevent/event.h - header for programs relying on mxfevent + * Copyright (C) 2021 Ellenor Bjornsdottir + * All rights reserved. + * + * Permission to use, modify, redistribute, or incorporate this work + * is granted, provided that the terms in doc/LICENCE are followed. + */ + +#ifndef HAS_MXFEVENT_EVENT_H +#define HAS_MXFEVENT_EVENT_H +#include <stddef.h> + +#ifndef SYS_POLL_H +#define BMFLAG(n) (1<<(n-1)) +// only these events/filters are meaningful to us in mxfevent +#define EVENTREAD BMFLAG(1) +#define EVENTWRITE BMFLAG(2) +#define EVENTERR BMFLAG(3) +#define EVENTHUP BMFLAG(4) +#define EVENTNVAL BMFLAG(5) +#else +#define EVENTREAD POLLIN|POLLRDNORM +#define EVENTWRITE POLLOUT|POLLWRNORM +#define EVENTERR POLLERR +#define EVENTHUP POLLHUP +#define EVENTNVAL POLLNVAL +#endif +typedef struct { + unsigned int refs; // References + void *opaque; // pointer to user's opaque +} rc_ptr_t; // XXX: will we ever use this? + +typedef struct { + unsigned int queue; // kq fd; only used by kq, epoll and illumos ports +} mxfpq_t; // this is an opaque that'll be used in rc_ptr_t by mxfpoll + +// mxfpoll() will be conceptually similar to a bastard hybrid +// of kqueue() and ppoll and will be implemented using +// the former or the latter in order if available. +typedef int event_return_t; + +#ifndef SYS_POLL_H +typedef struct { + int fd; // File descriptor, as in struct pollfd + short events; // Events user seeks + short revents; // Events user got +} pollfd_t; // low level structure +typedef unsigned int nfds_t; +#else +typedef struct pollfd pollfd_t; +#endif + +// temporary until we import TAI handling +typedef struct timespec mxftimespec_t; + +extern int mxfpoll (rc_ptr_t *mxfpollqueue, pollfd_t fds[], nfds_t nfds, mxftimespec_t *timeout); + +#endif diff --git a/src/libmxf/mxfevent/NOTES.mxfevent b/src/libmxf/mxfevent/NOTES.mxfevent @@ -0,0 +1,14 @@ + ...:: High level overview +NightmareMail needs an event loop library. There's nothing sufficiently +generic to be used by any kind of networked application. + +Why does NightmareMail need an event loop library? Surely we already +have one in qmail-send.c? + +Well... qmail-send's event loop is a nightmare of selectitude. + + ...:: What should the interface look like? +Probably broadly related to iopause, which Laurent Bercot of Skarnet uses +in his 'skalibs.' Perhaps NightmareMail should be constructed so it can +be linked against libskarnet, or against libmxfevent, with equal +functionality. diff --git a/src/libmxf/mxfevent/bsdq.c b/src/libmxf/mxfevent/bsdq.c @@ -0,0 +1,14 @@ +/* + * libmxf/mxfevent/bsdq.c - kqueue support for the mxfevent interface + * Copyright (C) -2021 Ellenor Bjornsdottir + * All rights reserved. + * + * Permission to use, modify, redistribute, or incorporate this work + * is granted, provided that the terms in doc/LICENCE are followed. + */ + +#include <mxfevent/event.h> + +// This is safe because this file will not be compiled except on BSD. +#include <sys/event.h> + diff --git a/src/libmxf/mxfevent/common.c b/src/libmxf/mxfevent/common.c @@ -0,0 +1,11 @@ +/* + * libmxf/mxfevent/common.c - common code for the mxfevent interface + * Copyright (C) -2021 Ellenor Bjornsdottir + * All rights reserved. + * + * Permission to use, modify, redistribute, or incorporate this work + * is granted, provided that the terms in doc/LICENCE are followed. + */ + +#include <mxfevent/event.h> + diff --git a/src/libmxf/mxfevent/poll.c b/src/libmxf/mxfevent/poll.c @@ -0,0 +1,37 @@ +/* + * libmxf/mxfevent/poll.c - poll support for the mxfevent interface + * Copyright (C) -2021 Ellenor Bjornsdottir + * All rights reserved. + * + * Permission to use, modify, redistribute, or incorporate this work + * is granted, provided that the terms in doc/LICENCE are followed. + */ + +#include <mxfevent/event.h> + +// This is safe because this file will only be compiled on platforms +// that support poll.h. +#include <poll.h> + +// MUST NOT BE NULL PTR! can be 0 refs tho. +int mxfpoll ( + rc_ptr_t *mxfpollqueue, pollfd_t fds[], nfds_t nfds, + mxftimespec_t *timeout +) { + unsigned int *refc, *queue; + int ret = 0; + refc = &((*mxfpollqueue).refs); + mxfpq_t *mxfpq = (mxfpq_t *)(mxfpollqueue->opaque); + queue = &(mxfpq->queue); // Not actually used in the poll() variant + *refc++; // now 1 ref + + if (*refc > 0) return -2; // This queue is already in use. + +#ifdef USING_PPOLL + ret = ppoll((struct pollfd *)fds, nfds, timeout, 0); +#else + ret = poll((struct pollfd *)fds, nfds, (timeout == NULL) ? 0 : ((timeout->tv_sec * 1000)+((timeout->tv_nsec) / 1000 / 1000))); +#endif + *refc--; // back to 0 ref + return ret; +} diff --git a/src/mxfmilter/include/milterproto.h b/src/mxfmilter/include/milterproto.h @@ -0,0 +1,97 @@ +/* src/mxfmilter/include/milterproto.h + * Milter protocol definitions. + * This file was created with reference to publicly available documentation + at http://www.pell.portland.or.us/~orc/Code/postoffice/milter-protocol.html . + * + * Copyright 2021 Ellenor Bjornsdottir ellenor@umbrellix.net + * All Rights Reserved. + * Unlike the rest of the MXF distribution, + * Permission to use, redistribute, evaluate, or modify this work is granted + provided the above copyright notice, this permission notice, and the + following warranty notice are retained. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + THE POSSIBILITY OF SUCH DAMAGE. + * + * As a special exception, the warranty notice above may be reproduced in + regular sentence case to ease readability. + */ + +#ifndef _WITH_MXFMILTER_MILTERPROTO_H +#define _WITH_MXFMILTER_MILTERPROTO_H + +/* Yes, I'm really writing my own Milter protocol library. Why? + None are license compatible with the USL, under which MXF is + released. The final product of this project will be a + "miltersleeve" for mxf-local, mxf-remote and mxf-qmtpc, + written in C and released under the USL, using this library. */ + +// From-MTA + +#define MTA_ABORT 'A' +#define MTA_BODYCHUNK 'B' +#define MTA_CLIENT 'C' +#define MTA_SMMACROS 'D' // {CMHR}nameNULvalueNULnameNULvalueNUL +#define MTA_ENDBODY 'E' +#define MTA_HELO 'H' +#define MTA_HEADER 'L' // nameNULvalueNUL +#define MTA_ENDHDR 'N' +#define MTA_MAILFROM 'M' // senderNULesmtparg...NUL +#define MTA_RCPTTO 'R' // recipientNULesmtparg...NUL +#define MTA_OPTNEG 'O' // uint32s: version, actions, protocol +#define MTA_QUIT 'Q' + +// From Filter + +#define FILTER_ADDRCPT '+' // rcptNUL +#define FILTER_DELRCPT '-' // rcptNUL +#define FILTER_ACCEPT 'a' +#define FILTER_TACCEPT 'c' +#define FILTER_REPBODY 'b' // body +#define FILTER_DISCARD 'd' +#define FILTER_ADDHDR 'h' // nameNULvalueNUL +#define FILTER_CHGHDR 'm' // unti32 idx, nameNULvalueNUL +#define FILTER_PROGRESS 'p' // still making progress +#define FILTER_40INE 'q' // reasonNUL +#define FILTER_FAILD 'r' // D-type failure +#define FILTER_FAILZ 't' // Z-type failure +#define FILTER_FREPLY 'y' // smtpcode[3] textNUL +#define FILTER_OPTNEG MTA_OPTNEG + +// Actions + +#define ACTION_ 0x01 +#define ACTION_ 0x02 +#define ACTION_ 0x04 +#define ACTION_ 0x08 +#define ACTION_ 0x10 +#define ACTION_ 0x20 + +// Skips + +#define SKIP_CONNECT 0x01 +#define SKIP_HELO 0x02 +#define SKIP_MAILFROM 0x04 +#define SKIP_RCPTTO 0x08 +#define SKIP_BODY 0x10 +#define SKIP_HEADER 0x20 +#define SKIP_ENDHDR 0x40 + +// Structure + +typedef struct { + uint32_t length; // subtract 1 for the length of the str pointed to in data + char cmd; + void *data; // treat as chars in practice +} miltercommand; + +#endif diff --git a/src/qmail-smtpd.c b/src/qmail-smtpd.c @@ -64,7 +64,7 @@ void smtp_greet(code) char *code; } void smtp_help(arg) char *arg; { - out("214 NightmareMail - the Falsix Mail eXchanger Service home page: <https://github.com./SystemLeningrad/fmxs> FMXS is based on notqmail. notqmail home page: <https://notqmail.org>\r\n"); + out("214 NightmareMail home page: <https://github.com./SystemLeningrad/mxf> MXF is based on notqmail. notqmail home page: <https://notqmail.org>\r\n"); } void smtp_quit(arg) char *arg; { @@ -300,6 +300,7 @@ int *hops; flaginheader = 1; pos = 0; flagmaybex = flagmaybey = flagmaybez = 1; for (;;) { + /* This isn't very optimized -- Amelia B */ substdio_get(&ssin,&ch,1); if (flaginheader) { if (pos < 9) { diff --git a/src/str_chr.c b/src/str_chr.c @@ -8,6 +8,7 @@ unsigned int str_chr(char *s, int c) ch = c; t = s; for (;;) { + // Loop unrolling? Smart Bernstein. if (!*t) break; if (*t == ch) break; ++t; if (!*t) break; if (*t == ch) break; ++t; if (!*t) break; if (*t == ch) break; ++t;