commit 47baf7859ec511c4939fbf5b44e292bb60485aac
parent 1dd7b07f688d0fa38353914d2a2c4d4393abd430
Author: Amitai Schleier <schmonz-web-git@schmonz.com>
Date: Tue, 9 Jul 2019 07:17:00 -0400
Fix build on utmpx-only systems, such as FreeBSD.
FreeBSD removed <utmp.h> almost a decade ago, leaving only <utmpx.h>:
https://github.com/freebsd/freebsd/commit/cb38fdae7c004eec078edf577e1819ce9760aecb
With this change, on a system...
- with <utmpx.h> but no <utmp.h>: build proceeds past qbiff.c
- with <utmpx.h> and <utmp.h>: build chooses <utmpx.h>
- with no <utmpx.h>: no change in behavior
Supports goals: being easily packaged by OS integrators
Broaches non-goals: none known
Risks: may run qbiff incorrectly on a system with broken utmpx implementation
Diffstat:
8 files changed, 65 insertions(+), 23 deletions(-)
diff --git a/CHANGES b/CHANGES
@@ -1,3 +1,4 @@
+20190715 code: detect and prefer utmpx where available.
20190708 code: use DESTDIR environment variable as root directory in install.
20071130 version: netqmail 1.06
20071130 legal: qmail-1.03 is now in the public domain
diff --git a/FILES b/FILES
@@ -432,3 +432,6 @@ maildir.c
tcp-environ.5
constmap.h
constmap.c
+qtmp.h1
+qtmp.h2
+tryutmpx.c
diff --git a/Makefile b/Makefile
@@ -1073,7 +1073,7 @@ qbiff.1
qbiff.o: \
compile qbiff.c readwrite.h stralloc.h gen_alloc.h substdio.h subfd.h \
-substdio.h open.h byte.h str.h headerbody.h hfield.h env.h exit.h
+substdio.h open.h byte.h str.h headerbody.h hfield.h env.h exit.h qtmp.h
./compile qbiff.c
qmail-clean: \
@@ -1674,6 +1674,12 @@ compile qsutil.c stralloc.h gen_alloc.h readwrite.h substdio.h \
qsutil.h
./compile qsutil.c
+qtmp.h: \
+tryutmpx.c compile load qtmp.h1 qtmp.h2
+ ( ( ./compile tryutmpx.c && ./load tryutmpx ) >/dev/null 2>&1 \
+ && cat qtmp.h2 || cat qtmp.h1 ) > qtmp.h
+ rm -f tryutmpx.o tryutmpx
+
quote.o: \
compile quote.c stralloc.h gen_alloc.h str.h quote.h
./compile quote.c
@@ -1829,7 +1835,8 @@ date822fmt.h date822fmt.c dns.h dns.c trylsock.c tryrsolv.c ip.h ip.c \
ipalloc.h ipalloc.c select.h1 select.h2 trysysel.c ndelay.h ndelay.c \
ndelay_off.c direntry.3 direntry.h1 direntry.h2 trydrent.c prot.h \
prot.c chkshsgr.c warn-shsgr tryshsgr.c ipme.h ipme.c trysalen.c \
-maildir.5 maildir.h maildir.c tcp-environ.5 constmap.h constmap.c
+maildir.5 maildir.h maildir.c tcp-environ.5 constmap.h constmap.c \
+qtmp.h1 qtmp.h2 tryutmpx.c
shar -m `cat FILES` > shar
chmod 400 shar
diff --git a/TARGETS b/TARGETS
@@ -385,3 +385,4 @@ forgeries.0
man
setup
check
+qtmp.h
diff --git a/qbiff.c b/qbiff.c
@@ -1,13 +1,6 @@
#include <sys/types.h>
#include <sys/stat.h>
-#include <utmp.h>
-#ifndef UTMP_FILE
-#ifdef _PATH_UTMP
-#define UTMP_FILE _PATH_UTMP
-#else
-#define UTMP_FILE "/etc/utmp"
-#endif
-#endif
+#include "qtmp.h"
#include "readwrite.h"
#include "stralloc.h"
#include "substdio.h"
@@ -20,15 +13,12 @@
#include "env.h"
#include "exit.h"
-substdio ssutmp;
-char bufutmp[sizeof(struct utmp) * 16];
-int fdutmp;
substdio sstty;
char buftty[1024];
int fdtty;
-struct utmp ut;
-char line[sizeof(ut.ut_line) + 1];
+UTMP_INIT;
+char line[sizeof(ut->ut_line) + 1];
stralloc woof = {0};
stralloc tofrom = {0};
stralloc text = {0};
@@ -63,7 +53,7 @@ void main()
if (!(user = env_get("USER"))) _exit(0);
if (!(sender = env_get("SENDER"))) _exit(0);
if (!(userext = env_get("LOCAL"))) _exit(0);
- if (str_len(user) > sizeof(ut.ut_name)) _exit(0);
+ if (str_len(user) > sizeof(ut->UTMP_USER)) _exit(0);
if (!stralloc_copys(&tofrom,"*** TO <")) _exit(0);
if (!stralloc_cats(&tofrom,userext)) _exit(0);
@@ -88,15 +78,13 @@ void main()
if (!stralloc_cat(&woof,&text)) _exit(0);
if (!stralloc_cats(&woof,"\015\n")) _exit(0);
- fdutmp = open_read(UTMP_FILE);
- if (fdutmp == -1) _exit(0);
- substdio_fdbuf(&ssutmp,read,fdutmp,bufutmp,sizeof(bufutmp));
+ UTMP_OPEN;
- while (substdio_get(&ssutmp,&ut,sizeof(ut)) == sizeof(ut))
- if (!str_diffn(ut.ut_name,user,sizeof(ut.ut_name)))
+ while (UTMP_READ_MORE)
+ if (UTMP_TYPE_MATCHES && !str_diffn(ut->UTMP_USER,user,sizeof(ut->UTMP_USER)))
{
- byte_copy(line,sizeof(ut.ut_line),ut.ut_line);
- line[sizeof(ut.ut_line)] = 0;
+ byte_copy(line,sizeof(ut->ut_line),ut->ut_line);
+ line[sizeof(ut->ut_line)] = 0;
if (line[0] == '/') continue;
if (!line[0]) continue;
if (line[str_chr(line,'.')]) continue;
diff --git a/qtmp.h1 b/qtmp.h1
@@ -0,0 +1,24 @@
+#ifndef QTMP_H
+#define QTMP_H
+
+#include <utmp.h>
+#ifndef UTMP_FILE
+#ifdef _PATH_UTMP
+#define UTMP_FILE _PATH_UTMP
+#else
+#define UTMP_FILE "/etc/utmp"
+#endif
+#endif
+#define UTMP_INIT \
+ struct utmp utm; \
+ struct utmp *ut = &utm;
+ substdio ssutmp; \
+ char bufutmp[sizeof(struct utmp) * 16]
+#define UTMP_USER ut_name
+#define UTMP_OPEN \
+ if (open_read(UTMP_FILE) == -1) _exit(0); \
+ substdio_fdbuf(&ssutmp,read,fdutmp,bufutmp,sizeof(bufutmp))
+#define UTMP_READ_MORE (substdio_get(&ssutmp,ut,sizeof(utm)) == sizeof(utm))
+#define UTMP_TYPE_MATCHES 1
+
+#endif
diff --git a/qtmp.h2 b/qtmp.h2
@@ -0,0 +1,11 @@
+#ifndef QTMP_H
+#define QTMP_H
+
+#include <utmpx.h>
+#define UTMP_INIT struct utmpx *ut
+#define UTMP_USER ut_user
+#define UTMP_OPEN
+#define UTMP_READ_MORE (ut = getutxent())
+#define UTMP_TYPE_MATCHES (ut->ut_type == USER_PROCESS)
+
+#endif
diff --git a/tryutmpx.c b/tryutmpx.c
@@ -0,0 +1,7 @@
+#include <utmpx.h>
+
+void main()
+{
+ struct utmpx ut;
+ ut.ut_type = sizeof(ut.ut_line) + sizeof(ut.ut_user);
+}