Skip to content
Permalink
Browse files

Fix build on utmpx-only systems, such as FreeBSD.

FreeBSD removed <utmp.h> almost a decade ago, leaving only <utmpx.h>:
freebsd/freebsd@cb38fda

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
  • Loading branch information...
schmonz committed Jul 9, 2019
1 parent 1dd7b07 commit 47baf7859ec511c4939fbf5b44e292bb60485aac
Showing with 65 additions and 23 deletions.
  1. +1 −0 CHANGES
  2. +3 −0 FILES
  3. +9 −2 Makefile
  4. +1 −0 TARGETS
  5. +9 −21 qbiff.c
  6. +24 −0 qtmp.h1
  7. +11 −0 qtmp.h2
  8. +7 −0 tryutmpx.c
@@ -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
3 FILES
@@ -432,3 +432,6 @@ maildir.c
tcp-environ.5
constmap.h
constmap.c
qtmp.h1
qtmp.h2
tryutmpx.c
@@ -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

@@ -385,3 +385,4 @@ forgeries.0
man
setup
check
qtmp.h
30 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;
24 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
11 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
@@ -0,0 +1,7 @@
#include <utmpx.h>

void main()
{
struct utmpx ut;
ut.ut_type = sizeof(ut.ut_line) + sizeof(ut.ut_user);
}

0 comments on commit 47baf78

Please sign in to comment.
You can’t perform that action at this time.