Official Patch #2 for Mush 7.1

Greg A. Woods woods at eci386.uucp
Wed Jul 18 12:15:43 AEST 1990


In article <10491 at ogicse.ogc.edu> schaefer at ogicse.cse.ogi.edu (Barton E. Schaefer) writes:
> This is Official Patch #2 for Mush 7.1.
>[....]
>     Handling of "corrupted" spool mailboxes has been improved.  The
>     size of the spool file is now correctly recorded on new mail checks,
>     which should reduce the frequency of corruption reports on systems
>     that rely on DOT_LOCKing.

Unfortunately the code for DOT_LOCKing is still very closely tied to
either BSD, or SysVr3.0+ (i.e SVID vol. 3).  It will not work on
earlier versions of SysV, i.e. those described by SVID vol. 1.

According to the SVID vol. 1, setuid(BA_OS), there is no
"saved-set-group-ID" capability in SysV.  This means that either mush
is made setuid root, or another locking mechanism is found.  Our 3b1's
(which run a bastardized version of SysVr2.1) also have smail2.5 and
lmail2.6 installed, and since lmail2.6 uses a similar (and compatible)
scheme to DOT_LOCKing, I've decided to write a pair of helper
programmes which can be exec()'ed to lock and unlock the mailbox,
instead of changing the locking scheme.

I'll post these here, instead of just mailing them off to Bart for
inclusion in the next patch.  I do so in order to allow other SysVr2
sites to get running safely as soon as possible, as well as to solicit
comment on other possible solutions (I think these are far from being
the most desirable, or secure, solution).

I'm also considering adding a couple of locking enhancements to lmail,
specifically also have it lockf() the file if lockf() is available, and
perhaps have it set the modes on mailboxes such that mandatory locking
(if available) is enforced by lockf() on all read()'s and write()'s.

