nightmaremail

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

commit 0490604cde3d40ca95657a45e35f4d5df641fe1c
parent 8838f4434a7504fd5228084b801a7ecfbb89e1a0
Author: Amitai Schleier <schmonz-web-git@schmonz.com>
Date:   Mon, 12 Aug 2019 11:52:33 -0400

Extract an "instqueue" program from instpackage.

Packagers need a way to make the queue (and only the queue) at
package-install time.

Diffstat:
MCHANGES.md | 1+
MMakefile | 24+++++++++++++++++++-----
MTARGETS | 3+++
Mhier.c | 35++++++++++++++++++++---------------
Mhier.h | 1+
Ainstfiles.c | 203+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Minstpackage.c | 205++-----------------------------------------------------------------------------
Ainstqueue.c | 16++++++++++++++++
8 files changed, 268 insertions(+), 220 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md @@ -1,3 +1,4 @@ +- 20201120 code: add instqueue for packagers, extracted from instpackage. - 20200803 avoid sending CRCRLF in qmail-remote if input contains CRLF - 20200614 remove maildirwatch - 20200614 stop rewriting RCPT TO: domains when they are a CNAME (RFC 5321 5.1) diff --git a/Makefile b/Makefile @@ -725,17 +725,31 @@ instchown.o: \ compile instchown.c strerr.h error.h exit.h hier.h ./compile instchown.c +instfiles.o: \ +compile instfiles.c substdio.h strerr.h env.h error.h fifo.h open.h \ +str.h stralloc.h + ./compile instfiles.c + instpackage: \ -load instpackage.o fifo.o hier.o auto_qmail.o auto_split.o strerr.a \ +load instpackage.o instfiles.o fifo.o hier.o auto_qmail.o auto_split.o strerr.a \ substdio.a open.a error.a env.a str.a fs.a stralloc.a - ./load instpackage fifo.o hier.o auto_qmail.o auto_split.o \ + ./load instpackage instfiles.o fifo.o hier.o auto_qmail.o auto_split.o \ strerr.a substdio.a open.a error.a env.a str.a fs.a stralloc.a instpackage.o: \ -compile instpackage.c substdio.h strerr.h env.h error.h fifo.h open.h \ -readwrite.h exit.h alloc.h str.h stralloc.h hier.h +compile instpackage.c open.h strerr.h hier.h ./compile instpackage.c +instqueue: \ +load instqueue.o instfiles.o fifo.o hier.o auto_qmail.o auto_split.o strerr.a \ +substdio.a open.a error.a env.a str.a fs.a stralloc.a + ./load instqueue instfiles.o fifo.o hier.o auto_qmail.o auto_split.o \ + strerr.a substdio.a open.a error.a env.a str.a fs.a stralloc.a + +instqueue.o: \ +compile instqueue.c open.h strerr.h hier.h + ./compile instqueue.c + instuidgid.o: \ compile instuidgid.c uidgid.h auto_uids.h auto_users.h ./compile instuidgid.c @@ -774,7 +788,7 @@ qmail-pop3d qmail-popup qmail-qmqpc qmail-qmqpd qmail-qmtpd \ qmail-smtpd sendmail tcp-env qmail-newmrh config config-fast \ dnsptr dnsip dnsfq hostname ipmeprint qreceipt qbiff \ forward preline condredirect bouncesaying except maildirmake \ -maildir2mbox install instpackage instchown \ +maildir2mbox install instpackage instqueue instchown \ instcheck home home+df proc proc+df binm1 binm1+df binm2 binm2+df \ binm3 binm3+df diff --git a/TARGETS b/TARGETS @@ -295,8 +295,11 @@ instcheck.o instcheck instchown.o instchown +instfiles.o instpackage.o instpackage +instqueue.o +instqueue instuidgid.o home home+df diff --git a/hier.c b/hier.c @@ -28,6 +28,25 @@ void dsplit(char *base, /* must be under 100 bytes */ } } +void hier_queue() +{ + d(auto_qmail,"queue",auto_uidq,auto_gidq,0750); + d(auto_qmail,"queue/pid",auto_uidq,auto_gidq,0700); + d(auto_qmail,"queue/intd",auto_uidq,auto_gidq,0700); + d(auto_qmail,"queue/todo",auto_uidq,auto_gidq,0750); + d(auto_qmail,"queue/bounce",auto_uids,auto_gidq,0700); + + dsplit("queue/mess",auto_uidq,0750); + dsplit("queue/info",auto_uids,0700); + dsplit("queue/local",auto_uids,0700); + dsplit("queue/remote",auto_uids,0700); + + d(auto_qmail,"queue/lock",auto_uidq,auto_gidq,0750); + z(auto_qmail,"queue/lock/tcpto",1024,auto_uidr,auto_gidq,0644); + z(auto_qmail,"queue/lock/sendmutex",0,auto_uids,auto_gidq,0600); + p(auto_qmail,"queue/lock/trigger",auto_uids,auto_gidq,0622); +} + void hier() { h(auto_qmail,auto_uido,auto_gidq,0755); @@ -49,21 +68,7 @@ void hier() d(auto_qmail,"alias",auto_uida,auto_gidq,02755); - d(auto_qmail,"queue",auto_uidq,auto_gidq,0750); - d(auto_qmail,"queue/pid",auto_uidq,auto_gidq,0700); - d(auto_qmail,"queue/intd",auto_uidq,auto_gidq,0700); - d(auto_qmail,"queue/todo",auto_uidq,auto_gidq,0750); - d(auto_qmail,"queue/bounce",auto_uids,auto_gidq,0700); - - dsplit("queue/mess",auto_uidq,0750); - dsplit("queue/info",auto_uids,0700); - dsplit("queue/local",auto_uids,0700); - dsplit("queue/remote",auto_uids,0700); - - d(auto_qmail,"queue/lock",auto_uidq,auto_gidq,0750); - z(auto_qmail,"queue/lock/tcpto",1024,auto_uidr,auto_gidq,0644); - z(auto_qmail,"queue/lock/sendmutex",0,auto_uids,auto_gidq,0600); - p(auto_qmail,"queue/lock/trigger",auto_uids,auto_gidq,0622); + hier_queue(); c(auto_qmail,"boot","home",auto_uido,auto_gidq,0755); c(auto_qmail,"boot","home+df",auto_uido,auto_gidq,0755); diff --git a/hier.h b/hier.h @@ -9,5 +9,6 @@ extern void p(char *home, char *fifo, uid_t uid, gid_t gid, int mode); extern void c(char *home, char *subdir, char *file, uid_t uid, gid_t gid, int mode); extern void z(char *home, char *file, int len, uid_t uid, gid_t gid, int mode); extern void hier(void); +extern void hier_queue(void); #endif diff --git a/instfiles.c b/instfiles.c @@ -0,0 +1,203 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include "substdio.h" +#include "strerr.h" +#include "env.h" +#include "error.h" +#include "fifo.h" +#include "open.h" +#include "str.h" +#include "stralloc.h" + +#define FATAL "instfiles: fatal: " + +int fdsourcedir = -1; + +static void die_nomem() +{ + strerr_die2sys(111,FATAL,"out of memory"); +} + +static void ddhome(stralloc *dd, char *home) +{ + const char *denv = env_get("DESTDIR"); + if (denv) + if (!stralloc_copys(dd,denv)) die_nomem(); + + if (!stralloc_catb(dd,home,str_len(home))) die_nomem(); + if (!stralloc_0(dd)) die_nomem(); +} + +static int mkdir_p(char *home, int mode) +{ + stralloc parent = { 0 }; + unsigned int sl; + int r = mkdir(home,mode); + if (!r || errno != error_noent) + return r; + + /* try parent first */ + sl = str_rchr(home, '/'); + if (!stralloc_copyb(&parent,home,sl)) die_nomem(); + if (!stralloc_0(&parent)) die_nomem(); + r = mkdir_p(parent.s,mode); + free(parent.s); + if (r && errno != error_exist) + return r; + + return mkdir(home,mode); +} + +void h(char *home, uid_t uid, gid_t gid, int mode) +{ + stralloc dh = { 0 }; + ddhome(&dh, home); + home=dh.s; + if (mkdir_p(home,mode) == -1) + if (errno != error_exist) + strerr_die4sys(111,FATAL,"unable to mkdir ",home,": "); + if (chmod(home,mode) == -1) + strerr_die4sys(111,FATAL,"unable to chmod ",home,": "); + free(dh.s); +} + +void d(char *home, char *subdir, uid_t uid, gid_t gid, int mode) +{ + stralloc dh = { 0 }; + ddhome(&dh, home); + home=dh.s; + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (mkdir(subdir,0700) == -1) + if (errno != error_exist) + strerr_die6sys(111,FATAL,"unable to mkdir ",home,"/",subdir,": "); + if (chmod(subdir,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",subdir,": "); + free(dh.s); +} + +void p(char *home, char *fifo, uid_t uid, gid_t gid, int mode) +{ + stralloc dh = { 0 }; + ddhome(&dh, home); + home=dh.s; + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (fifo_make(fifo,0700) == -1) + if (errno != error_exist) + strerr_die6sys(111,FATAL,"unable to mkfifo ",home,"/",fifo,": "); + if (chmod(fifo,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",fifo,": "); + free(dh.s); +} + +char inbuf[SUBSTDIO_INSIZE]; +char outbuf[SUBSTDIO_OUTSIZE]; +substdio ssin; +substdio ssout; + +void c(char *home, char *subdir, char *file, uid_t uid, gid_t gid, int mode) +{ + int fdin; + int fdout; + stralloc dh = { 0 }; + + if (fchdir(fdsourcedir) == -1) + strerr_die2sys(111,FATAL,"unable to switch back to source directory: "); + + fdin = open_read(file); + if (fdin == -1) { + /* silently ignore missing catman pages */ + if (errno == error_noent && strncmp(subdir, "man/cat", 7) == 0) + return; + strerr_die4sys(111,FATAL,"unable to read ",file,": "); + } + + /* if the user decided to build only dummy catman pages then don't install */ + if (strncmp(subdir, "man/cat", 7) == 0) { + struct stat st; + if (fstat(fdin, &st) != 0) + strerr_die4sys(111,FATAL,"unable to stat ",file,": "); + if (st.st_size == 0) { + close(fdin); + return; + } + } + + ddhome(&dh, home); + home=dh.s; + + substdio_fdbuf(&ssin,read,fdin,inbuf,sizeof(inbuf)); + + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + if (chdir(subdir) == -1) + strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": "); + + fdout = open_trunc(file); + if (fdout == -1) + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + substdio_fdbuf(&ssout,write,fdout,outbuf,sizeof(outbuf)); + + switch(substdio_copy(&ssout,&ssin)) { + case -2: + strerr_die4sys(111,FATAL,"unable to read ",file,": "); + case -3: + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + } + + close(fdin); + if (substdio_flush(&ssout) == -1) + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + if (fsync(fdout) == -1) + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + if (close(fdout) == -1) /* NFS silliness */ + strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); + + if (chmod(file,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod .../",subdir,"/",file,": "); + free(dh.s); +} + +void z(char *home, char *file, int len, uid_t uid, gid_t gid, int mode) +{ + int fdout; + stralloc dh = { 0 }; + + ddhome(&dh, home); + home=dh.s; + if (chdir(home) == -1) + strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); + + fdout = open_trunc(file); + if (fdout == -1) + strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); + substdio_fdbuf(&ssout,write,fdout,outbuf,sizeof(outbuf)); + + while (len-- > 0) + if (substdio_put(&ssout,"",1) == -1) + strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); + + if (substdio_flush(&ssout) == -1) + strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); + if (fsync(fdout) == -1) + strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); + if (close(fdout) == -1) /* NFS silliness */ + strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); + + if (chmod(file,mode) == -1) + strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",file,": "); + free(dh.s); +} + +/* these are ignored, but hier() passes them to h() and friends */ +uid_t auto_uida = -1; +uid_t auto_uido = -1; +uid_t auto_uidq = -1; +uid_t auto_uidr = -1; +uid_t auto_uids = -1; + +gid_t auto_gidq = -1; diff --git a/instpackage.c b/instpackage.c @@ -1,208 +1,13 @@ -#include <sys/stat.h> -#include <sys/types.h> -#include <string.h> -#include <unistd.h> -#include "substdio.h" -#include "strerr.h" -#include "env.h" -#include "error.h" -#include "fifo.h" #include "hier.h" -#include "open.h" -#include "alloc.h" -#include "str.h" -#include "stralloc.h" +#include <sys/stat.h> +#include <stddef.h> +#include "open.h" +#include "strerr.h" #define FATAL "instpackage: fatal: " -int fdsourcedir = -1; - -static void die_nomem() -{ - strerr_die2sys(111,FATAL,"out of memory"); -} - -static void ddhome(stralloc *dd, char *home) -{ - const char *denv = env_get("DESTDIR"); - if (denv) - if (!stralloc_copys(dd,denv)) die_nomem(); - - if (!stralloc_catb(dd,home,str_len(home))) die_nomem(); - if (!stralloc_0(dd)) die_nomem(); -} - -static int mkdir_p(char *home, int mode) -{ - stralloc parent = { 0 }; - unsigned int sl; - int r = mkdir(home,mode); - if (!r || errno != error_noent) - return r; - - /* try parent first */ - sl = str_rchr(home, '/'); - if (!stralloc_copyb(&parent,home,sl)) die_nomem(); - if (!stralloc_0(&parent)) die_nomem(); - r = mkdir_p(parent.s,mode); - alloc_free(parent.s); - if (r && errno != error_exist) - return r; - - return mkdir(home,mode); -} - -void h(char *home, uid_t uid, gid_t gid, int mode) -{ - stralloc dh = { 0 }; - ddhome(&dh, home); - home=dh.s; - if (mkdir_p(home,mode) == -1) - if (errno != error_exist) - strerr_die4sys(111,FATAL,"unable to mkdir ",home,": "); - if (chmod(home,mode) == -1) - strerr_die4sys(111,FATAL,"unable to chmod ",home,": "); - alloc_free(dh.s); -} - -void d(char *home, char *subdir, uid_t uid, gid_t gid, int mode) -{ - stralloc dh = { 0 }; - ddhome(&dh, home); - home=dh.s; - if (chdir(home) == -1) - strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); - if (mkdir(subdir,0700) == -1) - if (errno != error_exist) - strerr_die6sys(111,FATAL,"unable to mkdir ",home,"/",subdir,": "); - if (chmod(subdir,mode) == -1) - strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",subdir,": "); - alloc_free(dh.s); -} - -void p(char *home, char *fifo, uid_t uid, gid_t gid, int mode) -{ - stralloc dh = { 0 }; - ddhome(&dh, home); - home=dh.s; - if (chdir(home) == -1) - strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); - if (fifo_make(fifo,0700) == -1) - if (errno != error_exist) - strerr_die6sys(111,FATAL,"unable to mkfifo ",home,"/",fifo,": "); - if (chmod(fifo,mode) == -1) - strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",fifo,": "); - alloc_free(dh.s); -} - -char inbuf[SUBSTDIO_INSIZE]; -char outbuf[SUBSTDIO_OUTSIZE]; -substdio ssin; -substdio ssout; - -void c(char *home, char *subdir, char *file, uid_t uid, gid_t gid, int mode) -{ - int fdin; - int fdout; - stralloc dh = { 0 }; - - if (fchdir(fdsourcedir) == -1) - strerr_die2sys(111,FATAL,"unable to switch back to source directory: "); - - fdin = open_read(file); - if (fdin == -1) { - /* silently ignore missing catman pages */ - if (errno == error_noent && strncmp(subdir, "man/cat", 7) == 0) - return; - strerr_die4sys(111,FATAL,"unable to read ",file,": "); - } - - /* if the user decided to build only dummy catman pages then don't install */ - if (strncmp(subdir, "man/cat", 7) == 0) { - struct stat st; - if (fstat(fdin, &st) != 0) - strerr_die4sys(111,FATAL,"unable to stat ",file,": "); - if (st.st_size == 0) { - close(fdin); - return; - } - } - - ddhome(&dh, home); - home=dh.s; - - substdio_fdbuf(&ssin,read,fdin,inbuf,sizeof(inbuf)); - - if (chdir(home) == -1) - strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); - if (chdir(subdir) == -1) - strerr_die6sys(111,FATAL,"unable to switch to ",home,"/",subdir,": "); - - fdout = open_trunc(file); - if (fdout == -1) - strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); - substdio_fdbuf(&ssout,write,fdout,outbuf,sizeof(outbuf)); - - switch(substdio_copy(&ssout,&ssin)) { - case -2: - strerr_die4sys(111,FATAL,"unable to read ",file,": "); - case -3: - strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); - } - - close(fdin); - if (substdio_flush(&ssout) == -1) - strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); - if (fsync(fdout) == -1) - strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); - if (close(fdout) == -1) /* NFS silliness */ - strerr_die6sys(111,FATAL,"unable to write .../",subdir,"/",file,": "); - - if (chmod(file,mode) == -1) - strerr_die6sys(111,FATAL,"unable to chmod .../",subdir,"/",file,": "); - alloc_free(dh.s); -} - -void z(char *home, char *file, int len, uid_t uid, gid_t gid, int mode) -{ - int fdout; - stralloc dh = { 0 }; - - ddhome(&dh, home); - home=dh.s; - if (chdir(home) == -1) - strerr_die4sys(111,FATAL,"unable to switch to ",home,": "); - - fdout = open_trunc(file); - if (fdout == -1) - strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); - substdio_fdbuf(&ssout,write,fdout,outbuf,sizeof(outbuf)); - - while (len-- > 0) - if (substdio_put(&ssout,"",1) == -1) - strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); - - if (substdio_flush(&ssout) == -1) - strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); - if (fsync(fdout) == -1) - strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); - if (close(fdout) == -1) /* NFS silliness */ - strerr_die6sys(111,FATAL,"unable to write ",home,"/",file,": "); - - if (chmod(file,mode) == -1) - strerr_die6sys(111,FATAL,"unable to chmod ",home,"/",file,": "); - alloc_free(dh.s); -} - -/* these are ignored, but hier() passes them to h() and friends */ -uid_t auto_uida = -1; -uid_t auto_uido = -1; -uid_t auto_uidq = -1; -uid_t auto_uidr = -1; -uid_t auto_uids = -1; - -gid_t auto_gidq = -1; +extern int fdsourcedir; int main(void) { diff --git a/instqueue.c b/instqueue.c @@ -0,0 +1,16 @@ +#include "hier.h" + +#include <sys/stat.h> +#include <stddef.h> +#include "open.h" +#include "strerr.h" + +int main(void) +{ + if (open_read(".") == -1) + strerr_die1sys(111,"instqueue: fatal: unable to open current directory: "); + + umask(077); + hier_queue(); + return 0; +}