Subject: Accounting daemon (#412 1 of 2)
Index:	sys/kern_acct.c,usr.sbin/accton,usr.sbin/sa 2.11BSD

Description:
	1) In kern_acct.c there has been, for many years, the comment:
 *
 * 	SHOULD REPLACE THIS WITH A DRIVER THAT CAN BE READ TO SIMPLIFY.
 *

	2) malloc(3) would corrupt the arena when passed 0 as the requested
	   size.  This would cause the program to coredump later in a non-
	   obvious way.

Repeat-By:
	Observation ;-)

Fix:
	The addition of the accounting 'driver' is something I've wanted
	to do for a long time (an itch I had to scratch ;-)).

	malloc(3) now returns an error when asked to allocate 0 bytes.

	This is the first attempt at providing a "accounting driver".  The
	kernel logging module (subr_log.c) was completely rewritten and
	generalized.  The logging driver now supports multiple devices:

	  minor device 0 is the traditional kernel log device /dev/klog

	  minor device 1 is reserved for the future error logging daemon.

	  minor device 2 is the process accounting device (/dev/acctd) read 
	  by the accounting daemon acctd(8) [/usr/libexec/acctd].

	At the present time the log driver is only built for 3 devices but that
	can be raised at any time by changing the definition of 'NLOG' in
	subr_log.c.

	The accounting enable/disable program 'accton' was rewritten to
	not use accton(2) but instead to run/stop the new accounting daemon 
	/usr/libexec/acctd.  

	One BIG advantage of the new accounting driver and accton(8) program is
	that over 1/2KB of code and data is removed from the kernel (this takes
	into account the growth of subr_log!).

	Many people are not interested in the accounting information (the first
	thing commonly done is to remove /usr/adm/acct _or_ run 'accton' to
	turn off accounting) so saving space in the kernel is a Good Thing.  

	NOTE:  the old system call 'acct(2)' is removed from the system
	       in this update.  Only 'accton(8)' and 'init(8)' ever used it
	       and they are patched as part of the update process.

	Make sure you have both parts (#412 and 413) before proceeding with 
	the patching.  The first (this) part contains the instructions (which
	are not repeated in the 2nd part) and a shar file containing:

		412.patch - a patch file
		412.remove - a small shell script to remove old files

	The 2nd part (#413) is a shar file of new programs which are being added
	to the system ('acctd').

	NOTE:  Because 'init(8)' is updated by this update it is a VERY good
	       idea to have a current bootable backup tape.  Such a tape
	       contains the standalone utilities and a dump of the root file-
	       system.  If something goes awry during the updating of 'init' 
	       (powerfail is a good example) the system will be left unbootable.
	       At that time having a bootable tape backup will be of great 
	       value!  To create a bootable backup:

			cd /sys/pdpstand
			make
			./maketape /dev/nrmt0 maketape.data
			dump 0f /dev/rmt0 /

		(changing 'rmt0' as appropriate for your tape device).

	All set?  Ok - let's go.

	Save the two parts to tmp files (/tmp/412 and /tmp/413 are used in
	the instructions).  Cut where indicated.

	IF you do not want to completely remove the (2) files listed in
	412.remove then use "mv" to rename them to something else.  The old
	manpages must NOT exist later on in the update proceedure.

	Turn off accounting (in case it is on):

		accton

	Then:

		cd /tmp
		sh 412
		sh 413
		patch -p0 < 412.patch
		sh 412.remove

	That's the easy part.  Don't worry there is much more (and harder)
	work to come ;)

	Next 'libc' is updated.  There are two ways to do this:  a complete
	rebuild (about an hour and a half) or follow the somewhat lengthy
	manual instructions below.

	If you want to start a "make" of libc and go out to dinner then:

		cd /usr/src/lib/libc
		make
		(go out to dinner)
		make install
		make clean

	To update libc (and the profiling version libc_p) with only those
	changes necessary run the following commands (cut&paste this into
	a shell script might save typing;)):

		ar dv /lib/libc.a acct.o
		ar dv /usr/lib/libc_p.a acct.o
		cd /usr/src/lib/libc/gen
		cc -p -O  -c malloc.c
		ld -X -r malloc.o
		mv a.out malloc.o
		ar rv /usr/lib/libc_p.a malloc.o
		cc -O  -c malloc.c
		ld -X -r malloc.o
		mv a.out malloc.o
		ar rv /lib/libc.a malloc.o
		ranlib /lib/libc.a /usr/lib/libc_p.a

	Now the new accounting daemon is built and installed:

		cd /usr/src/libexec/acctd
		make
		make install
		make clean

	Then the updated 'sa' manpage:

		cd /usr/src/usr.sbin/sa
		make
		make install
		make clean

	and the new accton(8) program:

		cd /usr/src/usr.sbin/accton
		make 
		make install
		make clean

	The new device nodes are now created.  This is done by creating all
	the "standard" devices.  Since most of these already exist you will 
	see some warnings (that can be ignored) about devices already existing.

		cd /dev
		./MAKEDEV std

	Next a new kernel and 'init(8)' program are created.

		cd /sys/YOURKERNEL
		make clean
		make

	There MAY be overlay size problems.  Several object modules change
	size and that can cause an existing overlay scheme to break.   Edit
	the kernel's Makefile and move things between 'OV' and 'BASE' until the
	linker does not complain.

	If you are not running a networking kernel then omit references to
	'/netnix' below:

		mv /unix /ounix
		mv /netnix /onetnix
		mv unix netnix /
		chmod 744 /unix /netnix
		make clean
		make

	DO NOT REBOOT yet.  The new 'init' process needs to be installed.

		cd /usr/src/sbin/init
		make
		mv /etc/init /etc/init.old
		mv init /etc/init

	Now reboot:

		reboot

	Voila - you're done.  

	'accton' by default works exactly as it did before.  With no arguments
	accounting is turned off.  With exactly one filename argument (of a 
	file that must already exist) accounting is turned on.  New options
	do exist and are described in the manpage.  Accton(8) will start and
	stop the daemon (acctd) but it is possible to kill and run (as root)
	the acctd program manually if desired.

	You may notice that there is now much more "buffering" of 
	accounting information.  Looking at the accounting file (/usr/adm/acct
	by default) with "ls -l" will not immediately show changes in size.
	In the event of a crash (but NOT from an orderly shutdown) up to
	31 accounting events may be lost due to 'acctd'  buffering  the data.
	This is being looked into and will likely be improved in the future.

	As always this and previous updates to 2.11BSD are available via
	anonymous FTP to either FTP.IIPO.GTEGSC.COM or MOE.2BSD.COM in the
	directory /pub/2.11BSD.

--------------------------cut here-------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	412.patch
#	412.remove
# This archive created: Fri Apr 16 16:29:32 1999
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f '412.patch'
then
	echo shar: "will not over-write existing file '412.patch'"
