Subject: test(1) and hostname(1) ported from BSD 4.4 (#231)
Index:	/usr/src/bin/test,hostname 2.11BSD

Description:
	Whilst attempting to run some scripts on an 11/73 I discovered that
	test had gained a few switches over the years which were not in 
	the 2.11 version.  I therefore ported test from a 4.4 lite based system
	to 2.11.  In doing this test.c and hostname.c were moved from the 
	/usr/src/bin directory into subdirectories along with their corres-
	ponding manpages.

	This update affects the following:

	added files:
		/usr/src/bin/test
		/usr/src/bin/test.1
		/usr/src/bin/test/test.c
		/usr/src/bin/test/operators.h
		/usr/src/bin/test/operators.c
		/usr/src/bin/test/Makefile
		/usr/src/bin/test/TEST.csh

		/usr/src/bin/hostname
		/usr/src/bin/hostname/hostname.c
		/usr/src/bin/hostname/Makefile
		/usr/src/bin/hostname/hostname.1

	modified files:
		/usr/src/bin/Makefile
		/usr/src/man/man1/Makefile
		/usr/include/sys/stat.h
		/VERSION

	deleted files:
		/usr/src/bin/hostname.c
		/usr/src/bin/test.c
		/usr/src/man/man1/hostname.1
		/usr/src/man/man1/test.1

Repeat-By:
	Inspection.

Fix:
	The style of this update will appear different than previous ones
	because the port of test(1) and hostname(1) was contributed by
	another 2.11 site [Robin Birch (rbirch@ukpoeng.co.uk)].  Thanks, Robin,
	for doing the manpages!  I hope I did not mangle your contribution 
	too badly.

	Save this file into /tmp as /tmp/231 and remove all of the header 
	down to the "cut here" line.

	The file /tmp/231 contains:

		/tmp/script.231
		/tmp/patch.231
		/tmp/shar.231

	/tmp/script.231 is a shell script which will apply the patches,
	unshar the archive of new files, compile and install the new
	programs and then delete the old files.

	NOTE:  You may wish to only read /tmp/script.231 and perform the
	       actual steps yourself.  It is up to you which you prefer doing.

	Then:

	1)  cd /tmp

	2)  /bin/sh /tmp/231

	3)    sh ./script.231
	   or
	      read the script file and perform the steps manually.

	4) rm /tmp/231 /tmp/script.231 /tmp/shar.231 /tmp/patch.231
	   rm /usr/include/sys/stat.h~ /VERSION~ /usr/src/bin/Makefile~
	   rm /usr/src/man/man1/Makefile~

===============================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:
#	/tmp/script.231
#	/tmp/patch.231
#	/tmp/shar.231
# This archive created: Mon Mar 13 21:29:29 1995
export PATH; PATH=/bin:/usr/bin:$PATH
if test -f '/tmp/script.231'
then
	echo shar: "will not over-write existing file '/tmp/script.231'"
else
sed 's/^Z//' << \SHAR_EOF > '/tmp/script.231'
Z#! /bin/sh
Z
Zif [ ! -f /tmp/shar.231 ]; then
Z	echo -n "/tmp/shar.231 - the shar file containing the new files"
Z	echo " was not found."
Z	exit 1
Zfi
Z
Zif [ ! -f /tmp/patch.231 ]; then
Z	echo -n "/tmp/patch.231 - the patch file which updates stat.h and"
Z	echo " various Makefiles was not found."
Z	exit 1
Zfi
Z
Zpatch -p0 < /tmp/patch.231
Z
Zsh /tmp/shar.231
Z
Zcd /usr/src/bin/test
Zmake install
Zmake clean
Z
Zcd /usr/src/bin/hostname
Zmake install
Zmake clean
Z
Zrm -f /usr/src/man/man1/test.1
Zrm -f /usr/src/man/man1/hostname.1
Zrm -f /usr/src/bin/test.c
Zrm -f /usr/src/bin/hostname.c
SHAR_EOF
chmod +x '/tmp/script.231'
fi
if test -f '/tmp/patch.231'
then
	echo shar: "will not over-write existing file '/tmp/patch.231'"