Anyway, here it is.  Note that a patch for "Makefile" is also included.
Makefile was derived directly from makefile.sys.v, as the patch
indicates.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  Patch.sVr2 dolock.c undolock.c
# Wrapped by woods at gate.UUCP on Tue Jul 17 22:05:04 1990
PATH=/bin:/usr/bin:/usr/lbin ; export PATH
if test -f 'Patch.sVr2' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Patch.sVr2'\"
else
echo shar: Extracting \"'Patch.sVr2'\" \(6913 characters\)
sed "s/^X//" >'Patch.sVr2' <<'END_OF_FILE'
XIndex: Makefile
X*** makefile.sys.v	Sat May 12 22:16:31 1990
X--- Makefile	Tue Jul 17 20:31:43 1990
X***************
X*** 27,33
X  
X  # IRIX 3.2 systems (SGI Iris workstations) should add -DDIRECTORY to CFLAGS
X  
X! CFLAGS= 	-O -DSYSV -DUSG -DCURSES -DREGCMP -DSIGRET=void
X  LDFLAGS=
X  LIBS= 		-lcurses -lPW
X  OTHERLIBS=
X
X--- 27,33 -----
X  
X  # IRIX 3.2 systems (SGI Iris workstations) should add -DDIRECTORY to CFLAGS
X  
X! CFLAGS= 	-O -DSYSV -DSYSVR2 -DUSG -DCURSES -DREGCMP -DSIGRET=int -DDIRECTORY -DSMAIL
X  LDFLAGS=
X  LIBS= 		-lcurses -lPW -ldirent -lmalloc
X  OTHERLIBS=
X***************
X*** 29,35
X  
X  CFLAGS= 	-O -DSYSV -DUSG -DCURSES -DREGCMP -DSIGRET=void
X  LDFLAGS=
X! LIBS= 		-lcurses -lPW
X  OTHERLIBS=
X  # Use some variant of this one if you #define MMDF in config.h
X  #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a
X
X--- 29,35 -----
X  
X  CFLAGS= 	-O -DSYSV -DSYSVR2 -DUSG -DCURSES -DREGCMP -DSIGRET=int -DDIRECTORY -DSMAIL
X  LDFLAGS=
X! LIBS= 		-lcurses -lPW -ldirent -lmalloc
X  OTHERLIBS=
X  # Use some variant of this one if you #define MMDF in config.h
X  #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a
X***************
X*** 35,40
X  #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a
X  PROG=		mush
X  
X  $(PROG): $(OBJS1) $(OBJS2)
X  	@echo loading...
X  	@$(CC) $(LDFLAGS) $(OBJS1) $(OBJS2) -o $(PROG) $(LIBS) $(OTHERLIBS)
X
X--- 35,44 -----
X  #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a
X  PROG=		mush
X  
X+ #if SYSVR2
X+ all: $(PROG) dolock undolock
X+ #endif SYSVR2
X+ 
X  $(PROG): $(OBJS1) $(OBJS2)
X  	$(CC) $(LDFLAGS) $(OBJS1) $(OBJS2) -o $(PROG) $(LIBS) $(OTHERLIBS)
X  
X***************
X*** 36,43
X  PROG=		mush
X  
X  $(PROG): $(OBJS1) $(OBJS2)
X! 	@echo loading...
X! 	@$(CC) $(LDFLAGS) $(OBJS1) $(OBJS2) -o $(PROG) $(LIBS) $(OTHERLIBS)
X  
X  $(OBJS1): $(HDRS1) $(HDRS2)
X  $(OBJS2): $(HDRS1) $(HDRS2) $(HDRS3)
X
X--- 40,46 -----
X  #endif SYSVR2
X  
X  $(PROG): $(OBJS1) $(OBJS2)
X! 	$(CC) $(LDFLAGS) $(OBJS1) $(OBJS2) -o $(PROG) $(LIBS) $(OTHERLIBS)
X  
X  #if SYSVR2
X  dolock: dolock.o
X***************
X*** 39,44
X  	@echo loading...
X  	@$(CC) $(LDFLAGS) $(OBJS1) $(OBJS2) -o $(PROG) $(LIBS) $(OTHERLIBS)
X  
X  $(OBJS1): $(HDRS1) $(HDRS2)
X  $(OBJS2): $(HDRS1) $(HDRS2) $(HDRS3)
X  loop.o: version.h
X
X--- 42,55 -----
X  $(PROG): $(OBJS1) $(OBJS2)
X  	$(CC) $(LDFLAGS) $(OBJS1) $(OBJS2) -o $(PROG) $(LIBS) $(OTHERLIBS)
X  
X+ #if SYSVR2
X+ dolock: dolock.o
X+ 	$(CC) $(LDFLAGS) dolock.o -o dolock
X+ 
X+ undolock: undolock.o
X+ 	$(CC) $(LDFLAGS) undolock.o -o undolock
X+ #endif SYSVR2
X+ 	
X  $(OBJS1): $(HDRS1) $(HDRS2)
X  $(OBJS2): $(HDRS1) $(HDRS2) $(HDRS3)
X  loop.o: version.h
X***************
X*** 43,51
X  $(OBJS2): $(HDRS1) $(HDRS2) $(HDRS3)
X  loop.o: version.h
X  
X! BINDIR= /usr/local/bin
X! LIBDIR= /usr/local/lib
X! MRCDIR= /usr/lib
X  MANDIR= /usr/local/man/man1
X  MANEXT= 1
X  
X
X--- 54,62 -----
X  $(OBJS2): $(HDRS1) $(HDRS2) $(HDRS3)
X  loop.o: version.h
X  
X! BINDIR= /usr/lbin
X! LIBDIR= /usr/lib/mush
X! MRCDIR= /usr/lib/mush
X  MANDIR= /usr/local/man/man1
X  MANEXT= 1
X  
X***************
X*** 51,60
X  
X  install: mush
X  	cp mush $(BINDIR)
X! 	strip $(BINDIR)/mush
X! 	chmod 0755 $(BINDIR)/mush
X! 	cp mush.1 $(MANDIR)/mush.$(MANEXT)
X! 	chmod 0644 $(MANDIR)/mush.$(MANEXT)
X  	cp cmd_help $(LIBDIR)
X  	chmod 0644 $(LIBDIR)/cmd_help
X  	cp Mushrc $(MRCDIR)/Mushrc
X
X--- 62,76 -----
X  
X  install: mush
X  	cp mush $(BINDIR)
X! #	strip $(BINDIR)/mush
X! #if SYSV
X! 	chgrp mail $(BINDIR)/mush
X! 	chmod 2755 $(BINDIR)/mush
X! #else
X! #	chmod 755 $(BINDIR)/mush
X! #endif
X! #	cp mush.1 $(MANDIR)/mush.$(MANEXT)
X! #	chmod 0644 $(MANDIR)/mush.$(MANEXT)
X  	cp cmd_help $(LIBDIR)
X  	chmod 0644 $(LIBDIR)/cmd_help
X  #	cp Mushrc $(MRCDIR)/Mushrc
X***************
X*** 57,61
X  	chmod 0644 $(MANDIR)/mush.$(MANEXT)
X  	cp cmd_help $(LIBDIR)
X  	chmod 0644 $(LIBDIR)/cmd_help
X! 	cp Mushrc $(MRCDIR)/Mushrc
X! 	chmod 0644 $(MRCDIR)/Mushrc
X
X--- 73,87 -----
X  #	chmod 0644 $(MANDIR)/mush.$(MANEXT)
X  	cp cmd_help $(LIBDIR)
X  	chmod 0644 $(LIBDIR)/cmd_help
X! #	cp Mushrc $(MRCDIR)/Mushrc
X! #	chmod 0644 $(MRCDIR)/Mushrc
X! 	cp Mail.rc $(MRCDIR)
X! 	chmod 0644 $(MRCDIR)/Mail.rc
X! #if SYSVR2
X! 	cp dolock $(LIBDIR)
X! 	chgrp mail $(LIBDIR)/dolock
X! 	chmod 2755 $(LIBDIR)/dolock
X! 	cp undolock $(LIBDIR)
X! 	chgrp mail $(LIBDIR)/undolock
X! 	chmod 2755 $(LIBDIR)/undolock
X! #endif SYSVR2
XIndex: lock.c
X*** Standard Input	Wed Dec 31 19:00:00 1969
X--- lock.c	Tue Jul 17 21:47:06 1990
X***************
X*** 26,31 ****
X--- 26,36 ----
X      char buf[MAXPATHLEN];
X      int lockfd, cnt = 0;
X      SIGRET (*oldint)(), (*oldquit)();
X+ #ifdef SYSVR2
X+     int	status;
X+     int lockpid;
X+     int waitid;
X+ #endif
X  
X  #ifdef SYSV
X      /* Only the spoolfile needs to be dot_locked -- other files are
X***************
X*** 35,40 ****
X--- 40,70 ----
X      if (strcmp(spoolfile, filename) != 0)
X  	return 0;
X  #endif
X+ #ifdef SYSVR2	/* no saved-group id on setgid pgms. */
X+ 	switch (lockpid = fork()) {
X+ 	case 0:
X+ 		execl(DO_DOT_LOCK, "mush-dolock", spoolfile, filename, (char *) NULL);
X+ 		error("unable to exec(%s, %s)", DO_DOT_LOCK, filename);
X+ 		status = -1;
X+ 		break;
X+ 	case -1:
X+ 		error("unable to fork(dolock) for %s", filename);
X+ 		status = -1;
X+ 		break;
X+ 	default:
X+ 		while ((waitid = wait(&status)) == -1)
X+ 			error("oops, wait() got EINTR");
X+ 		if (waitid != lockpid)
X+ 			error("oops, wait() got %d, not %d", waitid, lockpid);
X+ 		if (status != 0) {
X+ 			errno = ((status & 0xf) == 0) ? (status >> 8) & 0xf : 0;
X+ 			error("unable to lock %s (status = %d)", filename, status);
X+ 			status = -1;
X+ 		}
X+ 		break;
X+ 	}
X+ 	return(status);
X+ #else
X  #ifdef BSD
X      setregid(rgid, sgid);
X  #else /* BSD */
X***************
X*** 73,78 ****
X--- 103,109 ----
X      setgid(getgid());
X  #endif /* BSD */
X      return lockfd == -1? -1 : 0;
X+ #endif /* SYSVR2 */
X  }
X  #endif /* DOT_LOCK */
X  
X***************
X*** 200,209 ****
X--- 231,270 ----
X  {
X  #ifdef DOT_LOCK
X      char buf[MAXPATHLEN];
X+ #ifdef SYSVR2
X+     int	status;
X+     int lockpid;
X+     int waitid;
X+ #endif
X  #endif /* DOT_LOCK */
X  
X      fflush(fp);
X  #ifdef DOT_LOCK
X+ #ifdef SYSVR2	/* no saved-group id on setgid pgms. */
X+ 
X+ 	switch (lockpid = fork()) {
X+ 	case 0:
X+ 		execl(UNDO_DOT_LOCK, "mush-undolock", spoolfile, filename, (char *) NULL);
X+ 		error("unable to exec(%s, %s)", UNDO_DOT_LOCK, filename);
X+ 		status = -1;
X+ 		break;
X+ 	case -1:
X+ 		error("unable to fork(undolock) for %s", filename);
X+ 		status = -1;
X+ 		break;
X+ 	default:
X+ 		while ((waitid = wait(&status)) == -1)
X+ 			error("oops, wait() got EINTR");
X+ 		if (waitid != lockpid)
X+ 			error("oops, wait() got %d, not %d", waitid, lockpid);
X+ 		if (status != 0) {
X+ 			errno = ((status & 0xf) == 0) ? (status >> 8) & 0xf : 0;
X+ 			error("unable to unlock %s (status = %d)", filename, status);
X+ 			status = -1;
X+ 		}
X+ 		break;
X+ 	}
X+ #else /* !SYSVR2 */
X  #ifdef BSD
X      setregid(rgid, sgid);
X  #else
X***************
X*** 222,227 ****
X--- 283,289 ----
X  #else
X      setgid(getgid());
X  #endif /* BSD */
X+ #endif /* SYSVR2 */
X  #endif /* DOT_LOCK */
X  
X      (void) flock(fileno(fp), LOCK_UN);
END_OF_FILE
if test 6913 -ne `wc -c <'Patch.sVr2'`; then
    echo shar: \"'Patch.sVr2'\" unpacked with wrong size!
fi
# end of 'Patch.sVr2'
fi
if test -f 'dolock.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'dolock.c'\"
else
echo shar: Extracting \"'dolock.c'\" \(996 characters\)
sed "s/^X//" >'dolock.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <errno.h>
X#include <fcntl.h>
X#include "config.h"
X
Xint
Xmain(argc, argv)
X	int	argc;
X	char	*argv[];
X{
X	char	*filename;
X	char	*spoolfile;
X	char	buf[BUFSIZ];
X	int	lockfd;
X	int	cnt = 0;
X
X	if (strcmp(argv[0], "mush-dolock") != 0 || argc != 3) {
X		fprintf(stderr, "dolock: usage error.\n");
X		exit(0);
X	}
X	spoolfile = argv[1];
X	filename = argv[2];
X	/*
X	 * Only the spoolfile needs to be dot_locked
X	 */
X	if (strcmp(spoolfile, filename) != 0)
X		exit(0);
X	(void) sprintf(buf, "%s.lock", filename);
X	while ((lockfd = open(buf, O_CREAT|O_WRONLY|O_EXCL, 0444)) == -1) {
X		if (errno != EEXIST) {
X			fprintf(stderr, "%s: unable to lock %s", argv[0], filename);
X			perror("");
X			break;
X		}
X		if (cnt++ == 0)
X			printf("%s already locked, waiting", filename);
X		else {
X			putchar('.');
X			fflush(stdout);
X		}
X		sleep(1);
X		/* SIGINT will terminate the process, with non-zero status */
X	}
X	if (lockfd == -1)
X		exit(errno);
X	if (cnt)
X		puts("done.");
X	(void) close(lockfd);
X	exit(0);
X}
END_OF_FILE
if test 996 -ne `wc -c <'dolock.c'`; then
    echo shar: \"'dolock.c'\" unpacked with wrong size!
fi
# end of 'dolock.c'
fi
if test -f 'undolock.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'undolock.c'\"
else
echo shar: Extracting \"'undolock.c'\" \(579 characters\)
sed "s/^X//" >'undolock.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <string.h>
X#include <errno.h>
X#include "config.h"
X
Xint
Xmain(argc, argv)
X	int	argc;
X	char	*argv[];
X{
X	char	*filename;
X	char	*spoolfile;
X	char	buf[BUFSIZ];
X	int	cnt = 0;
X
X	if (strcmp(argv[0], "mush-undolock") != 0 || argc != 3) {
X		fprintf(stderr, "undolock: usage error\n");
X		exit(0);
X	}
X	spoolfile = argv[1];
X	filename = argv[2];
X	if (strcmp(spoolfile, filename) == 0) {
X		(void) sprintf(buf, "%s.lock", filename);
X		if (unlink(buf) == -1) {
X			fprintf(stderr, "undolock: can't unlink(%s) - ", buf);
X			perror("");
X			exit(errno);
X		}
X	}
X	exit(0);
X}
END_OF_FILE
if test 579 -ne `wc -c <'undolock.c'`; then
    echo shar: \"'undolock.c'\" unpacked with wrong size!
fi
# end of 'undolock.c'
fi
echo shar: End of shell archive.
exit 0
-- 
						Greg A. Woods

woods@{eci386,gate,robohack,ontmoh,tmsoft}.UUCP
+1-416-443-1734 [h]  +1-416-595-5425 [w]    VE3-TCP	Toronto, Ontario CANADA



More information about the Comp.sources.bugs mailing list