else
sed 's/^Y//' << \SHAR_EOF > '412.patch'
Y*** /dev/MAKEDEV.old	Sat Feb  1 15:55:51 1997
Y--- /dev/MAKEDEV	Fri Feb 19 18:20:56 1999
Y***************
Y*** 4,10 ****
Y  # All rights reserved.  The Berkeley software License Agreement
Y  # specifies the terms and conditions for redistribution.
Y  #
Y! #	@(#)MAKEDEV	4.27.5 (2.11BSD GTE) 1997/1/31
Y  #
Y  # Device "make" file.  Valid arguments:
Y  #	std	standard devices
Y--- 4,10 ----
Y  # All rights reserved.  The Berkeley software License Agreement
Y  # specifies the terms and conditions for redistribution.
Y  #
Y! #	@(#)MAKEDEV	4.27.6 (2.11BSD) 1999/2/19
Y  #
Y  # Device "make" file.  Valid arguments:
Y  #	std	standard devices
Y***************
Y*** 60,65 ****
Y--- 60,67 ----
Y  	mknod zero		c 1 3	; chmod 444 zero
Y  	mknod tty		c 9 0	; chmod 666 tty
Y   	mknod klog		c 22 0	; chmod 600 klog
Y+ 	mknod errlog		c 22 1	; chmod 600 errlog
Y+ 	mknod acctlog		c 22 2  ; chmod 600 acctlog
Y  	;;
Y  
Y  fd)
Y*** /usr/include/syscall.h.old	Wed Dec 31 22:56:18 1997
Y--- /usr/include/syscall.h	Fri Feb 26 20:09:41 1999
Y***************
Y*** 3,9 ****
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)syscall.h	5.4.8 (2.11BSD GTE) 1997/12/31
Y   */
Y  
Y  /*
Y--- 3,9 ----
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)syscall.h	5.4.9 (2.11BSD) 1999/2/19
Y   */
Y  
Y  /*
Y***************
Y*** 61,67 ****
Y  #define	SYS_getegid	48
Y  #define	SYS_setgid	49
Y  #define	SYS_setegid	50
Y! #define	SYS_acct	51
Y  #define	SYS_phys	52
Y  #define	SYS_lock	53
Y  #define	SYS_ioctl	54
Y--- 61,67 ----
Y  #define	SYS_getegid	48
Y  #define	SYS_setgid	49
Y  #define	SYS_setegid	50
Y! 				/* 51 was acct */
Y  #define	SYS_phys	52
Y  #define	SYS_lock	53
Y  #define	SYS_ioctl	54
Y*** /usr/src/sys/conf/checksys.c.old	Sun Aug 28 10:53:38 1994
Y--- /usr/src/sys/conf/checksys.c	Sat Dec  5 17:51:31 1998
Y***************
Y*** 3,9 ****
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)checksys.c	1.5 (2.11BSD GTE) 8/28/94
Y   */
Y  
Y  /*
Y--- 3,9 ----
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)checksys.c	1.6 (2.11BSD) 1998/12/5
Y   */
Y  
Y  /*
Y***************
Y*** 19,24 ****
Y--- 19,25 ----
Y  #include "a.out.h"
Y  #include "stdio.h"
Y  #include "namei.h"
Y+ #include "msgbuf.h"
Y  
Y  /* Round up to a click boundary. */
Y  #define	cround(bytes)	((bytes + ctob(1) - 1) / ctob(1) * ctob(1));
Y***************
Y*** 36,42 ****
Y  #define	N_QUOTDESC	17
Y  #define	N_NAMECACHE	18
Y  #define	N_IOSIZE	19
Y! #define	N_NUMSYMS	20
Y  
Y  	struct	nlist	nl[N_NUMSYMS];
Y  
Y--- 37,44 ----
Y  #define	N_QUOTDESC	17
Y  #define	N_NAMECACHE	18
Y  #define	N_IOSIZE	19
Y! #define	N_NLOG		20
Y! #define	N_NUMSYMS	21
Y  
Y  	struct	nlist	nl[N_NUMSYMS];
Y  
Y***************
Y*** 60,66 ****
Y  	"_xitdesc",			/* 16 */
Y  	"_quotdesc",			/* 17 */
Y  	"_namecache",			/* 18 */
Y! 	"__iosize"			/* 19 */
Y  	};
Y  
Y  static struct exec obj;
Y--- 62,69 ----
Y  	"_xitdesc",			/* 16 */
Y  	"_quotdesc",			/* 17 */
Y  	"_namecache",			/* 18 */
Y! 	"__iosize",			/* 19 */
Y! 	"_nlog"				/* 20 */
Y  	};
Y  
Y  static struct exec obj;
Y***************
Y*** 229,234 ****
Y--- 232,239 ----
Y  		totsize += (ninode * sizeof(struct namecache));
Y  	if (nl[N_IOSIZE].n_type)
Y  		totsize += getval(N_IOSIZE);
Y+ 	if (nl[N_NLOG].n_type)
Y+ 		totsize += (getval(N_NLOG) * MSG_BSIZE);
Y  	totsize += ctob(USIZE);
Y  	printf("System will occupy %ld bytes of memory (including buffers and clists).\n", totsize);
Y  	for (i = 0; i < N_NUMSYMS; i++) {
Y*** /usr/src/sys/sys/subr_log.c.old	Wed Nov 30 22:05:08 1994
Y--- /usr/src/sys/sys/subr_log.c	Tue Mar  9 19:44:56 1999
Y***************
Y*** 3,15 ****
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)subr_log.c	1.3 (2.11BSD GTE) 11/30/94
Y   */
Y  
Y  /*
Y!  * Error log buffer for kernel printf's.
Y   */
Y  
Y  #include "param.h"
Y  #include "user.h"
Y  #include "proc.h"
Y--- 3,29 ----
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)subr_log.c	2.0 (2.11BSD) 1998/12/5
Y   */
Y  
Y  /*
Y!  * logioctl() had the wrong number of arguments.  Argh!  Apparently this
Y!  * driver was overlooked when 'dev' was added to ioctl entry points.
Y!  *
Y!  * logclose() returned garbage.  this went unnoticed because most programs
Y!  * don't check status when doing a close.
Y! 
Y!  * Remove vax ifdefs - this driver is never going back to vaxland.
Y!  *
Y!  * Add support for multiple log devices.  Minor device 0 is the traditional
Y!  * kernel logger (/dev/klog), minor device 1 is reserved for the future device 
Y!  * error logging daemon.  Minor device 2 is used by the 'accounting' daemon
Y!  * 'acctd'.
Y   */
Y  
Y+ #define	NLOG	3
Y+ 	int	nlog = NLOG;
Y+ 
Y  #include "param.h"
Y  #include "user.h"
Y  #include "proc.h"
Y***************
Y*** 20,209 ****
Y  #include "errno.h"
Y  #include "uio.h"
Y  #include "machine/seg.h"
Y  
Y  #define LOG_RDPRI	(PZERO + 1)
Y  
Y  #define LOG_ASYNC	0x04
Y  #define LOG_RDWAIT	0x08
Y  
Y! struct logsoftc {
Y! 	int	sc_state;		/* see above for possibilities */
Y! 	struct	proc *sc_selp;		/* process waiting on select call */
Y! 	int	sc_pgid;		/* process/group for async I/O */
Y! } logsoftc;
Y  
Y! int	log_open;			/* also used in log() */
Y  
Y  /*ARGSUSED*/
Y  logopen(dev, mode)
Y  	dev_t dev;
Y  	int mode;
Y! {
Y  
Y! 	if (log_open)
Y! 		return (EBUSY);
Y! 	log_open = 1;
Y! 	logsoftc.sc_pgid = u.u_procp->p_pid;	/* signal process only */
Y! 
Y! #ifndef	pdp11
Y! 	/*
Y! 	 * Potential race here with putchar() but since putchar should be
Y! 	 * called by autoconf, msg_magic should be initialized by the time
Y! 	 * we get here.
Y! 	 */
Y! 	if (msgbuf.msg_magic != MSG_MAGIC) {
Y! 		register int i;
Y! 
Y! 		msgbuf.msg_magic = MSG_MAGIC;
Y! 		msgbuf.msg_bufx = msgbuf.msg_bufr = 0;
Y! 		for (i=0; i < MSG_BSIZE; i++)
Y! 			msgbuf.msg_bufc[i] = 0;
Y  	}
Y- #endif
Y- 	return (0);
Y- }
Y  
Y  /*ARGSUSED*/
Y  logclose(dev, flag)
Y! 	dev_t dev;
Y! {
Y! 	log_open = 0;
Y! 	logsoftc.sc_state = 0;
Y! }
Y  
Y  /*ARGSUSED*/
Y  logread(dev, uio, flag)
Y  	dev_t dev;
Y  	struct uio *uio;
Y  	int flag;
Y! {
Y  	register int l;
Y! 	register int s;
Y! 	int error = 0;
Y! #ifdef	pdp11
Y  	char	buf[ctob(2)];
Y- #endif
Y  
Y  	s = splhigh();
Y! 	while (msgbuf.msg_bufr == msgbuf.msg_bufx) {
Y! 		if (flag & IO_NDELAY) {
Y  			splx(s);
Y! 			return (EWOULDBLOCK);
Y  		}
Y! 		logsoftc.sc_state |= LOG_RDWAIT;
Y! 		sleep((caddr_t)&msgbuf, LOG_RDPRI);
Y! 	}
Y! 	splx(s);
Y! 	logsoftc.sc_state &= ~LOG_RDWAIT;
Y  
Y! 	while (uio->uio_resid) {
Y! 		l = msgbuf.msg_bufx - msgbuf.msg_bufr;
Y! 		if (l < 0)
Y! 			l = MSG_BSIZE - msgbuf.msg_bufr;
Y! 		l = MIN(l, uio->uio_resid);
Y! 		if (l == 0)
Y  			break;
Y! #ifdef	pdp11
Y  		l = MIN(l, sizeof buf);
Y! 		mapseg5(msgbuf.msg_click, (btoc(MSG_BSIZE) << 8) | RW);
Y! 		bcopy(&msgbuf.msg_bufc[msgbuf.msg_bufr], buf, l);
Y  		normalseg5();
Y  		error = uiomove(buf, l, uio);
Y! #else
Y! 		error = uiomove((caddr_t)&msgbuf.msg_bufc[msgbuf.msg_bufr],
Y! 			(int)l, uio);
Y! #endif
Y! 		if (error)
Y  			break;
Y! 		msgbuf.msg_bufr += l;
Y! 		if (msgbuf.msg_bufr < 0 || msgbuf.msg_bufr >= MSG_BSIZE)
Y! 			msgbuf.msg_bufr = 0;
Y  	}
Y- 	return (error);
Y- }
Y  
Y  /*ARGSUSED*/
Y  logselect(dev, rw)
Y  	dev_t dev;
Y  	int rw;
Y! {
Y  	register int s = splhigh();
Y  
Y! 	switch (rw) {
Y! 
Y! 	case FREAD:
Y! 		if (msgbuf.msg_bufr != msgbuf.msg_bufx) {
Y! 			splx(s);
Y! 			return (1);
Y  		}
Y- 		logsoftc.sc_selp = u.u_procp;
Y- 		break;
Y- 	}
Y  	splx(s);
Y! 	return (0);
Y! }
Y  
Y! logwakeup()
Y! {
Y  	register struct proc *p;
Y  
Y! 	if (!log_open)
Y  		return;
Y! 	if (logsoftc.sc_selp) {
Y! 		selwakeup(logsoftc.sc_selp, (long) 0);
Y! 		logsoftc.sc_selp = 0;
Y! 	}
Y! 	if (logsoftc.sc_state & LOG_ASYNC) {
Y! 		if (logsoftc.sc_pgid < 0)
Y! 			gsignal(-logsoftc.sc_pgid, SIGIO); 
Y! 		else if (p = pfind(logsoftc.sc_pgid))
Y  			psignal(p, SIGIO);
Y! 	}
Y! 	if (logsoftc.sc_state & LOG_RDWAIT) {
Y! 		wakeup((caddr_t)&msgbuf);
Y! 		logsoftc.sc_state &= ~LOG_RDWAIT;
Y! 	}
Y  }
Y  
Y  /*ARGSUSED*/
Y! logioctl(com, data, flag)
Y  	caddr_t data;
Y! {
Y  	long l;
Y  	register int s;
Y  
Y! 	switch (com) {
Y  
Y! 	/* return number of characters immediately available */
Y! 	case FIONREAD:
Y! 		s = splhigh();
Y! 		l = msgbuf.msg_bufx - msgbuf.msg_bufr;
Y! 		splx(s);
Y! 		if (l < 0)
Y! 			l += MSG_BSIZE;
Y! 		*(off_t *)data = l;
Y! 		break;
Y  
Y! 	case FIONBIO:
Y! 		break;
Y  
Y! 	case FIOASYNC:
Y! 		if (*(int *)data)
Y! 			logsoftc.sc_state |= LOG_ASYNC;
Y  		else
Y! 			logsoftc.sc_state &= ~LOG_ASYNC;
Y! 		break;
Y  
Y! 	case TIOCSPGRP:
Y! 		logsoftc.sc_pgid = *(int *)data;
Y! 		break;
Y  
Y! 	case TIOCGPGRP:
Y! 		*(int *)data = logsoftc.sc_pgid;
Y! 		break;
Y  
Y! 	default:
Y! 		return (-1);
Y  	}
Y- 	return (0);
Y- }
Y--- 34,368 ----
Y  #include "errno.h"
Y  #include "uio.h"
Y  #include "machine/seg.h"
Y+ #include "map.h"
Y  
Y  #define LOG_RDPRI	(PZERO + 1)
Y  
Y+ #define	LOG_OPEN	0x01
Y  #define LOG_ASYNC	0x04
Y  #define LOG_RDWAIT	0x08
Y  
Y! /*
Y!  * This is an efficiency hack.  This global is provided for exit() to
Y!  * test and avoid the overhead of function calls when accounting is
Y!  * turned off.
Y! */
Y! 	int	Acctopen;
Y  
Y! 	struct	msgbuf	msgbuf[NLOG];
Y! 	static	struct logsoftc
Y! 		{
Y! 		int	sc_state;	/* see above for possibilities */
Y! 		struct	proc *sc_selp;	/* process waiting on select call */
Y! 		int	sc_pgid;	/* process/group for async I/O */
Y! 		int	sc_overrun;	/* full buffer count */
Y! 		} logsoftc[NLOG];
Y  
Y  /*ARGSUSED*/
Y  logopen(dev, mode)
Y  	dev_t dev;
Y  	int mode;
Y! 	{
Y! 	register int	unit = minor(dev);
Y  
Y! 	if	(unit >= NLOG)
Y! 		return(ENODEV);
Y! 	if	(logisopen(unit))
Y! 		return(EBUSY);
Y! 	if	(msgbuf[unit].msg_click == 0)	/* no buffer allocated */
Y! 		return(ENOMEM);
Y! 	logsoftc[unit].sc_state |= LOG_OPEN;
Y! 	if	(unit == logACCT)
Y! 		Acctopen = 1;
Y! 	logsoftc[unit].sc_pgid = u.u_procp->p_pid;  /* signal process only */
Y! 	logsoftc[unit].sc_overrun = 0;
Y! 	return(0);
Y  	}
Y  
Y  /*ARGSUSED*/
Y  logclose(dev, flag)
Y! 	dev_t	dev;
Y! 	int	flag;
Y! 	{
Y! 	register int unit = minor(dev);
Y  
Y+ 	logsoftc[unit].sc_state = 0;
Y+ 	if	(unit == logACCT)
Y+ 		Acctopen = 0;
Y+ 	return(0);
Y+ 	}
Y+ 
Y+ /*
Y+  * This is a helper function to keep knowledge of this driver's data
Y+  * structures away from the rest of the kernel.
Y+ */
Y+ logisopen(unit)
Y+ 	int	unit;
Y+ 	{
Y+ 
Y+ 	if	(logsoftc[unit].sc_state & LOG_OPEN)
Y+ 		return(1);
Y+ 	return(0);
Y+ 	}
Y+ 
Y  /*ARGSUSED*/
Y  logread(dev, uio, flag)
Y  	dev_t dev;
Y  	struct uio *uio;
Y  	int flag;
Y! 	{
Y  	register int l;
Y! 	register struct logsoftc *lp;
Y! 	register struct msgbuf *mp;
Y! 	int	s, error = 0;
Y  	char	buf[ctob(2)];
Y  
Y+ 	l = minor(dev);
Y+ 	lp = &logsoftc[l];
Y+ 	mp = &msgbuf[l];
Y  	s = splhigh();
Y! 	while	(mp->msg_bufr == mp->msg_bufx)
Y! 		{
Y! 		if	(flag & IO_NDELAY)
Y! 			{
Y  			splx(s);
Y! 			return(EWOULDBLOCK);
Y! 			}
Y! 		lp->sc_state |= LOG_RDWAIT;
Y! 		sleep((caddr_t)mp, LOG_RDPRI);
Y  		}
Y! 	lp->sc_state &= ~LOG_RDWAIT;
Y  
Y! 	while	(uio->uio_resid)
Y! 		{
Y! 		l = mp->msg_bufx - mp->msg_bufr;
Y! /*
Y!  * If the reader and writer are equal then we have caught up and there
Y!  * is nothing more to transfer.
Y! */
Y! 		if	(l == 0)
Y  			break;
Y! /*
Y!  * If the write pointer is behind the reader then only consider as
Y!  * available for now the bytes from the read pointer thru the end of 
Y!  * the buffer.
Y! */
Y! 		if	(l < 0)
Y! 			{
Y! 			l = MSG_BSIZE - mp->msg_bufr;
Y! /*
Y!  * If the reader is exactly at the end of the buffer it is
Y!  * time to wrap it around to the beginning and recalculate the
Y!  * amount of data to transfer.
Y! */
Y! 			if	(l == 0)
Y! 				{
Y! 				mp->msg_bufr = 0;
Y! 				continue;
Y! 				}
Y! 			}
Y! 		l = MIN(l, uio->uio_resid);
Y  		l = MIN(l, sizeof buf);
Y! 		mapseg5(mp->msg_click, (btoc(MSG_BSIZE) << 8) | RW);
Y! 		bcopy(&mp->msg_bufc[mp->msg_bufr], buf, l);
Y  		normalseg5();
Y  		error = uiomove(buf, l, uio);
Y! 		if	(error)
Y  			break;
Y! 		mp->msg_bufr += l;
Y! 		if	(mp->msg_bufr < 0 || mp->msg_bufr >= MSG_BSIZE)
Y! 			mp->msg_bufr = 0;
Y! 		}
Y! 	splx(s);
Y! 	return(error);
Y  	}
Y  
Y  /*ARGSUSED*/
Y  logselect(dev, rw)
Y  	dev_t dev;
Y  	int rw;
Y! 	{
Y  	register int s = splhigh();
Y+ 	int	unit = minor(dev);
Y  
Y! 	switch	(rw)
Y! 		{
Y! 		case	FREAD:
Y! 			if	(msgbuf[unit].msg_bufr != msgbuf[unit].msg_bufx)
Y! 				{
Y! 				splx(s);
Y! 				return(1);
Y! 				}
Y! 			logsoftc[unit].sc_selp = u.u_procp;
Y! 			break;
Y  		}
Y  	splx(s);
Y! 	return(0);
Y! 	}
Y  
Y! logwakeup(unit)
Y! 	int	unit;
Y! 	{
Y  	register struct proc *p;
Y+ 	register struct logsoftc *lp;
Y+ 	register struct msgbuf *mp;
Y  
Y! 	if	(!logisopen(unit))
Y  		return;
Y! 	lp = &logsoftc[unit];
Y! 	mp = &msgbuf[unit];
Y! 	if	(lp->sc_selp)
Y! 		{
Y! 		selwakeup(lp->sc_selp, (long) 0);
Y! 		lp->sc_selp = 0;
Y! 		}
Y! 	if	(lp->sc_state & LOG_ASYNC && (mp->msg_bufx != mp->msg_bufr))
Y! 		{
Y! 		if	(lp->sc_pgid < 0)
Y! 			gsignal(-lp->sc_pgid, SIGIO); 
Y! 		else if (p = pfind(lp->sc_pgid))
Y  			psignal(p, SIGIO);
Y! 		}
Y! 	if	(lp->sc_state & LOG_RDWAIT)
Y! 		{
Y! 		wakeup((caddr_t)mp);
Y! 		lp->sc_state &= ~LOG_RDWAIT;
Y! 		}
Y  }
Y  
Y  /*ARGSUSED*/
Y! logioctl(dev, com, data, flag)
Y! 	dev_t	dev;
Y! 	u_int	com;
Y  	caddr_t data;
Y! 	int	flag;
Y! 	{
Y  	long l;
Y  	register int s;
Y+ 	int	unit;
Y+ 	register struct logsoftc *lp;
Y+ 	register struct msgbuf *mp;
Y  
Y! 	unit = minor(dev);
Y! 	lp = &logsoftc[unit];
Y! 	mp = &msgbuf[unit];
Y  
Y! 	switch	(com)
Y! 		{
Y! 		case	FIONREAD:
Y! 			s = splhigh();
Y! 			l = mp->msg_bufx - mp->msg_bufr;
Y! 			splx(s);
Y! 			if	(l < 0)
Y! 				l += MSG_BSIZE;
Y! 			*(off_t *)data = l;
Y! 			break;
Y! 		case	FIONBIO:
Y! 			break;
Y! 		case	FIOASYNC:
Y! 			if (*(int *)data)
Y! 				lp->sc_state |= LOG_ASYNC;
Y! 			else
Y! 				lp->sc_state &= ~LOG_ASYNC;
Y! 			break;
Y! 		case	TIOCSPGRP:
Y! 			lp->sc_pgid = *(int *)data;
Y! 			break;
Y! 		case	TIOCGPGRP:
Y! 			*(int *)data = lp->sc_pgid;
Y! 			break;
Y! 		default:
Y! 			return(-1);
Y! 		}
Y! 	return(0);
Y! 	}
Y  
Y! /*
Y!  * This is inefficient for single character writes.  Alas, changing this
Y!  * to be buffered would affect the networking code's use of printf.  
Y! */
Y  
Y! logwrt(buf,len,log)
Y! 	char	*buf;
Y! 	int	len;
Y! 	int	log;
Y! 	{
Y! 	segm	s5;
Y! 	register struct msgbuf *mp = &msgbuf[log];
Y! 	struct	logsoftc *lp = &logsoftc[log];
Y! 	register int	infront;
Y! 	int  s, n, writer, err = 0;
Y! 
Y! 	if	(mp->msg_magic != MSG_MAGIC || (len > MSG_BSIZE))
Y! 		return(-1);
Y! 	saveseg5(s5);
Y! /*
Y!  * Hate to do this but since this can be called from anywhere in the kernel
Y!  * we have to hold off any interrupt service routines so they don't change
Y!  * things.  This looks like a lot of code but it isn't really.
Y! */
Y! 	s = splhigh();
Y! 	while	(len)
Y! 		{
Y! again:		infront = MSG_BSIZE - mp->msg_bufx;
Y! 		if	(infront <= 0)
Y! 			{
Y! 			mp->msg_bufx = 0;
Y! 			infront = MSG_BSIZE - mp->msg_bufr;
Y! 			}
Y! 		n = mp->msg_bufr - mp->msg_bufx;
Y! 		if	(n < 0)		/* bufr < bufx */
Y! 			writer = (MSG_BSIZE - mp->msg_bufx) + mp->msg_bufr;
Y! 		else if	(n == 0)
Y! 			writer = MSG_BSIZE;
Y  		else
Y! 			{
Y! 			writer = n;
Y! 			infront = n;
Y! 			}
Y! 		if	(len > writer)
Y! 			{
Y! /*
Y!  * won't fit.  the total number of bytes to be written is
Y!  * greater than the number available.  the buffer is full.
Y!  * throw away the old data and keep the current data by resetting
Y!  * the 'writer' pointer to the current 'reader' position.  Bump the
Y!  * overrun counter in case anyone wants to look at it for debugging.
Y! */
Y! 			lp->sc_overrun++;
Y! 			mp->msg_bufx = mp->msg_bufr;
Y! 			goto	again;
Y! 			}
Y! 		if	(infront > len)
Y! 			infront = len;
Y! 		mapseg5(mp->msg_click, (btoc(MSG_BSIZE) << 8) | RW);  /* XXX */
Y! 		bcopy(buf, &mp->msg_bufc[mp->msg_bufx], infront);
Y! 		restorseg5(s5);
Y! 		mp->msg_bufx += infront;
Y! 		len -= infront;
Y! 		buf += infront;
Y! 		}
Y! out:	splx(s);
Y! 	return(err);
Y! 	}
Y  
Y! /*
Y!  * Initialize the log driver.  Called from the system startup code (machdep2.c).
Y!  * All buffers are the same (MSG_BSIZE) size.
Y! */
Y  
Y! loginit()
Y! 	{
Y! register struct msgbuf *mp;
Y  
Y! 	for	(mp = &msgbuf[0]; mp < &msgbuf[NLOG]; mp++)
Y! 		{
Y! 		mp->msg_click = malloc(coremap,btoc(MSG_BSIZE));
Y! 		if	(!mp->msg_click)
Y! 			return(-1);
Y! 		mp->msg_magic = MSG_MAGIC;
Y! 		mp->msg_bufc = SEG5;
Y! 		mp->msg_bufx = mp->msg_bufr = 0;
Y! 		}
Y! 	return(0);
Y  	}
Y*** /usr/src/sys/sys/subr_prf.c.old	Thu May 24 14:40:59 1990
Y--- /usr/src/sys/sys/subr_prf.c	Sat Dec  5 17:34:36 1998
Y***************
Y*** 3,9 ****
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)subr_prf.c	1.1 (2.10BSD Berkeley) 12/1/86
Y   */
Y  
Y  #include "param.h"
Y--- 3,9 ----
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)subr_prf.c	1.2 (2.11BSD) 1998/12/5
Y   */
Y  
Y  #include "param.h"
Y***************
Y*** 101,107 ****
Y  	if (ttycheckoutq(tp, 0) == 0)
Y  		flags = TOLOG;
Y  	prf(fmt, &x1, flags, tp);
Y! 	logwakeup();
Y  }
Y  
Y  /*
Y--- 101,107 ----
Y  	if (ttycheckoutq(tp, 0) == 0)
Y  		flags = TOLOG;
Y  	prf(fmt, &x1, flags, tp);
Y! 	logwakeup(logMSG);
Y  }
Y  
Y  /*
Y***************
Y*** 115,128 ****
Y  	unsigned x1;
Y  {
Y  	register s = splhigh();
Y- 	extern int log_open;
Y  
Y  	logpri(level);
Y  	prf(fmt, &x1, TOLOG, (struct tty *)0);
Y  	splx(s);
Y! 	if (!log_open)
Y  		prf(fmt, &x1, TOCONS, (struct tty *)0);
Y! 	logwakeup();
Y  }
Y  
Y  logpri(level)
Y--- 115,127 ----
Y  	unsigned x1;
Y  {
Y  	register s = splhigh();
Y  
Y  	logpri(level);
Y  	prf(fmt, &x1, TOLOG, (struct tty *)0);
Y  	splx(s);
Y! 	if (!logisopen(logMSG))
Y  		prf(fmt, &x1, TOCONS, (struct tty *)0);
Y! 	logwakeup(logMSG);
Y  }
Y  
Y  logpri(level)
Y***************
Y*** 293,299 ****
Y  tablefull(tab)
Y  	char *tab;
Y  {
Y! 	log(LOG_ERR, "%s: table is full\n", tab);
Y  }
Y  
Y  /*
Y--- 292,298 ----
Y  tablefull(tab)
Y  	char *tab;
Y  {
Y! 	log(LOG_ERR, "%s: table full\n", tab);
Y  }
Y  
Y  /*
Y***************
Y*** 314,324 ****
Y   * are saved in msgbuf for inspection later.
Y   */
Y  putchar(c, flags, tp)
Y! 	register int c;
Y! 	struct tty *tp;
Y  {
Y- 	extern char *panicstr;
Y- 	segm  s5;
Y  
Y  	if (flags & TOTTY) {
Y  		register int s = spltty();
Y--- 313,321 ----
Y   * are saved in msgbuf for inspection later.
Y   */
Y  putchar(c, flags, tp)
Y! 	int c, flags;
Y! 	register struct tty *tp;
Y  {
Y  
Y  	if (flags & TOTTY) {
Y  		register int s = spltty();
Y***************
Y*** 332,348 ****
Y  		}
Y  		splx(s);
Y  	}
Y! 	if ((flags & TOLOG) && c != '\0' && c != '\r' && c != 0177) {
Y! 		if (msgbuf.msg_magic != MSG_MAGIC)
Y! 			goto docons;
Y! 		saveseg5(s5);
Y! 		mapseg5(msgbuf.msg_click, (btoc(MSG_BSIZE) << 8) | RW);
Y! 		msgbuf.msg_bufc[msgbuf.msg_bufx++] = c;
Y! 		if (msgbuf.msg_bufx < 0 || msgbuf.msg_bufx >= MSG_BSIZE)
Y! 			msgbuf.msg_bufx = 0;
Y! 		restorseg5(s5);
Y! 	}
Y! docons:
Y  	if ((flags & TOCONS) && c != '\0')
Y  		cnputc(c);
Y  }
Y--- 329,336 ----
Y  		}
Y  		splx(s);
Y  	}
Y! 	if ((flags & TOLOG) && c != '\0' && c != '\r' && c != 0177)
Y! 		logwrt(&c, 1, logMSG);
Y  	if ((flags & TOCONS) && c != '\0')
Y  		cnputc(c);
Y  }
Y*** /usr/src/sys/sys/kern_acct.c.old	Sat Aug  2 21:51:39 1997
Y--- /usr/src/sys/sys/kern_acct.c	Sat Mar 20 20:43:51 1999
Y***************
Y*** 3,140 ****
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)kern_acct.c	2.6 (2.11BSD) 1997/8/1
Y   *
Y!  * This module is a real mishmash of FreeBSD, 4.3BSD, and home brewed code.
Y   */
Y  
Y  #include "param.h"
Y  #include "systm.h"
Y- #include "fs.h"
Y- #include "dir.h"
Y- #include "inode.h"
Y  #include "user.h"
Y! #include "namei.h"
Y! #include "proc.h"
Y! #include <sys/file.h>
Y! #include "acct.h"
Y  #include "kernel.h"
Y! #include "syslog.h"
Y  
Y! /*
Y!  * SHOULD REPLACE THIS WITH A DRIVER THAT CAN BE READ TO SIMPLIFY.
Y!  */
Y! short	acctsuspend = 2;	/* stop accounting when < 2% free space left */
Y! short	acctresume = 4;		/* resume when free space risen to > 4% */
Y! short	acctchkfreq = 15;	/* frequency to check space for accounting */
Y! short	acctdisabled = 0;	/* 0 = not disabled */
Y! struct	inode *acctp;
Y! comp_t	compress();
Y! static	int	chkfreesp();
Y  
Y  /*
Y-  * Perform process accounting functions.
Y-  */
Y- sysacct()
Y- 	{
Y- 	register struct inode *ip = NULL;
Y- 	register struct a {
Y- 		char	*fname;
Y- 	} *uap = (struct a *)u.u_ap;
Y- 	struct	nameidata nd;
Y- 	register struct nameidata *ndp = &nd;
Y- 	int	error;
Y- 
Y- 	if	(!suser())
Y- 		{
Y- 		error = u.u_error;	/* XXX */
Y- 		goto out;
Y- 		}
Y- /*
Y-  * If accounting is to be started to a file, "open" that file for
Y-  * writing.  We don't check that the file is 'normal' because while it may
Y-  * be strange to write to a tape or (unmounted) disk why should it be
Y-  * prohibited?
Y- */
Y- 	if	(uap->fname != NULL)
Y- 		{
Y- 		NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname);
Y- 		if	((error = vn_open(ndp, FFLAGS(O_WRONLY), 0)) != 0)
Y- 			goto	out;
Y- 		ip = ndp->ni_ip;
Y- 		}
Y- /*
Y-  * Swap the accounting files.
Y- */
Y- 	error = swapacctf(ip);
Y- 
Y- out:
Y- 	return(u.u_error = error);
Y- 	}
Y- 
Y- /*
Y-  * This was broken out into a function of its own so that it could be 
Y-  * called from elsewhere in the kernel.  The experiment that was done for
Y-  * didn't work out but it doesn't hurt anything to retain this function 
Y-  * (it might come in handy in the future).
Y- */
Y- swapacctf(ip)
Y- 	register struct inode *ip;
Y- 	{
Y- 	register struct inode *oacctp;
Y- 
Y- 	oacctp = acctp;
Y- 	acctp = ip;
Y- 	if	(oacctp)
Y- 		(void)vn_close(oacctp, FWRITE);
Y- 	if	(acctp)
Y- 		acctwatch();
Y- 	return(0);
Y- 	}
Y- 
Y- acctwatch()
Y- 	{
Y- 	register struct fs *fs;
Y- 	static	time_t	acctchecktime;
Y- 
Y- 	if	(acctp == NULL || time.tv_sec < acctchecktime)
Y- 		return;		/* do not refresh timer */
Y- 	acctchecktime = time.tv_sec + acctchkfreq;
Y- 	fs = acctp->i_fs;
Y- 
Y- 	if	(acctdisabled)
Y- 		{
Y- 		if	(chkfreesp(fs, acctresume) > 0)
Y- 			{
Y- 			acctdisabled = 0;
Y- 			log(LOG_NOTICE, "Acct resume\n");
Y- 			}
Y- 		}
Y- 	else
Y- 		{
Y- 		if	(chkfreesp(fs, acctsuspend) <= 0)
Y- 			{
Y- 			log(LOG_NOTICE, "Acct suspend\n");
Y- 			acctdisabled = 1;
Y- 			}
Y- 		}
Y- 	}
Y- 
Y- /*
Y   * On exit, write a record on the accounting file.
Y   */
Y  acct()
Y  	{
Y  	struct	acct acctbuf;
Y- 	register struct inode *ip;
Y  	register struct acct *ap = &acctbuf;
Y! 	int	resid;
Y  
Y- 	acctwatch();
Y- 
Y- 	if	((ip = acctp) == NULL || acctdisabled)
Y- 		return;
Y- 	ilock(ip);
Y  	bcopy(u.u_comm, ap->ac_comm, sizeof(acctbuf.ac_comm));
Y  /*
Y   * The 'user' and 'system' times need to be converted from 'hz' (linefrequency)
Y--- 3,35 ----
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)kern_acct.c	3.0 (2.11BSD) 1999/2/19
Y   *
Y!  * This module is a shadow of its former self.  This comment:
Y!  *
Y!  * 	SHOULD REPLACE THIS WITH A DRIVER THAT CAN BE READ TO SIMPLIFY.
Y!  *
Y!  * is all that is left of the original kern_acct.c module.
Y   */
Y  
Y  #include "param.h"
Y  #include "systm.h"
Y  #include "user.h"
Y! #include "msgbuf.h"
Y  #include "kernel.h"
Y! #include "acct.h"
Y  
Y! 	comp_t	compress();
Y  
Y  /*
Y   * On exit, write a record on the accounting file.
Y   */
Y  acct()
Y  	{
Y  	struct	acct acctbuf;
Y  	register struct acct *ap = &acctbuf;
Y! 	static	short acctcnt = 0;
Y  
Y  	bcopy(u.u_comm, ap->ac_comm, sizeof(acctbuf.ac_comm));
Y  /*
Y   * The 'user' and 'system' times need to be converted from 'hz' (linefrequency)
Y***************
Y*** 157,177 ****
Y  	else
Y  		ap->ac_tty = NODEV;
Y  	ap->ac_flag = u.u_acflag;
Y- 	u.u_error = 0;			/* XXX */
Y- 	u.u_error = rdwri(UIO_WRITE, ip, ap, sizeof(acctbuf), ip->i_size,
Y- 			UIO_SYSSPACE, IO_UNIT|IO_APPEND, (int *)&resid);
Y- 	if	(u.u_error)
Y- 		{
Y  /*
Y!  * The only time this should happen is when a physical error occurs on the
Y!  * disk drive.  The freespace check has been made earlier so an error at this
Y!  * time is I/O related.  The message is terse to save space (D-space doesn't
Y!  * grow on trees you know ;)).
Y  */
Y! 		log(LOG_NOTICE,"acct %d %d\n", u.u_error, resid);
Y! 		acctdisabled = 1;
Y  		}
Y- 	iunlock(ip);
Y  	}
Y  
Y  /*
Y--- 52,69 ----
Y  	else
Y  		ap->ac_tty = NODEV;
Y  	ap->ac_flag = u.u_acflag;
Y  /*
Y!  * Not a lot that can be done if logwrt fails so ignore any errors.  Every
Y!  * 10 commands call the wakeup routine.  This isn't perfect but does cut 
Y!  * down the overhead of issuing a wakeup to the accounting daemon every 
Y!  * single accounting record.
Y  */
Y! 	logwrt(ap, sizeof (*ap), logACCT);
Y! 	if	(acctcnt++ > 10)
Y! 		{
Y! 		logwakeup(logACCT);
Y! 		acctcnt = 0;
Y  		}
Y  	}
Y  
Y  /*
Y***************
Y*** 194,217 ****
Y  		if	(mant < (1L << MANTSIZE))
Y  			return(mant | (exp << MANTSIZE));
Y  	return(~0);
Y- 	}
Y- 
Y- /*
Y-  * A helper function since freespace's generated code is so voluminous.  All
Y-  * we really want is an indication if there is the desired amount of space
Y-  * available (greater than or equal, less than zero).
Y- */
Y- static int
Y- chkfreesp(fs, percent)
Y- 	register struct fs *fs;
Y- 	int	percent;
Y- 	{
Y- 	daddr_t	l;
Y- 
Y- 	l = freespace(fs, percent);
Y- 	if	(l < 0)
Y- 		return(-1);
Y- 	else if	(l == 0)
Y- 		return(0);
Y- 	return(1);
Y  	}
Y--- 86,89 ----
Y*** /usr/src/sys/sys/init_sysent.c.old	Wed Dec 31 22:57:38 1997
Y--- /usr/src/sys/sys/init_sysent.c	Fri Feb 26 20:27:44 1999
Y***************
Y*** 3,9 ****
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)init_sysent.c	1.13 (2.11BSD GTE) 1997/12/31
Y   */
Y  
Y  /*
Y--- 3,9 ----
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)init_sysent.c	1.14 (2.11BSD) 1999/2/22
Y   */
Y  
Y  /*
Y***************
Y*** 52,58 ****
Y  
Y  /* 1.7 system operation support */
Y  int	umount(),smount();
Y! int	sync(),reboot(),sysacct(), __sysctl();
Y  
Y  /* 2.1 generic operations */
Y  int	read(),write(),readv(),writev(),ioctl();
Y--- 52,58 ----
Y  
Y  /* 1.7 system operation support */
Y  int	umount(),smount();
Y! int	sync(),reboot(),__sysctl();
Y  
Y  /* 2.1 generic operations */
Y  int	read(),write(),readv(),writev(),ioctl();
Y***************
Y*** 162,168 ****
Y  	0, getegid,			/*  48 = getegid */
Y  	1, setgid,			/*  49 = setgid */
Y  	1, setegid,			/*  50 = setegid */
Y! 	1, sysacct,			/*  51 = turn acct off/on */
Y  	3, phys,			/*  52 = (2.9) set phys addr */
Y  	1, lock,			/*  53 = (2.9) lock in core */
Y  	4, ioctl,			/*  54 = ioctl */
Y--- 162,168 ----
Y  	0, getegid,			/*  48 = getegid */
Y  	1, setgid,			/*  49 = setgid */
Y  	1, setegid,			/*  50 = setegid */
Y! 	0, nosys,			/*  51 = unused */
Y  	3, phys,			/*  52 = (2.9) set phys addr */
Y  	1, lock,			/*  53 = (2.9) lock in core */
Y  	4, ioctl,			/*  54 = ioctl */
Y*** /usr/src/sys/sys/kern_exit.c.old	Thu Jan 30 14:03:30 1997
Y--- /usr/src/sys/sys/kern_exit.c	Tue Feb 23 22:06:16 1999
Y***************
Y*** 3,9 ****
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)kern_exit.c	2.2 (2.11BSD GTE) 1997/1/30
Y   */
Y  
Y  #include "param.h"
Y--- 3,9 ----
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)kern_exit.c	2.3 (2.11BSD) 1999/2/23
Y   */
Y  
Y  #include "param.h"
Y***************
Y*** 24,29 ****
Y--- 24,31 ----
Y  #endif
Y  #include "ingres.h"
Y  
Y+ extern	int	Acctopen;	/* kern_acct.c */
Y+ 
Y  /*
Y   * exit system call: pass back caller's arg
Y   */
Y***************
Y*** 72,78 ****
Y  		iput(u.u_rdir);
Y  	}
Y  	u.u_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
Y! 	(void) acct();
Y  #ifdef QUOTA
Y  	QUOTAMAP();
Y  	qclean();
Y--- 74,81 ----
Y  		iput(u.u_rdir);
Y  	}
Y  	u.u_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
Y! 	if	(Acctopen)
Y! 		(void) acct();
Y  #ifdef QUOTA
Y  	QUOTAMAP();
Y  	qclean();
Y*** /usr/src/sys/h/acct.h.old	Fri Nov 28 16:23:16 1997
Y--- /usr/src/sys/h/acct.h	Fri Feb 19 17:37:42 1999
Y***************
Y*** 3,9 ****
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)acct.h	2.1	(2.11BSD) 1997/11/28
Y   */
Y  
Y  /*
Y--- 3,9 ----
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)acct.h	2.2	(2.11BSD) 1999/2/19
Y   */
Y  
Y  /*
Y***************
Y*** 41,43 ****
Y--- 41,52 ----
Y   * comp_t fields.  This is not necessarily equal to hz.
Y   */
Y  #define AHZ 64
Y+ 
Y+ #ifndef	KERNEL
Y+ #define	_PATH_ACCTD	"/usr/libexec/acctd"
Y+ #define	_PATH_ACCTFILE "/usr/adm/acct"
Y+ #define	_PATH_ACCTDPID "/var/run/acctd.pid"
Y+ #define	_PATH_ACCTDCF "/etc/acctd.cf"
Y+ #define	_PATH_DEVALOG "/dev/acctlog"
Y+ #endif
Y+ 
Y*** /usr/src/sys/h/msgbuf.h.old	Mon Aug  7 21:57:16 1989
Y--- /usr/src/sys/h/msgbuf.h	Sat Dec  5 17:41:21 1998
Y***************
Y*** 3,9 ****
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)msgbuf.h	1.1 (2.10BSD Berkeley) 12/1/86
Y   */
Y  
Y  #define	MSG_MAGIC	0x063061
Y--- 3,9 ----
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)msgbuf.h	1.2 (2.11BSD) 1998/12/5
Y   */
Y  
Y  #define	MSG_MAGIC	0x063061
Y***************
Y*** 16,21 ****
Y  	u_short	msg_click;
Y  	char	*msg_bufc;
Y  };
Y! #if defined(KERNEL) && !defined(SUPERVISOR)
Y! struct	msgbuf msgbuf;
Y! #endif
Y--- 16,22 ----
Y  	u_short	msg_click;
Y  	char	*msg_bufc;
Y  };
Y! 
Y! #define	logMSG	0		/* /dev/klog */
Y! #define	logDEV	1		/* /dev/erlg */
Y! #define	logACCT	2		/* /dev/acct */
Y*** /usr/src/sys/pdp/machdep2.c.old	Mon Mar  2 21:33:46 1998
Y--- /usr/src/sys/pdp/machdep2.c	Fri Feb 19 16:35:21 1999
Y***************
Y*** 3,9 ****
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)machdep2.c	2.8 (2.11BSD) 1998/3/2
Y   */
Y  
Y  #include "param.h"
Y--- 3,9 ----
Y   * All rights reserved.  The Berkeley software License Agreement
Y   * specifies the terms and conditions for redistribution.
Y   *
Y!  *	@(#)machdep2.c	2.9 (2.11BSD) 1999/2/19
Y   */
Y  
Y  #include "param.h"
Y***************
Y*** 221,233 ****
Y  		panic("buffers");
Y  #undef B
Y  
Y! #define	C	(btoc(MSG_BSIZE))
Y! 	if ((msgbuf.msg_click = malloc(coremap, C)) == 0)
Y! 		panic("msgbuf");
Y! 	msgbuf.msg_magic = MSG_MAGIC;
Y! 	msgbuf.msg_bufc = SEG5;
Y! 	msgbuf.msg_bufx = msgbuf.msg_bufr = 0;
Y! #undef	C
Y  
Y  #define	C	(btoc(sizeof (struct xmount)))
Y  	for	(i = 0; i < NMOUNT; i++)
Y--- 221,230 ----
Y  		panic("buffers");
Y  #undef B
Y  
Y! /*
Y!  * Now initialize the log driver (kernel logger, error logger and accounting)
Y! */
Y! 	loginit();
Y  
Y  #define	C	(btoc(sizeof (struct xmount)))
Y  	for	(i = 0; i < NMOUNT; i++)
Y*** /usr/src/libexec/Makefile.old	Fri Dec 13 20:56:00 1996
Y--- /usr/src/libexec/Makefile	Fri Feb 19 17:22:00 1999
Y***************
Y*** 1,7 ****
Y  #
Y  # Steven Schultz - put in the public domain 1996/6/25.
Y  #
Y! #	@(#)Makefile	1.3 (2.11BSD) 1996/12/13
Y  #
Y  DESTDIR=
Y  CFLAGS=	-O
Y--- 1,7 ----
Y  #
Y  # Steven Schultz - put in the public domain 1996/6/25.
Y  #
Y! #	@(#)Makefile	1.5 (2.11BSD) 1999/2/19
Y  #
Y  DESTDIR=
Y  CFLAGS=	-O
Y***************
Y*** 8,15 ****
Y  SEPFLAG= -i
Y  TAGSFILE=tags
Y  
Y! SUBDIR=	comsat ctimed fingerd ftpd getNAME getty identd makekey popper rexecd \
Y! 	rlogind rshd talkd tcpd telnetd tftpd
Y  
Y  all:	${SUBDIR}
Y  
Y--- 8,15 ----
Y  SEPFLAG= -i
Y  TAGSFILE=tags
Y  
Y! SUBDIR=	acctd comsat ctimed fingerd ftpd getNAME getty identd makekey 
Y! 	popper rexecd rlogind rshd talkd tcpd telnetd tftpd
Y  
Y  all:	${SUBDIR}
Y  
Y*** /usr/src/etc/MAKEDEV.old	Sat Feb  1 15:55:51 1997
Y--- /usr/src/etc/MAKEDEV	Fri Feb 19 18:20:56 1999
Y***************
Y*** 4,10 ****
Y  # All rights reserved.  The Berkeley software License Agreement
Y  # specifies the terms and conditions for redistribution.
Y  #
Y! #	@(#)MAKEDEV	4.27.5 (2.11BSD GTE) 1997/1/31
Y  #
Y  # Device "make" file.  Valid arguments:
Y  #	std	standard devices
Y--- 4,10 ----
Y  # All rights reserved.  The Berkeley software License Agreement
Y  # specifies the terms and conditions for redistribution.
Y  #
Y! #	@(#)MAKEDEV	4.27.6 (2.11BSD) 1999/2/19
Y  #
Y  # Device "make" file.  Valid arguments:
Y  #	std	standard devices
Y***************
Y*** 60,65 ****
Y--- 60,67 ----
Y  	mknod zero		c 1 3	; chmod 444 zero
Y  	mknod tty		c 9 0	; chmod 666 tty
Y   	mknod klog		c 22 0	; chmod 600 klog
Y+ 	mknod errlog		c 22 1	; chmod 600 errlog
Y+ 	mknod acctlog		c 22 2  ; chmod 600 acctlog
Y  	;;
Y  
Y  fd)
Y*** /usr/src/lib/libc/gen/malloc.c.old	Thu Apr 11 21:13:28 1996
Y--- /usr/src/lib/libc/gen/malloc.c	Mon Jan 18 20:02:24 1999
Y***************
Y*** 1,4 ****
Y! /*	@(#)malloc.c	2.2	(2.11BSD) 1996/4/11 */
Y  
Y  #include <unistd.h>
Y  
Y--- 1,4 ----
Y! /*	@(#)malloc.c	2.3	(2.11BSD) 1999/1/18 */
Y  
Y  #include <unistd.h>
Y  
Y***************
Y*** 100,105 ****
Y--- 100,107 ----
Y  	register nw;
Y  	static int temp;	/* coroutines assume no auto */
Y  
Y+ 	if (nbytes == 0)
Y+ 		return(NULL);
Y  	if (allocs[0].ptr == 0) {	/* first time */
Y  		allocs[0].ptr = setbusy(&allocs[1]);
Y  		allocs[1].ptr = setbusy(&allocs[0]);
Y*** /usr/src/lib/libc/pdp/sys/Makefile.old	Wed Dec 31 22:54:30 1997
Y--- /usr/src/lib/libc/pdp/sys/Makefile	Fri Feb 19 17:06:04 1999
Y***************
Y*** 1,6 ****
Y  # Placed in the public domain - 1995/05/06
Y  #
Y! #	@(#)Makefile	1.6 (2.11BSD) 1997/12/31
Y  
Y  CPP= /lib/cpp
Y  LD= /bin/ld
Y--- 1,6 ----
Y  # Placed in the public domain - 1995/05/06
Y  #
Y! #	@(#)Makefile	1.7 (2.11BSD) 1999/2/19
Y  
Y  CPP= /lib/cpp
Y  LD= /bin/ld
Y***************
Y*** 19,25 ****
Y  # these are generated with a second argument to SYSCALL of 'norm'.  Have to
Y  # split into more than one list because 'make' only permits 80 "lefts".
Y  
Y! NORM1= __sysctl.o accept.o access.o acct.o adjtime.o bind.o chdir.o chflags.o \
Y  	chmod.o chown.o chroot.o close.o connect.o dup.o dup2.o \
Y  	execve.o fchdir.o fchflags.o fchmod.o fchown.o fcntl.o flock.o fstat.o \
Y  	fsync.o ftruncate.o getdtablesize.o getgroups.o getitimer.o \
Y--- 19,25 ----
Y  # these are generated with a second argument to SYSCALL of 'norm'.  Have to
Y  # split into more than one list because 'make' only permits 80 "lefts".
Y  
Y! NORM1= __sysctl.o accept.o access.o adjtime.o bind.o chdir.o chflags.o \
Y  	chmod.o chown.o chroot.o close.o connect.o dup.o dup2.o \
Y  	execve.o fchdir.o fchflags.o fchmod.o fchown.o fcntl.o flock.o fstat.o \
Y  	fsync.o ftruncate.o getdtablesize.o getgroups.o getitimer.o \
Y*** /usr/src/usr.sbin/accton/accton.c.old	Sun Feb 15 20:51:19 1987
Y--- /usr/src/usr.sbin/accton/accton.c	Fri Feb 19 15:21:19 1999
Y***************
Y*** 1,15 ****
Y! static char *sccsid = "@(#)accton.c	4.1 (Berkeley) 10/1/80";
Y  main(argc, argv)
Y! char **argv;
Y! {
Y! 	extern errno;
Y! 	if (argc > 1)
Y! 		acct(argv[1]);
Y! 	else
Y! 		acct((char *)0);
Y! 	if (errno) {
Y! 		perror("accton");
Y! 		exit(1);
Y! 	}
Y  	exit(0);
Y! }
Y--- 1,204 ----
Y! /*
Y!  * Steven Schultz - sms@moe.2bsd.com
Y!  *
Y!  *	@(#)accton.c	1.0 (2.11BSD) 1999/2/10
Y!  *
Y!  * accton - enable/disable process accounting.
Y! */
Y! 
Y! #include	<signal.h>
Y! #include	<stdio.h>
Y! #include	<errno.h>
Y! #include	<stdlib.h>
Y! #include	<sys/types.h>
Y! #include	<sys/acct.h>
Y! #include	<sys/stat.h>
Y! 
Y! static	int	Suspend = 2;	/* %free when accounting suspended */
Y! static	int	Resume = 4;	/* %free when accounting to be resumed */
Y! static	int	Chkfreq = 30;	/* how often (seconds) to check disk space */
Y! static	char	*Acctfile;
Y! extern	char	*__progname;
Y! 	void	usage();
Y! 
Y  main(argc, argv)
Y! 	int	argc;
Y! 	char	**argv;
Y! 	{
Y! 	int	c;
Y! 	pid_t	pid;
Y! 	char	*cffile = _PATH_ACCTDCF;
Y! 	char	*pidfile = _PATH_ACCTDPID;
Y! 	char	*cp;
Y! 	long	l;
Y! 	register FILE	*fp;
Y! 	int	status;
Y! 	struct	stat	st;
Y! 
Y! 	if	(getuid())
Y! 		errx(1, "Only root can run this program");
Y! /*
Y!  * Handle the simple case of no arguments at all.  This turns off accounting
Y!  * completely by killing the accounting daemon 'acctd'.
Y! */
Y! 	if	(argc == 1)
Y! 		{
Y! 		fp = fopen(pidfile, "r");
Y! /*
Y!  * Note: it is not fatal to fail opening the pid file.  The accounting daemon
Y!  * may not have been run on this system yet.
Y! */
Y! 		if	(!fp)
Y! 			exit(0);
Y! 		if	(fscanf(fp, "%d\n", &pid) != 1)
Y! 			errx(1, "%s corrupt/unparseable",
Y! 				pidfile);
Y! 		if	(pid < 3 || pid > 30000) /* Paranoia */
Y! 			errx(1, "%s content out of bound(30000>pid>3)",
Y! 				pidfile);
Y! 		fclose(fp);
Y! 		if	(kill(pid, SIGTERM) < 0)
Y! 			{
Y! /* 
Y!  * It is not an error to turn off accounting if it is already disabled.  Ignore
Y!  * the no such process error from kill.
Y! */
Y! 			if	(errno != ESRCH)
Y! 				err(1, "kill(%d,SIGTERM)", pid);
Y! 			}
Y! 		exit(0);
Y! 		}
Y! 
Y! 	while	((c = getopt(argc, argv, "f:r:s:t:")) != EOF)
Y! 		{
Y! 		switch	(c)
Y! 			{
Y! 			case	'f':
Y! 				Acctfile = optarg;
Y! 				break;
Y! 			case	'r':
Y! 				cp = NULL;
Y! 				l = strtol(optarg, &cp, 10);
Y! 				if	(l < 0 || l > 99 || (cp && *cp))
Y! 					errx(1, "bad -r value");
Y! 				Resume = (int)l;
Y! 				break;
Y! 			case	's':
Y! 				cp = NULL;
Y! 				l = strtol(optarg, &cp, 10);
Y! 				if	(l < 0 || l > 99 || (cp && *cp))
Y! 					errx(1, "bad -s value");
Y! 				Suspend = (int)l;
Y! 				break;
Y! 			case	't':
Y! 				cp = NULL;
Y! 				l = strtol(optarg, &cp, 10);
Y! 				if	(l < 5 || l > 3600 || (cp && *cp))
Y! 					errx(1, "bad -t value (3600>=t>=5");
Y! 				Chkfreq = (int)l;
Y! 				break;
Y! 			case	'?':
Y! 			default:
Y! 				usage();
Y! 				/* NOTREACHED */
Y! 			}
Y! 		}
Y! 	argc -= optind;
Y! 	argv += optind;
Y! /*
Y!  * If we have exactly one argument left then it must be a filename.  This
Y!  * preserves the historical practice of running "accton /usr/adm/acct" to
Y!  * enable accounting.  It is an error to have more than one argument at this
Y!  * point.
Y! */
Y! 	if	(argc == 1)
Y! 		{
Y! 		if	(Acctfile)
Y! 			warnx("'-f %s' being overridden by trailing '%s'",
Y! 				Acctfile, *argv);
Y! 		Acctfile = *argv;
Y! 		}
Y! 	else if (argc != 0)
Y! 		{
Y! 		usage();
Y! 		/* NOTREACHED */
Y! 		}
Y! /*
Y!  * If after all of that we still don't have a file name then use the 
Y!  * default one.
Y! */
Y! 	if	(!Acctfile)
Y! 		Acctfile = _PATH_ACCTFILE;
Y! 
Y! /*
Y!  * Now open the conf file (creating it if it does not exist) and write out
Y!  * the parameters for the accounting daemon.  The conf file format is simple:
Y!  * "tag=value\n".  NO EXTRA WHITE SPACE or COMMENTS!
Y!  *
Y!  * IF the file already exists it must be owned by root and not writeable by
Y!  * group or other.  This is because the conf file contains a pathname that
Y!  * will be trusted by a daemon running as root.  The same check is made by
Y!  * 'acctd' to prevent believing bogus information.
Y! */
Y! 	if	(stat(cffile, &st) == 0)
Y! 		{
Y! 		if	(st.st_uid != 0)
Y! 			errx(1, "%s not owned by root", cffile);
Y! 		if	(st.st_mode & (S_IWGRP|S_IWOTH))
Y! 			errx(1, "%s writeable by group/other", cffile);
Y! 		}
Y! 	fp = fopen(cffile, "w");
Y! 	if	(!fp)
Y! 		errx(1, "fopen(%s,w)", cffile);
Y! 	fprintf(fp, "suspend=%d\n", Suspend);
Y! 	fprintf(fp, "resume=%d\n", Resume);
Y! 	fprintf(fp, "chkfreq=%d\n", Chkfreq);
Y! 	fprintf(fp, "acctfile=%s\n", Acctfile);
Y! 	fclose(fp);
Y! 
Y! /*
Y!  * After writing the conf file we need to send the current running 'acctd'
Y!  * process (if any) a SIGHUP.  If the pidfile can not be opened this may be
Y!  * the first time 'acctd' has ever been run.
Y! */
Y! 	fp = fopen(pidfile, "r");
Y! 	if	(fp)
Y! 		{
Y! 		if	(fscanf(fp, "%d\n", &pid) != 1)
Y! 			errx(1, "%s corrupt/unparseable", pidfile);
Y! 		if	(pid < 3 || pid > 30000) /* Paranoia */
Y! 			errx(1, "%s content out of bound(30000>pid>3)",
Y! 				pidfile);
Y! 		fclose(fp);
Y! 		if	(kill(pid, SIGHUP) < 0)
Y! 			{
Y! 			if	(errno != ESRCH)
Y! 				err(1, "%d from %s bogus value", pid, pidfile);
Y! 			/* process no longer exists, fall thru and start it */
Y! 			}
Y! 		}
Y! 	pid = vfork();
Y! 	switch	(pid)
Y! 		{
Y! 		case	-1:
Y! 			err(1, "vfork");
Y! 			/* NOTREACHED */
Y! 		case	0:		/* Child process */
Y! 			if	(execl(_PATH_ACCTD, "acctd", NULL) < 0)
Y! 				err(1, "execl %s", _PATH_ACCTD);
Y! 			/* NOTREACHED */
Y! 		default:		/* Parent */
Y! 			break;
Y! 		}
Y! 	if	(waitpid(pid, &status, 0) < 0)
Y! 		err(1, "waitpid for %d", pid);
Y  	exit(0);
Y! 	}
Y! 
Y! void
Y! usage()
Y! 	{
Y! 
Y! 	errx(1,"Usage: %s [-f acctfile] [-s %suspend] [-r %resume] [-t chkfreq] [acctfile]", __progname);
Y! 	/* NOTREACHED */
Y! 	}
Y*** /usr/src/usr.sbin/accton/Makefile.old	Sat Nov 16 16:00:54 1996
Y--- /usr/src/usr.sbin/accton/Makefile	Tue Feb 23 19:32:45 1999
Y***************
Y*** 1,20 ****
Y  #
Y  # Public Domain.  1996/11/16 - Steven Schultz
Y  #
Y! #	@(#)Makefile	1.0 (2.11BSD) 1996/11/16
Y  #
Y  CFLAGS=	 -O
Y  SEPFLAG= -i
Y  SRCS=	accton.c
Y  OBJS=	accton.o
Y  
Y! all: accton
Y  
Y  accton: ${OBJS}
Y  	${CC} ${CFLAGS} ${SEPFLAG} -o $@ ${OBJS}
Y  
Y  clean:
Y! 	rm -f ${OBJS} accton tags 
Y  
Y  depend: ${SRCS}
Y  	mkdep ${CFLAGS} ${SRCS}
Y--- 1,25 ----
Y  #
Y  # Public Domain.  1996/11/16 - Steven Schultz
Y  #
Y! #	@(#)Makefile	1.1 (2.11BSD) 1999/2/19
Y  #
Y  CFLAGS=	 -O
Y  SEPFLAG= -i
Y  SRCS=	accton.c
Y  OBJS=	accton.o
Y+ MAN=	accton.0
Y+ MANSRC=	accton.8
Y  
Y! all: accton accton.0
Y  
Y  accton: ${OBJS}
Y  	${CC} ${CFLAGS} ${SEPFLAG} -o $@ ${OBJS}
Y  
Y+ accton.0: ${MANSRC}
Y+ 	/usr/man/manroff ${MANSRC} > ${MAN}
Y+ 
Y  clean:
Y! 	rm -f ${OBJS} accton tags ${MAN}
Y  
Y  depend: ${SRCS}
Y  	mkdep ${CFLAGS} ${SRCS}
Y***************
Y*** 21,26 ****
Y--- 26,32 ----
Y  
Y  install: accton
Y  	install -s -o root -g bin -m 755 accton ${DESTDIR}/usr/sbin/accton
Y+ 	install -c -o bin -g bin -m 444 ${MAN} ${DESTDIR}/usr/man/cat8/${MAN}
Y  
Y  lint: ${SRCS}
Y  	lint -hax ${SRCS}
Y*** /usr/src/usr.sbin/sa/Makefile.old	Sat Jan  3 22:01:50 1998
Y--- /usr/src/usr.sbin/sa/Makefile	Fri Feb 19 16:12:14 1999
Y***************
Y*** 1,7 ****
Y  #
Y  # Public Domain.  1996/11/16 - Steven Schultz
Y  #
Y! #	@(#)Makefile	1.1 (2.11BSD) 1998/1/3
Y  #
Y  CFLAGS=	 -O
Y  SEPFLAG= -i
Y--- 1,7 ----
Y  #
Y  # Public Domain.  1996/11/16 - Steven Schultz
Y  #
Y! #	@(#)Makefile	1.2 (2.11BSD) 1999/2/19
Y  #
Y  CFLAGS=	 -O
Y  SEPFLAG= -i
Y***************
Y*** 26,33 ****
Y  
Y  install: all
Y  	install -c -o bin -g bin -m 444 ${MAN} ${DESTDIR}/usr/man/cat8
Y- 	-rm -f ${DESTDIR}/usr/man/cat8/accton.0
Y- 	ln ${DESTDIR}/usr/man/cat8/sa.0 ${DESTDIR}/usr/man/cat8/accton.0
Y  	install -s -o root -g bin -m 755 sa ${DESTDIR}/usr/sbin/sa
Y  
Y  lint: ${SRCS}
Y--- 26,31 ----
Y*** /usr/src/usr.sbin/sa/sa.8.old	Sat Feb 15 20:39:19 1997
Y--- /usr/src/usr.sbin/sa/sa.8	Fri Feb 19 16:13:56 1999
Y***************
Y*** 7,13 ****
Y  .TH SA 8 "November 16, 1996"
Y  .UC 4
Y  .SH NAME
Y! sa, accton \- system accounting
Y  .SH SYNOPSIS
Y  .B sa
Y  [
Y--- 7,13 ----
Y  .TH SA 8 "November 16, 1996"
Y  .UC 4
Y  .SH NAME
Y! sa \- system accounting
Y  .SH SYNOPSIS
Y  .B sa
Y  [
Y***************
Y*** 19,35 ****
Y  savacctfile ] [
Y  .B \-U
Y  usracctfile ] [ file ]
Y- .PP
Y- .B accton 
Y- [ file ]
Y  .SH DESCRIPTION
Y- With an argument naming an existing
Y- .I file,
Y- .I accton
Y- causes system accounting information for
Y- every process executed to be placed at the end of the file.
Y- If no argument is given, accounting is turned off.
Y- .PP
Y  .I Sa
Y  reports on, cleans up, and generally maintains accounting files.
Y  .PP
Y--- 19,25 ----
Y***************
Y*** 146,151 ****
Y  .br
Y  /usr/adm/usracct	per-user summary
Y  .SH "SEE ALSO"
Y! ac(8), acct(2)
Y  .SH BUGS
Y  The number of options to this program is absurd.
Y--- 136,141 ----
Y  .br
Y  /usr/adm/usracct	per-user summary
Y  .SH "SEE ALSO"
Y! ac(8), accton(8), acctd(8)
Y  .SH BUGS
Y  The number of options to this program is absurd.
Y*** /usr/src/sbin/init/init.c.old	Thu May  9 21:33:10 1996
Y--- /usr/src/sbin/init/init.c	Tue Feb 23 21:33:51 1999
Y***************
Y*** 5,11 ****
Y   */
Y  
Y  #if	defined(DOSCCS) && !defined(lint)
Y! static char sccsid[] = "@(#)init.c	5.6.3 (2.11BSD GTE) 1996/5/9";
Y  #endif
Y  
Y  #include <sys/param.h>
Y--- 5,11 ----
Y   */
Y  
Y  #if	defined(DOSCCS) && !defined(lint)
Y! static char sccsid[] = "@(#)init.c	5.6.4 (2.11BSD) 1999/2/23";
Y  #endif
Y  
Y  #include <sys/param.h>
Y***************
Y*** 190,196 ****
Y  {
Y  	register i, f;
Y  
Y- 	acct(0);
Y  	signal(SIGALRM, SIG_DFL);
Y  	for (i = 0; i < 10; i++)
Y  		close(i);
Y--- 190,195 ----
Y*** /VERSION.old	Wed Mar 10 19:40:59 1999
Y--- /VERSION	Tue Mar 30 20:15:24 1999
Y***************
Y*** 1,5 ****
Y! Current Patch Level: 410
Y! Date: March 10, 1999
Y  
Y  2.11 BSD
Y  ============
Y--- 1,5 ----
Y! Current Patch Level: 413
Y! Date: April 16, 1999
Y  
Y  2.11 BSD
Y  ============
SHAR_EOF
chmod 644 '412.patch'
fi
if test -f '412.remove'
then
	echo shar: "will not over-write existing file '412.remove'"
else
sed 's/^Y//' << \SHAR_EOF > '412.remove'
Y#!/bin/sh
Y
Yrm -f /usr/man/cat2/acct.0
Yrm -f /usr/man/cat8/accton.0
SHAR_EOF
chmod 755 '412.remove'
fi
exit 0
#	End of shell archive