else
sed 's/^Z//' << \SHAR_EOF > '/tmp/patch.231'
Z*** /usr/include/sys/stat.h.old	Mon Nov 28 19:39:43 1994
Z--- /usr/include/sys/stat.h	Mon Mar 13 21:06:42 1995
Z***************
Z*** 3,9 ****
Z   * All rights reserved.  The Berkeley software License Agreement
Z   * specifies the terms and conditions for redistribution.
Z   *
Z!  *	@(#)stat.h	7.1.2 (2.11BSD GTE) 11/25/94
Z   */
Z  
Z  #ifndef	_STAT_H_
Z--- 3,9 ----
Z   * All rights reserved.  The Berkeley software License Agreement
Z   * specifies the terms and conditions for redistribution.
Z   *
Z!  *	@(#)stat.h	7.1.4 (2.11BSD) 1995/03/13
Z   */
Z  
Z  #ifndef	_STAT_H_
Z***************
Z*** 44,49 ****
Z--- 44,70 ----
Z  #define	S_IREAD	0000400		/* read permission, owner */
Z  #define	S_IWRITE 0000200	/* write permission, owner */
Z  #define	S_IEXEC	0000100		/* execute/search permission, owner */
Z+ 
Z+ /*
Z+  * Definitions of flags in mode that are 4.4 compatible.
Z+  */
Z+ 
Z+ #define S_IFIFO 0010000		/* named pipe (fifo) - Not used by 2.11BSD */
Z+ 
Z+ #define S_IRWXU 0000700		/* RWX mask for owner */
Z+ #define S_IRUSR 0000400		/* R for owner */
Z+ #define S_IWUSR 0000200		/* W for owner */
Z+ #define S_IXUSR 0000100		/* X for owner */
Z+ 
Z+ #define S_IRWXG 0000070		/* RWX mask for group */
Z+ #define S_IRGRP 0000040		/* R for group */
Z+ #define S_IWGRP 0000020		/* W for group */
Z+ #define S_IXGRP 0000010		/* X for group */
Z+ 
Z+ #define S_IRWXO 0000007		/* RWX mask for other */
Z+ #define S_IROTH 0000004		/* R for other */
Z+ #define S_IWOTH 0000002		/* W for other */
Z+ #define S_IXOTH 0000001		/* X for other */
Z  
Z  /*
Z   * Definitions of flags stored in file flags word.  Different from 4.4 because
Z*** /usr/src/bin/Makefile.old	Sun Jan 15 22:42:00 1995
Z--- /usr/src/bin/Makefile	Mon Mar 13 20:42:49 1995
Z***************
Z*** 3,9 ****
Z  # All rights reserved.  The Berkeley software License Agreement
Z  # specifies the terms and conditions for redistribution.
Z  #
Z! #	@(#)Makefile	5.19.4 (2.11BSD GTE) 1/15/95
Z  #
Z  DESTDIR=
Z  CFLAGS=	-O
Z--- 3,9 ----
Z  # All rights reserved.  The Berkeley software License Agreement
Z  # specifies the terms and conditions for redistribution.
Z  #
Z! #	@(#)Makefile	5.19.5 (2.11BSD GTE) 1995/03/13
Z  #
Z  DESTDIR=
Z  CFLAGS=	-O
Z***************
Z*** 11,18 ****
Z  
Z  # Programs that live in subdirectories, and have makefiles of their own.
Z  #
Z! SUBDIR=	adb ar as awk chflags chpass csh diff ld login ls make nm passwd \
Z! 	sed sh sysctl tp
Z  
Z  # Shell scripts that need only be installed and are never removed.
Z  #
Z--- 11,18 ----
Z  
Z  # Programs that live in subdirectories, and have makefiles of their own.
Z  #
Z! SUBDIR=	adb ar as awk chflags chpass csh diff hostname ld login ls make nm 
Z! 	passwd sed sh sysctl test tp
Z  
Z  # Shell scripts that need only be installed and are never removed.
Z  #
Z***************
Z*** 22,29 ****
Z  # explicit make lines.
Z  #
Z  STD=	cat cc chgrp chmod cmp cp date dd du echo ed grep hostid \
Z! 	hostname kill ln mkdir mt mv nice od pagesize pr \
Z! 	pwd rm rmail rmdir size stty sync tar tee test time who
Z  
Z  # C programs that live in the current directory and need explicit make lines.
Z  #
Z--- 22,29 ----
Z  # explicit make lines.
Z  #
Z  STD=	cat cc chgrp chmod cmp cp date dd du echo ed grep hostid \
Z! 	kill ln mkdir mt mv nice od pagesize pr \
Z! 	pwd rm rmail rmdir size stty sync tar tee time who
Z  
Z  # C programs that live in the current directory and need explicit make lines.
Z  #
Z***************
Z*** 76,82 ****
Z  		(install -g tty -m 2751 -s $$i ${DESTDIR}/bin/$$i); done
Z  	-install -s -m 751 -g staff strip ${DESTDIR}/bin/xstrip
Z  	-mv ${DESTDIR}/bin/xstrip ${DESTDIR}/bin/strip
Z- 	rm -f ${DESTDIR}/bin/[; ln ${DESTDIR}/bin/test ${DESTDIR}/bin/[
Z  	rm -f ${DESTDIR}/bin/e; ln ${DESTDIR}/bin/ed ${DESTDIR}/bin/e
Z  
Z  clean:
Z--- 76,81 ----
Z*** /usr/src/man/man1/Makefile.old	Thu Jan  5 20:08:57 1995
Z--- /usr/src/man/man1/Makefile	Mon Mar 13 20:53:22 1995
Z***************
Z*** 14,19 ****
Z--- 14,20 ----
Z  # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
Z  # WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
Z  #
Z+ #	@(#)Makefile	1.2 (2.11BSD) 1995/03/13
Z  #
Z  MDIR=	/usr/man/cat1
Z  SRCS=	adb.1 addbib.1 apply.1 apropos.1 as.1 at.1 atq.1 atrm.1 \
Z***************
Z*** 23,29 ****
Z  	dd.1 deroff.1 df.1 diction.1 diff.1 diff3.1 du.1 echo.1 ed.1 \
Z  	efl.1 eqn.1 error.1 ex.1 expand.1 expr.1 f77.1 false.1 file.1 \
Z  	find.1 fmt.1 fold.1 fpr.1 from.1 fsplit.1 gcore.1 \
Z! 	graph.1 grep.1 groups.1 head.1 hostid.1 hostname.1 indent.1 \
Z  	install.1 intro.1 iostat.1 join.1 kill.1 last.1 lastcomm.1 ld.1 \
Z  	learn.1 leave.1 lex.1 lint.1 lisp.1 ln.1 logger.1 login.1 \
Z  	look.1 lookbib.1 lorder.1 lpq.1 lpr.1 lprm.1 lptest.1 ls.1 \
Z--- 24,30 ----
Z  	dd.1 deroff.1 df.1 diction.1 diff.1 diff3.1 du.1 echo.1 ed.1 \
Z  	efl.1 eqn.1 error.1 ex.1 expand.1 expr.1 f77.1 false.1 file.1 \
Z  	find.1 fmt.1 fold.1 fpr.1 from.1 fsplit.1 gcore.1 \
Z! 	graph.1 grep.1 groups.1 head.1 hostid.1 indent.1 \
Z  	install.1 intro.1 iostat.1 join.1 kill.1 last.1 lastcomm.1 ld.1 \
Z  	learn.1 leave.1 lex.1 lint.1 lisp.1 ln.1 logger.1 login.1 \
Z  	look.1 lookbib.1 lorder.1 lpq.1 lpr.1 lprm.1 lptest.1 ls.1 \
Z***************
Z*** 37,43 ****
Z  	sort.1 sortbib.1 spell.1 spline.1 split.1 strcompact.1 strings.1 \
Z  	strip.1 struct.1 stty.1 style.1 su.1 sum.1 symcompact.1 symorder.1 \
Z  	sysline.1 tabs.1 tail.1 talk.1 \
Z! 	tar.1 tbl.1 tc.1 tcopy.1 tee.1 telnet.1 test.1 time.1 \
Z  	tip.1 tk.1 tn3270.1 touch.1 tp.1 tr.1 troff.1 true.1 tset.1 \
Z  	tsort.1 tty.1 ul.1 unifdef.1 uniq.1 units.1 uptime.1 users.1 \
Z  	uucp.1 uuencode.1 uulog.1 uuname.1 uuq.1 uusend.1 uux.1 \
Z--- 38,44 ----
Z  	sort.1 sortbib.1 spell.1 spline.1 split.1 strcompact.1 strings.1 \
Z  	strip.1 struct.1 stty.1 style.1 su.1 sum.1 symcompact.1 symorder.1 \
Z  	sysline.1 tabs.1 tail.1 talk.1 \
Z! 	tar.1 tbl.1 tc.1 tcopy.1 tee.1 telnet.1 time.1 \
Z  	tip.1 tk.1 tn3270.1 touch.1 tp.1 tr.1 troff.1 true.1 tset.1 \
Z  	tsort.1 tty.1 ul.1 unifdef.1 uniq.1 units.1 uptime.1 users.1 \
Z  	uucp.1 uuencode.1 uulog.1 uuname.1 uuq.1 uusend.1 uux.1 \
Z***************
Z*** 51,57 ****
Z  	dd.0 deroff.0 df.0 diction.0 diff.0 diff3.0 du.0 echo.0 ed.0 \
Z  	efl.0 eqn.0 error.0 ex.0 expand.0 expr.0 f77.0 false.0 file.0 \
Z  	find.0 fmt.0 fold.0 fpr.0 from.0 fsplit.0 gcore.0 \
Z! 	graph.0 grep.0 groups.0 head.0 hostid.0 hostname.0 indent.0 \
Z  	install.0 intro.0 iostat.0 join.0 kill.0 last.0 lastcomm.0 ld.0 \
Z  	learn.0 leave.0 lex.0 lint.0 lisp.0 ln.0 logger.0 login.0 \
Z  	look.0 lookbib.0 lorder.0 lpq.0 lpr.0 lprm.0 lptest.0 ls.0 \
Z--- 52,58 ----
Z  	dd.0 deroff.0 df.0 diction.0 diff.0 diff3.0 du.0 echo.0 ed.0 \
Z  	efl.0 eqn.0 error.0 ex.0 expand.0 expr.0 f77.0 false.0 file.0 \
Z  	find.0 fmt.0 fold.0 fpr.0 from.0 fsplit.0 gcore.0 \
Z! 	graph.0 grep.0 groups.0 head.0 hostid.0 indent.0 \
Z  	install.0 intro.0 iostat.0 join.0 kill.0 last.0 lastcomm.0 ld.0 \
Z  	learn.0 leave.0 lex.0 lint.0 lisp.0 ln.0 logger.0 login.0 \
Z  	look.0 lookbib.0 lorder.0 lpq.0 lpr.0 lprm.0 lptest.0 ls.0 \
Z***************
Z*** 65,71 ****
Z  	sort.0 sortbib.0 spell.0 spline.0 split.0 strcompact.0 strings.0 \
Z  	strip.0 struct.0 stty.0 style.0 su.0 sum.0 symcompact.0 symorder.0 \
Z  	sysline.0 tabs.0 tail.0 talk.0 \
Z! 	tar.0 tbl.0 tc.0 tcopy.0 tee.0 telnet.0 test.0 time.0 \
Z  	tip.0 tk.0 tn3270.0 touch.0 tp.0 tr.0 troff.0 true.0 tset.0 \
Z  	tsort.0 tty.0 ul.0 unifdef.0 uniq.0 units.0 uptime.0 users.0 \
Z  	uucp.0 uuencode.0 uulog.0 uuname.0 uuq.0 uusend.0 uux.0 \
Z--- 66,72 ----
Z  	sort.0 sortbib.0 spell.0 spline.0 split.0 strcompact.0 strings.0 \
Z  	strip.0 struct.0 stty.0 style.0 su.0 sum.0 symcompact.0 symorder.0 \
Z  	sysline.0 tabs.0 tail.0 talk.0 \
Z! 	tar.0 tbl.0 tc.0 tcopy.0 tee.0 telnet.0 time.0 \
Z  	tip.0 tk.0 tn3270.0 touch.0 tp.0 tr.0 troff.0 true.0 tset.0 \
Z  	tsort.0 tty.0 ul.0 unifdef.0 uniq.0 units.0 uptime.0 users.0 \
Z  	uucp.0 uuencode.0 uulog.0 uuname.0 uuq.0 uusend.0 uux.0 \
Z*** /VERSION.old	Mon Mar 13 20:20:28 1995
Z--- /VERSION	Mon Mar 13 20:20:34 1995
Z***************
Z*** 1,4 ****
Z! Current Patch Level: 230
Z  
Z  2.11 BSD
Z  ============
Z--- 1,4 ----
Z! Current Patch Level: 231
Z  
Z  2.11 BSD
Z  ============
SHAR_EOF
fi
if test -f '/tmp/shar.231'
then
	echo shar: "will not over-write existing file '/tmp/shar.231'"
else
sed 's/^Z//' << \SHAR_EOF > '/tmp/shar.231'
Z#! /bin/sh
Z# This is a shell archive, meaning:
Z# 1. Remove everything above the #! /bin/sh line.
Z# 2. Save the resulting text in a file.
Z# 3. Execute the file with /bin/sh (not csh) to create:
Z#	/usr/src/bin/test
Z#	/usr/src/bin/hostname
Z# This archive created: Mon Mar 13 21:04:25 1995
Zexport PATH; PATH=/bin:/usr/bin:$PATH
Zif test ! -d '/usr/src/bin/test'
Zthen
Z	mkdir '/usr/src/bin/test'
Zfi
Zcd '/usr/src/bin/test'
Zif test -f 'TEST.csh'
Zthen
Z	echo shar: "will not over-write existing file 'TEST.csh'"
Zelse
Zsed 's/^X//' << \SHAR_EOF > 'TEST.csh'
ZX#	@(#)TEST.csh	5.2 (Berkeley) 4/30/93
ZX#	TEST.csh,v 1.3 1994/09/24 02:59:11 davidg Exp
ZX
ZX#alias t '/usr/src/bin/test/obj/test \!*; echo $status'
ZXalias t '/bin/test \!*; echo $status'
ZX#alias t '/u1/robin/progs/test/test \!*; echo $status'
ZX
ZXecho 't -b /dev/ttyp2'
ZXt -b /dev/ttyp2
ZXecho 't -b /dev/jb1a'
ZXt -b /dev/jb1a
ZX
ZXecho 't -c test.c'
ZXt -c test.c
ZXecho 't -c /dev/tty'
ZXt -c /dev/tty
ZX
ZXecho 't -d test.c'
ZXt -d test.c
ZXecho 't -d /etc'
ZXt -d /etc
ZX
ZXecho 't -e noexist'
ZXt -e noexist
ZXecho 't -e test.c'
ZXt -e test.c
ZX
ZXecho 't -f noexist'
ZXt -f noexist
ZXecho 't -f /dev/tty'
ZXt -f /dev/tty
ZXecho 't -f test.c'
ZXt -f test.c
ZX
ZXecho 't -g test.c'
ZXt -g test.c
ZXecho 't -g /bin/ps'
ZXt -g /bin/ps
ZX
ZXecho 't -n ""'
ZXt -n ""
ZXecho 't -n "hello"'
ZXt -n "hello"
ZX
ZXecho 't -p test.c'
ZXt -p test.c
ZX
ZXecho 't -r noexist'
ZXt -r noexist
ZXecho 't -r /etc/master.passwd'
ZXt -r /etc/master.passwd
ZXecho 't -r test.c'
ZXt -r test.c
ZX
ZXecho 't -s noexist'
ZXt -s noexist
ZXecho 't -s /dev/null'
ZXt -s /dev/null
ZXecho 't -s test.c'
ZXt -s test.c
ZX
ZXecho 't -t 20'
ZXt -t 20
ZXecho 't -t 0'
ZXt -t 0
ZX
ZXecho 't -u test.c'
ZXt -u test.c
ZXecho 't -u /bin/rcp'
ZXt -u /bin/rcp
ZX
ZXecho 't -w noexist'
ZXt -w noexist
ZXecho 't -w /etc/master.passwd'
ZXt -w /etc/master.passwd
ZXecho 't -w /dev/null'
ZXt -w /dev/null
ZX
ZXecho 't -x noexist'
ZXt -x noexist
ZXecho 't -x /bin/ps'
ZXt -x /bin/ps
ZXecho 't -x /etc/motd'
ZXt -x /etc/motd
ZX
ZXecho 't -z ""'
ZXt -z ""
ZXecho 't -z "foo"'
ZXt -z "foo"
ZX
ZXecho 't "foo"'
ZXt "foo"
ZXecho 't ""'
ZXt ""
ZX
ZXecho 't "hello" = "hello"'
ZXt "hello" = "hello"
ZXecho 't "hello" = "goodbye"'
ZXt "hello" = "goodbye"
ZX
ZXecho 't "hello" != "hello"'
ZXt "hello" != "hello"
ZXecho 't "hello" != "goodbye"'
ZXt "hello" != "goodbye"
ZX
ZXecho 't 200 -eq 200'
ZXt 200 -eq 200
ZXecho 't 34 -eq 222'
ZXt 34 -eq 222
ZX
ZXecho 't 200 -ne 200'
ZXt 200 -ne 200
ZXecho 't 34 -ne 222'
ZXt 34 -ne 222
ZX
ZXecho 't 200 -gt 200'
ZXt 200 -gt 200
ZXecho 't 340 -gt 222'
ZXt 340 -gt 222
ZX
ZXecho 't 200 -ge 200'
ZXt 200 -ge 200
ZXecho 't 34 -ge 222'
ZXt 34 -ge 222
ZX
ZXecho 't 200 -lt 200'
ZXt 200 -lt 200
ZXecho 't 34 -lt 222'
ZXt 34 -lt 222
ZX
ZXecho 't 200 -le 200'
ZXt 200 -le 200
ZXecho 't 340 -le 222'
ZXt 340 -le 222
ZX
ZXecho 't 700 -le 1000 -a -n "1" -a "20" = "20"'
ZXt 700 -le 1000 -a -n "1" -a "20" = "20"
ZXecho 't ! \( 700 -le 1000 -a -n "1" -a "20" = "20" \)'
ZXt ! \( 700 -le 1000 -a -n "1" -a "20" = "20" \)
ZX
ZXecho 't -5 -eq 5'
ZXt -5 -eq 5
ZX
ZX
ZXecho 't foo -a ""'
ZXt foo -a ""
ZXecho 't "" -a foo'
ZXt "" -a foo
ZXecho 't "" -a ""'
ZXt "" -a ""
ZXecho 't "" -o ""'
ZXt "" -o ""
ZX
ZSHAR_EOF
Zchmod +x 'TEST.csh'
Zfi
Zif test -f 'operators.c'
Zthen
Z	echo shar: "will not over-write existing file 'operators.c'"
Zelse
Zsed 's/^X//' << \SHAR_EOF > 'operators.c'
ZX/*-
ZX * Copyright (c) 1993, 1994
ZX *	The Regents of the University of California.  All rights reserved.
ZX *
ZX * Redistribution and use in source and binary forms, with or without
ZX * modification, are permitted provided that the following conditions
ZX * are met:
ZX * 1. Redistributions of source code must retain the above copyright
ZX *    notice, this list of conditions and the following disclaimer.
ZX * 2. Redistributions in binary form must reproduce the above copyright
ZX *    notice, this list of conditions and the following disclaimer in the
ZX *    documentation and/or other materials provided with the distribution.
ZX * 3. All advertising materials mentioning features or use of this software
ZX *    must display the following acknowledgement:
ZX *	This product includes software developed by the University of
ZX *	California, Berkeley and its contributors.
ZX * 4. Neither the name of the University nor the names of its contributors
ZX *    may be used to endorse or promote products derived from this software
ZX *    without specific prior written permission.
ZX *
ZX * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ZX * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ZX * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ZX * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
ZX * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ZX * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
ZX * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ZX * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
ZX * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
ZX * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
ZX * SUCH DAMAGE.
ZX *
ZX *	operators.c,v 1.3 1994/09/24 02:59:12 davidg Exp
ZX */
ZX
ZX#if defined(DOSCCS) & !defined(lint)
ZXstatic char sccsid[] = "@(#)operators.c	8.3 (Berkeley) 4/2/94";
ZX#endif /* not lint */
ZX
ZX/*
ZX * Operators used in the test command.
ZX */
ZX
ZX#include <stdio.h>
ZX
ZX#include "operators.h"
ZX
ZXchar unary_op[][4] = {
ZX      "!",
ZX      "-b",
ZX      "-c",
ZX      "-d",
ZX      "-e",
ZX      "-f",
ZX      "-g",
ZX      "-h",
ZX      "-k",
ZX      "-n",
ZX      "-p",
ZX      "-r",
ZX      "-s",
ZX      "-t",
ZX      "-u",
ZX      "-w",
ZX      "-x",
ZX      "-z",
ZX      "ZZZ"
ZX};
ZX
ZXchar binary_op[][4] = {
ZX      "-o",
ZX      "|",
ZX      "-a",
ZX      "&",
ZX      "=",
ZX      "!=",
ZX      "-eq",
ZX      "-ne",
ZX      "-gt",
ZX      "-lt",
ZX      "-le",
ZX      "-ge",
ZX      "ZZZ"
ZX};
ZX
ZXchar andor_op[][4] = {
ZX	"-o",
ZX	"|",
ZX	"-a",
ZX	"&",
ZX	"ZZZ"
ZX};
ZX
ZXint op_priority[] = {
ZX      3,
ZX      12,
ZX      12,
ZX      12,
ZX      12,
ZX      12,
ZX      12,
ZX      12,
ZX      12,
ZX      12,
ZX      12,
ZX      12,
ZX      12,
ZX      12,
ZX      12,
ZX      12,
ZX      12,
ZX      12,
ZX      1,
ZX      1,
ZX      2,
ZX      2,
ZX      4,
ZX      4,
ZX      4,
ZX      4,
ZX      4,
ZX      4,
ZX      4,
ZX      4,
ZX};
ZX
ZXint op_argflag[] = {
ZX      0,
ZX      OP_FILE,
ZX      OP_FILE,
ZX      OP_FILE,
ZX      OP_FILE,
ZX      OP_FILE,
ZX      OP_FILE,
ZX      OP_FILE,
ZX      OP_FILE,
ZX      OP_STRING,
ZX      OP_FILE,
ZX      OP_FILE,
ZX      OP_FILE,
ZX      OP_INT,
ZX      OP_FILE,
ZX      OP_FILE,
ZX      OP_FILE,
ZX      OP_STRING,
ZX      0,
ZX      0,
ZX      0,
ZX      0,
ZX      OP_STRING,
ZX      OP_STRING,
ZX      OP_INT,
ZX      OP_INT,
ZX      OP_INT,
ZX      OP_INT,
ZX      OP_INT,
ZX      OP_INT,
ZX};
ZSHAR_EOF
Zfi
Zif test -f 'operators.h'
Zthen
Z	echo shar: "will not over-write existing file 'operators.h'"
Zelse
Zsed 's/^X//' << \SHAR_EOF > 'operators.h'
ZX/*-
ZX * Copyright (c) 1993, 1994
ZX *	The Regents of the University of California.  All rights reserved.
ZX *
ZX * Redistribution and use in source and binary forms, with or without
ZX * modification, are permitted provided that the following conditions
ZX * are met:
ZX * 1. Redistributions of source code must retain the above copyright
ZX *    notice, this list of conditions and the following disclaimer.
ZX * 2. Redistributions in binary form must reproduce the above copyright
ZX *    notice, this list of conditions and the following disclaimer in the
ZX *    documentation and/or other materials provided with the distribution.
ZX * 3. All advertising materials mentioning features or use of this software
ZX *    must display the following acknowledgement:
ZX *	This product includes software developed by the University of
ZX *	California, Berkeley and its contributors.
ZX * 4. Neither the name of the University nor the names of its contributors
ZX *    may be used to endorse or promote products derived from this software
ZX *    without specific prior written permission.
ZX *
ZX * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ZX * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ZX * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ZX * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
ZX * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ZX * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
ZX * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ZX * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
ZX * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
ZX * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
ZX * SUCH DAMAGE.
ZX *
ZX *	@(#)operators.h	8.3 (Berkeley) 4/2/94
ZX *	operators.h,v 1.3 1994/09/24 02:59:13 davidg Exp
ZX */
ZX
ZX#define	NOT		0
ZX#define	ISBLOCK		1
ZX#define	ISCHAR		2
ZX#define	ISDIR		3
ZX#define	ISEXIST		4
ZX#define	ISFILE		5
ZX#define	ISSETGID	6
ZX#define	ISSYMLINK	7
ZX#define	ISSTICKY	8
ZX#define	STRLEN		9
ZX#define	ISFIFO		10
ZX#define	ISREAD		11
ZX#define	ISSIZE		12
ZX#define	ISTTY		13
ZX#define	ISSETUID	14
ZX#define	ISWRITE		15
ZX#define	ISEXEC		16
ZX#define	NULSTR		17
ZX
ZX#define	FIRST_BINARY_OP	18
ZX#define	OR1		18
ZX#define	OR2		19
ZX#define	AND1		20
ZX#define	AND2		21
ZX#define	STREQ		22
ZX#define	STRNE		23
ZX#define	EQ		24
ZX#define	NE		25
ZX#define	GT		26
ZX#define	LT		27
ZX#define	LE		28
ZX#define	GE		29
ZX
ZX
ZX#define	OP_INT		1	/* arguments to operator are integer */
ZX#define	OP_STRING	2	/* arguments to operator are string */
ZX#define	OP_FILE		3	/* argument is a file name */
ZSHAR_EOF
Zfi
Zif test -f 'test.c'
Zthen
Z	echo shar: "will not over-write existing file 'test.c'"
Zelse
Zsed 's/^X//' << \SHAR_EOF > 'test.c'
ZX/*-
ZX * Copyright (c) 1992, 1993, 1994
ZX *	The Regents of the University of California.  All rights reserved.
ZX *
ZX * This code is derived from software contributed to Berkeley by
ZX * Kenneth Almquist.
ZX *
ZX * Redistribution and use in source and binary forms, with or without
ZX * modification, are permitted provided that the following conditions
ZX * are met:
ZX * 1. Redistributions of source code must retain the above copyright
ZX *    notice, this list of conditions and the following disclaimer.
ZX * 2. Redistributions in binary form must reproduce the above copyright
ZX *    notice, this list of conditions and the following disclaimer in the
ZX *    documentation and/or other materials provided with the distribution.
ZX * 3. All advertising materials mentioning features or use of this software
ZX *    must display the following acknowledgement:
ZX *	This product includes software developed by the University of
ZX *	California, Berkeley and its contributors.
ZX * 4. Neither the name of the University nor the names of its contributors
ZX *    may be used to endorse or promote products derived from this software
ZX *    without specific prior written permission.
ZX *
ZX * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ZX * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ZX * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ZX * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
ZX * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ZX * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
ZX * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ZX * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
ZX * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
ZX * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
ZX * SUCH DAMAGE.
ZX *
ZX *	test.c,v 1.9 1994/11/05 20:48:06 ache Exp
ZX */
ZX
ZX#if defined(DOSCCS) & !defined(lint)
ZXstatic char copyright[] =
ZX"@(#) Copyright (c) 1992, 1993, 1994\n\
ZX	The Regents of the University of California.  All rights reserved.\n";
ZX#endif /* not lint */
ZX
ZX#if	defined(DOSCCS) & !defined(lint)
ZXstatic char sccsid[] = "@(#)test.c	8.3.1 (2.11BSD) 1995/03/13";
ZX#endif /* not lint */
ZX
ZX#include <sys/types.h>
ZX#include <sys/stat.h>
ZX#include <sys/param.h>
ZX
ZX#include <ctype.h>
ZX#include <errno.h>
ZX#include <stdio.h>
ZX#include <string.h>
ZX
ZX#include "operators.h"
ZX
ZX#define	STACKSIZE	12
ZX#define	NESTINCR	16
ZX
ZX/* data types */
ZX#define	STRING	0
ZX#define	INTEGER	1
ZX#define	BOOLEAN	2
ZX
ZX#define	IS_BANG(s) (s[0] == '!' && s[1] == '\0')
ZX
ZX/*
ZX * This structure hold a value.  The type keyword specifies the type of
ZX * the value, and the union u holds the value.  The value of a boolean
ZX * is stored in u.num (1 = TRUE, 0 = FALSE).
ZX */
ZXstruct value {
ZX	int type;
ZX	union {
ZX		char *string;
ZX		long num;
ZX	} u;
ZX};
ZX
ZXstruct operator {
ZX	short op;		/* Which operator. */
ZX	short pri;		/* Priority of operator. */
ZX};
ZX
ZXstruct filestat {
ZX	char *name;		/* Name of file. */
ZX	int rcode;		/* Return code from stat. */
ZX	struct stat stat;	/* Status info on file. */
ZX};
ZX
ZXextern char unary_op[][4];
ZXextern char binary_op[][4];
ZXextern char andor_op[][4];
ZXextern int op_priority[];
ZXextern int op_argflag[];
ZXextern long atol();
ZX
ZXmain(argc, argv)
ZX	int argc;
ZX	char *argv[];
ZX{
ZX
ZX	struct operator opstack[STACKSIZE];
ZX	register struct operator *opsp;
ZX	struct value valstack[STACKSIZE + 1];
ZX	register struct value *valsp;
ZX	struct filestat fs;
ZX	char  c, **ap, *opname, *p;
ZX	int binary, nest, op, pri, ret_val, skipping;
ZX
ZX	if ((p = argv[0]) == NULL)
ZX		errx(2, "test: argc is zero");
ZX
ZX	if (*p != '\0' && p[strlen(p) - 1] == '[') {
ZX		if (strcmp(argv[--argc], "]"))
ZX			errx(2, "missing ]");
ZX		argv[argc] = NULL;
ZX	}
ZX	ap = argv + 1;
ZX	fs.name = NULL;
ZX
ZX	/*
ZX	 * Test(1) implements an inherently ambiguous grammer.  In order to
ZX	 * assure some degree of consistency, we special case the POSIX 1003.2
ZX	 * requirements to assure correct evaluation for POSIX scripts.  The
ZX	 * following special cases comply with POSIX P1003.2/D11.2 Section
ZX	 * 4.62.4.
ZX	 */
ZX	switch(argc - 1) {
ZX	case 0:				/* % test */
ZX		return (1);
ZX		break;
ZX	case 1:				/* % test arg */
ZX		return (argv[1] == NULL || *argv[1] == '\0') ? 1 : 0;
ZX		break;
ZX	case 2:				/* % test op arg */
ZX		opname = argv[1];
ZX		if (IS_BANG(opname))
ZX			return (*argv[2] == '\0') ? 0 : 1;
ZX		else {
ZX			ret_val = posix_unary_op(&argv[1]);
ZX			if (ret_val >= 0)
ZX				return (ret_val);
ZX		}
ZX		break;
ZX	case 3:				/* % test arg1 op arg2 */
ZX		if (IS_BANG(argv[1])) {
ZX			ret_val = posix_unary_op(&argv[1]);
ZX			if (ret_val >= 0)
ZX				return (!ret_val);
ZX		} else {
ZX			ret_val = posix_binary_op(&argv[1]);
ZX			if (ret_val >= 0)
ZX				return (ret_val);
ZX		}
ZX		break;
ZX	case 4:				/* % test ! arg1 op arg2 */
ZX		if (IS_BANG(argv[1]) && lookup_op(argv[3], andor_op) < 0 ) {
ZX			ret_val = posix_binary_op(&argv[2]);
ZX			if (ret_val >= 0)
ZX				return (!ret_val);
ZX		}
ZX		break;
ZX	default:
ZX		break;
ZX	}
ZX
ZX	/*
ZX	 * We use operator precedence parsing, evaluating the expression as
ZX	 * we parse it.  Parentheses are handled by bumping up the priority
ZX	 * of operators using the variable "nest."  We use the variable
ZX	 * "skipping" to turn off evaluation temporarily for the short
ZX	 * circuit boolean operators.  (It is important do the short circuit
ZX	 * evaluation because under NFS a stat operation can take infinitely
ZX	 * long.)
ZX	 */
ZX	opsp = opstack + STACKSIZE;
ZX	valsp = valstack;
ZX	nest = skipping = 0;
ZX	if (*ap == NULL) {
ZX		valstack[0].type = BOOLEAN;
ZX		valstack[0].u.num = 0;
ZX		goto done;
ZX	}
ZX	for (;;) {
ZX		opname = *ap++;
ZX		if (opname == NULL)
ZX			syntax();
ZX		if (opname[0] == '(' && opname[1] == '\0') {
ZX			nest += NESTINCR;
ZX			continue;
ZX		} else if (*ap && (op = lookup_op(opname, unary_op)) >= 0) {
ZX			if (opsp == &opstack[0])
ZX				overflow();
ZX			--opsp;
ZX			opsp->op = op;
ZX			opsp->pri = op_priority[op] + nest;
ZX			continue;
ZX		} else {
ZX			valsp->type = STRING;
ZX			valsp->u.string = opname;
ZX			valsp++;
ZX		}
ZX		for (;;) {
ZX			opname = *ap++;
ZX			if (opname == NULL) {
ZX				if (nest != 0)
ZX					syntax();
ZX				pri = 0;
ZX				break;
ZX			}
ZX			if (opname[0] != ')' || opname[1] != '\0') {
ZX				if ((op = lookup_op(opname, binary_op)) < 0)
ZX					syntax();
ZX				op += FIRST_BINARY_OP;
ZX				pri = op_priority[op] + nest;
ZX				break;
ZX			}
ZX			if ((nest -= NESTINCR) < 0)
ZX				syntax();
ZX		}
ZX		while (opsp < &opstack[STACKSIZE] && opsp->pri >= pri) {
ZX			binary = opsp->op;
ZX			for (;;) {
ZX				valsp--;
ZX				c = op_argflag[opsp->op];
ZX				if (c == OP_INT) {
ZX					if (valsp->type == STRING)
ZX						get_int(valsp->u.string,
ZX						    &valsp->u.num);
ZX					valsp->type = INTEGER;
ZX				} else if (c >= OP_STRING) {	
ZX					            /* OP_STRING or OP_FILE */
ZX					if (valsp->type == INTEGER) {
ZX						if ((p = (char *)malloc(32)) == NULL)
ZX							err(2, NULL);
ZX#ifdef SHELL
ZX						fmtstr(p, 32, "%d", 
ZX						    valsp->u.num);
ZX#else
ZX						(void)sprintf(p,
ZX						    "%d", valsp->u.num);
ZX#endif
ZX						valsp->u.string = p;
ZX					} else if (valsp->type == BOOLEAN) {
ZX						if (valsp->u.num)
ZX							valsp->u.string = 
ZX						            "true";
ZX						else
ZX							valsp->u.string = "";
ZX					}
ZX					valsp->type = STRING;
ZX					if (c == OP_FILE && (fs.name == NULL ||
ZX					    strcmp(fs.name, valsp->u.string))) {
ZX						fs.name = valsp->u.string;
ZX						fs.rcode = 
ZX						    stat(valsp->u.string, 
ZX                                                    &fs.stat);
ZX					}
ZX				}
ZX				if (binary < FIRST_BINARY_OP)
ZX					break;
ZX				binary = 0;
ZX			}
ZX			if (!skipping)
ZX				expr_operator(opsp->op, valsp, &fs);
ZX			else if (opsp->op == AND1 || opsp->op == OR1)
ZX				skipping--;
ZX			valsp++;		/* push value */
ZX			opsp++;			/* pop operator */
ZX		}
ZX		if (opname == NULL)
ZX			break;
ZX		if (opsp == &opstack[0])
ZX			overflow();
ZX		if (op == AND1 || op == AND2) {
ZX			op = AND1;
ZX			if (skipping || expr_is_false(valsp - 1))
ZX				skipping++;
ZX		}
ZX		if (op == OR1 || op == OR2) {
ZX			op = OR1;
ZX			if (skipping || !expr_is_false(valsp - 1))
ZX				skipping++;
ZX		}
ZX		opsp--;
ZX		opsp->op = op;
ZX		opsp->pri = pri;
ZX	}
ZXdone:	return (expr_is_false(&valstack[0]));
ZX}
ZX
ZXint
ZXexpr_is_false(val)
ZX	register struct value *val;
ZX{
ZX
ZX	if (val->type == STRING) {
ZX		if (val->u.string[0] == '\0')
ZX			return (1);
ZX	} else {		/* INTEGER or BOOLEAN */
ZX		if (val->u.num == 0)
ZX			return (1);
ZX	}
ZX	return (0);
ZX}
ZX
ZX
ZX/*
ZX * Execute an operator.  Op is the operator.  Sp is the stack pointer;
ZX * sp[0] refers to the first operand, sp[1] refers to the second operand
ZX * (if any), and the result is placed in sp[0].  The operands are converted
ZX * to the type expected by the operator before expr_operator is called.
ZX * Fs is a pointer to a structure which holds the value of the last call
ZX * to stat, to avoid repeated stat calls on the same file.
ZX */
ZXvoid
ZXexpr_operator(op, sp, fs)
ZX	int op;
ZX	register struct value *sp;
ZX	struct filestat *fs;
ZX{
ZX	register int i;
ZX
ZX	switch (op) {
ZX	case NOT:
ZX		sp->u.num = expr_is_false(sp);
ZX		sp->type = BOOLEAN;
ZX		break;
ZX	case ISEXIST:
ZXexist:
ZX		if (fs == NULL || fs->rcode == -1)
ZX			goto false;
ZX		else
ZX			goto true;
ZX	case ISREAD:
ZX		if (geteuid() == 0)
ZX			goto exist;
ZX		i = S_IROTH;
ZX		goto permission;
ZX	case ISWRITE:
ZX		if (geteuid() != 0)
ZX			i = S_IWOTH;
ZX		else {
ZX			i = S_IWOTH|S_IWGRP|S_IWUSR;
ZX			goto filebit;
ZX		}
ZX		goto permission;
ZX	case ISEXEC:
ZX		if (geteuid() != 0) {
ZX			i = S_IXOTH;
ZXpermission:		if (fs->stat.st_uid == geteuid())
ZX				i <<= 6;
ZX			else {
ZX				gid_t grlist[NGROUPS];
ZX				int ngroups, j;
ZX
ZX				ngroups = getgroups(NGROUPS, grlist);
ZX				for (j = 0; j < ngroups; j++)
ZX					if (fs->stat.st_gid == grlist[j]) {
ZX						i <<= 3;
ZX						goto filebit;
ZX					}
ZX			}
ZX		} else
ZX			i = S_IXOTH|S_IXGRP|S_IXUSR;
ZX		goto filebit;	/* true if (stat.st_mode & i) != 0 */
ZX	case ISFILE:
ZX		i = S_IFREG;
ZX		goto filetype;
ZX	case ISDIR:
ZX		i = S_IFDIR;
ZX		goto filetype;
ZX	case ISCHAR:
ZX		i = S_IFCHR;
ZX		goto filetype;
ZX	case ISBLOCK:
ZX		i = S_IFBLK;
ZX		goto filetype;
ZX	case ISSYMLINK:
ZX		i = S_IFLNK;
ZX		(void)lstat(sp->u.string, &fs->stat);
ZX		goto filetype;
ZX	case ISFIFO:
ZX		i = S_IFIFO;
ZX		goto filetype;
ZXfiletype:	if ((fs->stat.st_mode & S_IFMT) == i && fs->rcode >= 0)
ZXtrue:			sp->u.num = 1;
ZX		else
ZXfalse:			sp->u.num = 0;
ZX		sp->type = BOOLEAN;
ZX		break;
ZX	case ISSETUID:
ZX		i = S_ISUID;
ZX		goto filebit;
ZX	case ISSETGID:
ZX		i = S_ISGID;
ZX		goto filebit;
ZX	case ISSTICKY:
ZX		i = S_ISVTX;
ZXfilebit:	if (fs->stat.st_mode & i && fs->rcode >= 0)
ZX			goto true;
ZX		goto false;
ZX	case ISSIZE:
ZX		sp->u.num = fs->rcode >= 0 ? fs->stat.st_size : 0L;
ZX		sp->type = INTEGER;
ZX		break;
ZX	case ISTTY:
ZX		sp->u.num = isatty(sp->u.num);
ZX		sp->type = BOOLEAN;
ZX		break;
ZX	case NULSTR:
ZX		if (sp->u.string[0] == '\0')
ZX			goto true;
ZX		goto false;
ZX	case STRLEN:
ZX		sp->u.num = strlen(sp->u.string);
ZX		sp->type = INTEGER;
ZX		break;
ZX	case OR1:
ZX	case AND1:
ZX		/*
ZX		 * These operators are mostly handled by the parser.  If we
ZX		 * get here it means that both operands were evaluated, so
ZX		 * the value is the value of the second operand.
ZX		 */
ZX		*sp = *(sp + 1);
ZX		break;
ZX	case STREQ:
ZX	case STRNE:
ZX		i = 0;
ZX		if (!strcmp(sp->u.string, (sp + 1)->u.string))
ZX			i++;
ZX		if (op == STRNE)
ZX			i = 1 - i;
ZX		sp->u.num = i;
ZX		sp->type = BOOLEAN;
ZX		break;
ZX	case EQ:
ZX		if (sp->u.num == (sp + 1)->u.num)
ZX			goto true;
ZX		goto false;
ZX	case NE:
ZX		if (sp->u.num != (sp + 1)->u.num)
ZX			goto true;
ZX		goto false;
ZX	case GT:
ZX		if (sp->u.num > (sp + 1)->u.num)
ZX			goto true;
ZX		goto false;
ZX	case LT:
ZX		if (sp->u.num < (sp + 1)->u.num)
ZX			goto true;
ZX		goto false;
ZX	case LE:
ZX		if (sp->u.num <= (sp + 1)->u.num)
ZX			goto true;
ZX		goto false;
ZX	case GE:
ZX		if (sp->u.num >= (sp + 1)->u.num)
ZX			goto true;
ZX		goto false;
ZX
ZX	}
ZX}
ZX
ZXint
ZXlookup_op(name, table)
ZX	char *name;
ZX	char *table;
ZX{
ZX	char *tp;
ZX	char c;
ZX	int  i;
ZX
ZX	c = name[1];
ZX	tp = table;
ZX	for(i = 0; strcmp((char *)(tp + i),"ZZZ") ; i=i+4){
ZX		if ((char)(tp + i)[1] == c && !strcmp((char *)(tp + i), name))
ZX			return (i/4);
ZX		} 
ZX	return (-1);
ZX}
ZX
ZXint
ZXposix_unary_op(argv)
ZX	char **argv;
ZX{
ZX	struct filestat fs;
ZX	struct value valp;
ZX	int op, c;
ZX	char *opname;
ZX
ZX	opname = *argv;
ZX	if ((op = lookup_op(opname, unary_op)) < 0)
ZX		return (-1);
ZX	c = op_argflag[op];
ZX	opname = argv[1];
ZX	valp.u.string = opname;
ZX	if (c == OP_FILE) {
ZX		fs.name = opname;
ZX		fs.rcode = stat(opname, &fs.stat);
ZX	} else if (c != OP_STRING)
ZX		return (-1);
ZX
ZX	expr_operator(op, &valp, &fs);
ZX	return (valp.u.num == 0);
ZX}
ZX
ZXint
ZXposix_binary_op(argv)
ZX	char  **argv;
ZX{
ZX	struct value v[2];
ZX	int op, c;
ZX	char *opname;
ZX
ZX	opname = argv[1];
ZX	if ((op = lookup_op(opname, binary_op)) < 0)
ZX		return (-1);
ZX	op += FIRST_BINARY_OP;
ZX	c = op_argflag[op];
ZX
ZX	if (c == OP_INT) {
ZX		get_int(argv[0], &v[0].u.num);
ZX		get_int(argv[2], &v[1].u.num);
ZX	} else {
ZX		v[0].u.string = argv[0];
ZX		v[1].u.string = argv[2];
ZX	}
ZX	expr_operator(op, v, NULL);
ZX	return (v[0].u.num == 0);
ZX}
ZX
ZX/*
ZX * Integer type checking.
ZX */
ZXvoid
ZXget_int(v, lp)
ZX	register char *v;
ZX	long *lp;
ZX{
ZX
ZX	for (; *v && isspace(*v); ++v);
ZX
ZX	if(!*v) {
ZX		*lp = 0;
ZX		return;
ZX	}
ZX
ZX	if (isdigit(*v) || ((*v == '-' || *v == '+') && isdigit(*(v+1)))) {
ZX		*lp = atol(v);
ZX		return;
ZX	}
ZX	errx(2, "%s: expected integer", v);
ZX}
ZX
ZXvoid
ZXsyntax()
ZX{
ZX
ZX	err(2, "syntax error");
ZX}
ZX
ZXvoid
ZXoverflow()
ZX{
ZX
ZX	err(2, "expression is too complex");
ZX}
ZSHAR_EOF
Zfi
Zif test -f 'test.1'
Zthen
Z	echo shar: "will not over-write existing file 'test.1'"
Zelse
Zsed 's/^X//' << \SHAR_EOF > 'test.1'
ZX.\" Copyright (c) 1991, 1993
ZX.\"	The Regents of the University of California.  All rights reserved.
ZX.\"
ZX.\" This code is derived from software contributed to Berkeley by
ZX.\" the Institute of Electrical and Electronics Engineers, Inc.
ZX.\"
ZX.\" Redistribution and use in source and binary forms, with or without
ZX.\" modification, are permitted provided that the following conditions
ZX.\" are met:
ZX.\" 1. Redistributions of source code must retain the above copyright
ZX.\"    notice, this list of conditions and the following disclaimer.
ZX.\" 2. Redistributions in binary form must reproduce the above copyright
ZX.\"    notice, this list of conditions and the following disclaimer in the
ZX.\"    documentation and/or other materials provided with the distribution.
ZX.\" 3. All advertising materials mentioning features or use of this software
ZX.\"    must display the following acknowledgement:
ZX.\"	This product includes software developed by the University of
ZX.\"	California, Berkeley and its contributors.
ZX.\" 4. Neither the name of the University nor the names of its contributors
ZX.\"    may be used to endorse or promote products derived from this software
ZX.\"    without specific prior written permission.
ZX.\"
ZX.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ZX.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ZX.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ZX.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
ZX.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ZX.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
ZX.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ZX.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
ZX.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
ZX.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
ZX.\" SUCH DAMAGE.
ZX.\"
ZX.\"     @(#)test.1	8.1.2 (2.11BSD) 1995/03/13
ZX.\"	test.1,v 1.2 1994/09/24 02:59:14 davidg Exp
ZX.\"
ZX.TH TEST 1 "March 13, 1995"
ZX.AT 3
ZX.SH NAME
ZXtest \- condition evaluation utility
ZX.SH SYNOPSIS
ZX.B test
ZX.I expression
ZX.SH DESCRIPTION
ZXThe
ZX.I test
ZXutility evaluates the expression and, if it evaluates
ZXto true, returns a zero (true) exit status; otherwise
ZXit returns 1 (false).
ZXIf there is no expression, test also
ZXreturns 1 (false).
ZX.PP
ZXAll operators and flags are separate arguments to the
ZX.I test
ZXutility.
ZX.PP
ZXThe following primaries are used to construct expression:
ZX.TP
ZX\fB \-b \fP \fI file \fP
ZXTrue if
ZX.I file
ZXexists and is a block special
ZXfile.
ZX.TP
ZX\fB \-c \fP \fI file \fP
ZXTrue if
ZX.I file
ZXexists and is a character
ZXspecial file.
ZX.TP
ZX\fB \-d \fP \fI file \fP
ZXTrue if
ZX.I file
ZXexists and is a directory.
ZX.TP
ZX\fB \-e \fP \fI file \fP
ZXTrue if
ZX.I file
ZXexists (regardless of type).
ZX.TP
ZX\fB \-f \fP \fI file \fP
ZXTrue if
ZX.I file
ZXexists and is a regular file.
ZX.TP
ZX\fB \-g \fP \fI file \fP
ZXTrue if
ZX.I file
ZXexists and its set group ID flag
ZXis set.
ZX.TP
ZX\fB \-h \fP \fI file \fP
ZXTrue if
ZX.I file
ZXexists and is a symbolic link.
ZX.TP
ZX\fB \-n \fP \fI string \fP
ZXTrue if the length of
ZX.I string
ZXis nonzero.
ZX.TP
ZX\fB \-p \fP \fI file \fP
ZXTrue if
ZX.I file
ZXis a named pipe
ZX.Po Tn FIFO Pc .
ZX.TP
ZX\fB \-r \fP \fI file \fP
ZXTrue if
ZX.I file 
ZXexists and is readable.
ZX.TP
ZX\fB \-s \fP \fI file \fP
ZXTrue if
ZX.I file
ZXexists and has a size greater
ZXthan zero.
ZX.TP
ZX\fB \-t \fp \fI [file_descriptor] \fP
ZXTrue if the file whose file descriptor number
ZXis
ZX.I file_descriptor
ZX(default 1) is open and is
ZXassociated with a terminal.
ZX.TP
ZX\fB \-u \fP \fI file \fP
ZXTrue if
ZX.I file
ZXexists and its set user ID flag
ZXis set.
ZX.TP
ZX\fB \-w \fP \fI file \fP
ZXTrue if
ZX.I file
ZXexists and is writable.
ZXTrue indicates only that the write flag is on.
ZXThe file is not writable on a read-only file
ZXsystem even if this test indicates true.
ZX.TP
ZX\fB \-x \fP \fI file \fP
ZXTrue if
ZX.I file
ZXexists and is executable.
ZXTrue indicates only that the execute flag is on.
ZXIf
ZX.I file
ZXis a directory, true 
ZXindicates that
ZX.I file
ZXcan be searched.
ZX.TP
ZX\fB \-z \fP \fI string \fP
ZXTrue if the length of
ZX.I string
ZXis zero.
ZX.TP
ZX\fI string \fP
ZXTrue if
ZX.I string
ZXis not the null
ZXstring.
ZX.TP
ZX\fI s1 \fP \fB = \fP \fI s2 \fP
ZXTrue if the strings
ZX.I s1
ZXand
ZX.I s2
ZXare identical.
ZX.TP
ZX\fI s1 \fP \fB != \fP \fI s2 \fP
ZXTrue if the strings
ZX.I s1
ZXand
ZX.I s2
ZXare not identical.
ZX.TP
ZX\fI n1 \fP \fB \-eq \fP \fI n2 \fP
ZXTrue if the integers
ZX.I n1
ZXand
ZX.I n2
ZXare algebraically
ZXequal.
ZX.TP
ZX\fI n1 \fP \fB \-ne \fP \fI n2 \fP
ZXTrue if the integers
ZX.I n1
ZXand
ZX.I n2
ZXare not
ZXalgebraically equal.
ZX.TP
ZX\fI n1 \fP \fB \-gt \fP \fI n2 \fP
ZXTrue if the integer
ZX.I n1
ZXis algebraically
ZXgreater than the integer
ZX.I n2 .
ZX.TP
ZX\fI n1 \fP \fB \-ge \fP \fI n2 \fP
ZXTrue if the integer
ZX.I n1
ZXis algebraically
ZXgreater than or equal to the integer
ZX.I n2 .
ZX.TP
ZX\fI n1 \fP \fB \-lt \fP \fI n2 \fP
ZXTrue if the integer
ZX.I n1
ZXis algebraically less
ZXthan the integer
ZX.I n2 .
ZX.TP
ZX\fI n1 \fP \fB \-le \fP \fI n2 \fP
ZXTrue if the integer
ZX.I n1
ZXis algebraically less
ZXthan or equal to the integer
ZX.I n2 .
ZX.TP
ZX.PP
ZXThese primaries can be combined with the following operators:
ZX.TP
ZX.B ! expression
ZXTrue if
ZX.I expression
ZXis false.
ZX.TP
ZX\fI expression1 \fP \fB \-a \fP \fI expression2 \fP
ZXTrue if both
ZX.I expression1
ZXand
ZX.I expression2
ZXare true.
ZX.TP
ZX\fI expression1 \fP \fB \-o \fP \fI expression2 \fP
ZXTrue if either
ZX.I expression1
ZXor
ZX.I expression2
ZXare true.
ZX.TP
ZX\fI (expression) \fP
ZXTrue if expression is true.
ZX.TP
ZX.PP
ZXThe
ZX.B \-a
ZXoperator has higher precedence than the
ZX.B \-o
ZXoperator.
ZX.SH GRAMMAR AMBIGUITY
ZXThe 
ZX.B test
ZXgrammar is inherently ambiguous.  In order to assure a degree of consistency,
ZXthe cases described in the 
ZXIEEE Std 1003.2 ("POSIX"), 
ZXsection D11.2/4.62.4, standard
ZXare evaluated consistently according to the rules specified in the
ZXstandards document.  All other cases are subject to the ambiguity in the
ZXcommand semantics.
ZX.SH RETURN VALUES
ZXThe
ZX.B test
ZXutility exits with one of the following values:
ZX.TP
ZX.B 0
ZXexpression evaluated to true.
ZX.TP
ZX.B 1
ZXexpression evaluated to false or expression was
ZXmissing.
ZX.TP
ZX.B >1
ZXAn error occurred.
ZX.SH BUGS
ZXNamed pipes are not implemented in 2.11BSD.
ZX.SH STANDARDS
ZXThe
ZX.B test
ZXfunction is expected to be
ZXIEEE Std 1003.2 ("POSIX")
ZXcompatible.
ZSHAR_EOF
Zfi
Zif test -f 'Makefile'
Zthen
Z	echo shar: "will not over-write existing file 'Makefile'"
Zelse
Zsed 's/^X//' << \SHAR_EOF > 'Makefile'
ZX#	Makefile for test
ZX#
ZX#	Robin Birch	11 march 1995
ZX#
ZX#	Version 1.1
ZX#
ZXSEPFLAG= -i
ZXCFLAGS = -O
ZX
ZXSRCS = test.c operators.c
ZXOBJS = test.o operators.o
ZX
ZXall:	test test.0
ZX
ZXtest:	${OBJS}
ZX	${CC} ${SEPFLAG} -o test ${OBJS}
ZX
ZXtest.0: test.1
ZX	/usr/man/manroff test.1 > test.0
ZX
ZXinstall: all
ZX	install -s -m 755 -g bin -o bin test ${DESTDIR}/bin
ZX	rm -f ${DESTDIR}/bin/[
ZX	ln ${DESTDIR}/bin/test ${DESTDIR}/bin/[
ZX	install -m 444 -g bin -o bin test.0 ${DESTDIR}/usr/man/cat1
ZX
ZXclean:	
ZX	rm -f *.o test *.core test.0
ZSHAR_EOF
Zfi
Zcd ..
Zif test ! -d '/usr/src/bin/hostname'
Zthen
Z	mkdir '/usr/src/bin/hostname'
Zfi
Zcd '/usr/src/bin/hostname'
Zif test -f 'hostname.1'
Zthen
Z	echo shar: "will not over-write existing file 'hostname.1'"
Zelse
Zsed 's/^X//' << \SHAR_EOF > 'hostname.1'
ZX.\" Copyright (c) 1983, 1988, 1990, 1993
ZX.\"	The Regents of the University of California.  All rights reserved.
ZX.\"
ZX.\" Redistribution and use in source and binary forms, with or without
ZX.\" modification, are permitted provided that the following conditions
ZX.\" are met:
ZX.\" 1. Redistributions of source code must retain the above copyright
ZX.\"    notice, this list of conditions and the following disclaimer.
ZX.\" 2. Redistributions in binary form must reproduce the above copyright
ZX.\"    notice, this list of conditions and the following disclaimer in the
ZX.\"    documentation and/or other materials provided with the distribution.
ZX.\" 3. All advertising materials mentioning features or use of this software
ZX.\"    must display the following acknowledgement:
ZX.\"	This product includes software developed by the University of
ZX.\"	California, Berkeley and its contributors.
ZX.\" 4. Neither the name of the University nor the names of its contributors
ZX.\"    may be used to endorse or promote products derived from this software
ZX.\"    without specific prior written permission.
ZX.\"
ZX.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ZX.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ZX.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ZX.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
ZX.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ZX.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
ZX.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ZX.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
ZX.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
ZX.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
ZX.\" SUCH DAMAGE.
ZX.\"
ZX.\"	@(#)hostname.1	8.1 (Berkeley) 5/31/93
ZX.\"	hostname.1,v 1.2 1994/09/24 02:55:40 davidg Exp
ZX.\"	hostname.1,v 1.2.1 29/1/95 Robin Birch
ZX.\"
ZX.TH HOSTNAME 1 "January 29, 1995"
ZX.SH NAME
ZXhostname \- set or print name of current host system
ZX.SH SYNOPSIS
ZX.B hostname
ZX[
ZX.B \-s
ZX] [ 
ZX.B nameofhost 
ZX]
ZX.PP
ZX.SH DESCRIPTION
ZX.I Hostname
ZXprints the name of the current host.  The super-user can
ZXset the hostname by supplying an argument; this is usually done in the
ZXnetwork initialization script
ZX.I /etc/netstart ,
ZXnormally run at boot
ZXtime.
ZX.PP
ZXOptions:
ZX.TP
ZX.B \-\^s
ZXTrims off any domain information from the printed
ZXname.
ZX.br
ZX.sp
ZX.SH SEE ALSO
ZXgethostname(2), sethostname(2)
ZX.SH HISTORY
ZXThe
ZX.I hostname
ZXcommand appeared in
ZXBSD 4.2 .
ZSHAR_EOF
Zfi
Zif test -f 'hostname.c'
Zthen
Z	echo shar: "will not over-write existing file 'hostname.c'"
Zelse
Zsed 's/^X//' << \SHAR_EOF > 'hostname.c'
ZX/*
ZX * Copyright (c) 1988, 1993
ZX *	The Regents of the University of California.  All rights reserved.
ZX *
ZX * Redistribution and use in source and binary forms, with or without
ZX * modification, are permitted provided that the following conditions
ZX * are met:
ZX * 1. Redistributions of source code must retain the above copyright
ZX *    notice, this list of conditions and the following disclaimer.
ZX * 2. Redistributions in binary form must reproduce the above copyright
ZX *    notice, this list of conditions and the following disclaimer in the
ZX *    documentation and/or other materials provided with the distribution.
ZX * 3. All advertising materials mentioning features or use of this software
ZX *    must display the following acknowledgement:
ZX *	This product includes software developed by the University of
ZX *	California, Berkeley and its contributors.
ZX * 4. Neither the name of the University nor the names of its contributors
ZX *    may be used to endorse or promote products derived from this software
ZX *    without specific prior written permission.
ZX *
ZX * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ZX * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ZX * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ZX * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
ZX * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ZX * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
ZX * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
ZX * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
ZX * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
ZX * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
ZX * SUCH DAMAGE.
ZX *
ZX *	hostname.c,v 1.2 1994/09/24 02:55:40 davidg Exp
ZX */
ZX
ZX#if defined(DOSCCS) & !defined(lint)
ZXstatic char copyright[] =
ZX"@(#) Copyright (c) 1988, 1993\n\
ZX	The Regents of the University of California.  All rights reserved.\n";
ZX#endif /* not lint */
ZX
ZX#if defined(DOSCCS) & !defined(lint)
ZXstatic char sccsid[] = "@(#)hostname.c	8.1.1 (R.Birch) 8/2/95";
ZX#endif /* not lint */
ZX
ZX#include <sys/param.h>
ZX
ZX#include <stdio.h>
ZX#include <string.h>
ZX
ZXint
ZXmain(argc,argv)
ZX	int argc;
ZX	char *argv[];
ZX{
ZX	extern int optind;
ZX	int ch, sflag;
ZX	char *p, hostname[MAXHOSTNAMELEN];
ZX
ZX	sflag = 0;
ZX	while ((ch = getopt(argc, argv, "s")) != EOF)
ZX		switch (ch) {
ZX		case 's':
ZX			sflag = 1;
ZX			break;
ZX		case '?':
ZX		default:
ZX			(void)fprintf(stderr,
ZX			    "usage: hostname [-s] [hostname]\n");
ZX			exit(1);
ZX		}
ZX	argc -= optind;
ZX	argv += optind;
ZX
ZX	if (*argv) {
ZX		if (sethostname(*argv, strlen(*argv)))
ZX			err(1, "sethostname");
ZX	} else {
ZX		if (gethostname(hostname, sizeof(hostname)))
ZX			err(1, "gethostname");
ZX		if (sflag && (p = strchr(hostname, '.')))
ZX			*p = '\0';
ZX		(void)printf("%s\n", hostname);
ZX	}
ZX	exit(0);
ZX}
ZSHAR_EOF
Zfi
Zif test -f 'Makefile'
Zthen
Z	echo shar: "will not over-write existing file 'Makefile'"
Zelse
Zsed 's/^X//' << \SHAR_EOF > 'Makefile'
ZX#
ZX# Public Domain.  1995/03/13 - Steven Schultz
ZX#
ZX#	@(#)Makefile	1.0 (2.11BSD GTE) 1995/03/13
ZX#
ZXCFLAGS=	 -O
ZXSEPFLAG= -i
ZXSRCS=	hostname.c
ZXOBJS=	hostname.o
ZX
ZXall: hostname hostname.0
ZX
ZXhostname: ${OBJS}
ZX	${CC} ${CFLAGS} ${SEPFLAG} -o $@ ${OBJS}
ZX
ZXhostname.0: hostname.1
ZX	/usr/man/manroff hostname.1 > hostname.0
ZX
ZXclean:
ZX	rm -f ${OBJS} tags hostname hostname.0
ZX
ZXdepend: ${SRCS}
ZX	mkdep ${CFLAGS} ${SRCS}
ZX
ZXinstall: all
ZX	install -s -o bin -g bin -m 755 hostname ${DESTDIR}/bin
ZX	install -c -o bin -g bin -m 444 hostname.0 ${DESTDIR}/usr/man/cat1
ZX
ZXlint: ${SRCS}
ZX	lint -hax ${SRCS}
ZX
ZXtags: ${SRCS}
ZX	ctags ${SRCS}
ZSHAR_EOF
Zfi
Zcd ..
Zexit 0
Z#	End of shell archive
SHAR_EOF
fi
exit 0
#	End of shell archive
