summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/smrsh
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/smrsh')
-rwxr-xr-xcontrib/sendmail/smrsh/Build508
-rw-r--r--contrib/sendmail/smrsh/Makefile17
-rw-r--r--contrib/sendmail/smrsh/Makefile.m4106
-rw-r--r--contrib/sendmail/smrsh/README96
-rw-r--r--contrib/sendmail/smrsh/smrsh.812
-rw-r--r--contrib/sendmail/smrsh/smrsh.c330
6 files changed, 345 insertions, 724 deletions
diff --git a/contrib/sendmail/smrsh/Build b/contrib/sendmail/smrsh/Build
index ab8a49d..c402815 100755
--- a/contrib/sendmail/smrsh/Build
+++ b/contrib/sendmail/smrsh/Build
@@ -1,513 +1,13 @@
#!/bin/sh
-# Copyright (c) 1998 Sendmail, Inc. All rights reserved.
-# Copyright (c) 1993, 1996-1997 Eric P. Allman. All rights reserved.
-# Copyright (c) 1993
-# The Regents of the University of California. All rights reserved.
+# Copyright (c) 1999 Sendmail, Inc. and its suppliers.
+# All rights reserved.
#
# By using this file, you agree to the terms and conditions set
# forth in the LICENSE file which can be found at the top level of
# the sendmail distribution.
#
#
-# @(#)Build 8.93 (Berkeley) 6/24/98
-#
-
-#
-# A quick-and-dirty script to compile sendmail and related programs
-# in the presence of multiple architectures. To use, just use
-# "sh Build".
-#
-
-trap "rm -f $obj/.settings$$; exit" 1 2 3 15
-
-cflag=""
-mflag=""
-sflag=""
-makeargs=""
-libdirs=""
-incdirs=""
-libsrch=""
-siteconfig=""
-EX_USAGE=64
-EX_NOINPUT=66
-EX_UNAVAILABLE=69
-
-while [ ! -z "$1" ]
-do
- case $1
- in
- -c) # clean out existing $obj tree
- cflag=1
- shift
- ;;
-
- -m) # show Makefile name only
- mflag=1
- shift
- ;;
-
- -E*) # environment variables to pass into Build
- arg=`echo $1 | sed 's/^-E//'`
- if [ -z "$arg" ]
- then
- shift # move to argument
- arg=$1
- fi
- if [ -z "$arg" ]
- then
- echo "Empty -E flag" >&2
- exit $EX_USAGE
- else
- case $arg
- in
- *=*) # check format
- eval $arg
- export `echo $arg | sed 's;=.*;;'`
- ;;
- *) # bad format
- echo "Bad format for -E argument ($arg)" >&2
- exit $EX_USAGE
- ;;
- esac
- shift
- fi
- ;;
-
- -L*) # set up LIBDIRS
- libdirs="$libdirs $1"
- shift
- ;;
-
- -I*) # set up INCDIRS
- incdirs="$incdirs $1"
- shift
- ;;
-
- -f*) # select site config file
- arg=`echo $1 | sed 's/^-f//'`
- if [ -z "$arg" ]
- then
- shift # move to argument
- arg=$1
- fi
- if [ "$siteconfig" ]
- then
- echo "Only one -f flag allowed" >&2
- exit $EX_USAGE
- else
- siteconfig=$arg
- if [ -z "$siteconfig" ]
- then
- echo "Missing argument for -f flag" >&2
- exit $EX_USAGE
- elif [ ! -f "$siteconfig" ]
- then
- echo "${siteconfig}: File not found"
- exit $EX_NOINPUT
- else
- shift # move past argument
- fi
- fi
- ;;
-
- -S) # skip auto-configure
- sflag="-s"
- shift
- ;;
-
- *) # pass argument to make
- makeargs="$makeargs \"$1\""
- shift
- ;;
- esac
-done
-
-#
-# Do heuristic guesses !ONLY! for machines that do not have uname
-#
-if [ -d /NextApps -a ! -f /bin/uname -a ! -f /usr/bin/uname ]
-then
- # probably a NeXT box
- arch=`hostinfo | sed -n 's/.*Processor type: \([^ ]*\).*/\1/p'`
- os=NeXT
- rel=`hostinfo | sed -n 's/.*NeXT Mach \([0-9\.]*\).*/\1/p'`
-elif [ -f /usr/sony/bin/machine -a -f /etc/osversion ]
-then
- # probably a Sony NEWS 4.x
- os=NEWS-OS
- rel=`awk '{ print $3}' /etc/osversion`
- arch=`/usr/sony/bin/machine`
-elif [ -d /usr/omron -a -f /bin/luna ]
-then
- # probably a Omron LUNA
- os=LUNA
- if [ -f /bin/luna1 ] && /bin/luna1
- then
- rel=unios-b
- arch=luna1
- elif [ -f /bin/luna2 ] && /bin/luna2
- then
- rel=Mach
- arch=luna2
- elif [ -f /bin/luna88k ] && /bin/luna88k
- then
- rel=Mach
- arch=luna88k
- fi
-elif [ -d /usr/apollo -a -d \`node_data ]
-then
- # probably a Apollo/DOMAIN
- os=DomainOS
- arch=$ISP
- rel=`/usr/apollo/bin/bldt | grep Domain | awk '{ print $4 }' | sed -e 's/,//g'`
-fi
-
-if [ ! "$arch" -a ! "$os" -a ! "$rel" ]
-then
- arch=`uname -m | sed -e 's/ //g'`
- os=`uname -s | sed -e 's/\//-/g' -e 's/ //g'`
- rel=`uname -r | sed -e 's/(/-/g' -e 's/)//g'`
-fi
-
-#
-# Tweak the values we have already got. PLEASE LIMIT THESE to
-# tweaks that are absolutely necessary because your system uname
-# routine doesn't return something sufficiently unique. Don't do
-# it just because you don't like the name that is returned. You
-# can combine the architecture name with the os name to create a
-# unique Makefile name.
-#
-
-# tweak machine architecture
-case $arch
-in
- sun4*) arch=sun4;;
-
- 9000/*) arch=`echo $arch | sed -e 's/9000.//' -e 's/..$/xx/'`;;
-
- DS/907000) arch=ds90;;
-
- NILE*) arch=NILE
- os=`uname -v`;;
-esac
-
-# tweak operating system type and release
-node=`uname -n | sed -e 's/\//-/g' -e 's/ //g'`
-if [ "$os" = "$node" -a "$arch" = "i386" -a "$rel" = 3.2 -a "`uname -v`" = 2 ]
-then
- # old versions of SCO UNIX set uname -s the same as uname -n
- os=SCO_SV
-fi
-if [ "$rel" = 4.0 ]
-then
- case $arch in
- 3[34]??|3[34]??,*)
- if [ -d /usr/sadm/sysadm/add-ons/WIN-TCP ]
- then
- os=NCR.MP-RAS.2.x
- elif [ -d /usr/sadm/sysadm/add-ons/inet ]
- then
- os=NCR.MP-RAS.3.x
- fi
- ;;
- esac
-fi
-
-case $os
-in
- DYNIX-ptx) os=PTX;;
- Paragon*) os=Paragon;;
- HP-UX) rel=`echo $rel | sed -e 's/^[^.]*\.0*//'`;;
- AIX) rela=$rel
- rel=`uname -v`
- case $rel in
- 2) arch=""
- ;;
- 4) if [ "$rela" = "3" ]
- then
- arch=$rela
- fi
- ;;
- esac
- rel=$rel.$rela
- ;;
- BSD-386) os=BSD-OS;;
- SCO_SV) os=SCO; rel=`uname -X | sed -n 's/Release = 3.2v//p'`;;
- UNIX_System_V) if [ "$arch" = "ds90" ]
- then
- os="UXPDS"
- rel=`uname -v | sed -e 's/\(V.*\)L.*/\1/'`
- fi;;
- SINIX-?) os=SINIX;;
- DomainOS) case $rel in
- 10.4*) rel=10.4;;
- esac
- ;;
-esac
-
-# get "base part" of operating system release
-rroot=`echo $rel | sed -e 's/\.[^.]*$//'`
-rbase=`echo $rel | sed -e 's/\..*//'`
-if [ "$rroot" = "$rbase" ]
-then
- rroot=$rel
-fi
-
-# heuristic tweaks to clean up names -- PLEASE LIMIT THESE!
-if [ "$os" = "unix" ]
-then
- # might be Altos System V
- case $rel
- in
- 5.3*) os=Altos;;
- esac
-elif [ -r /unix -a -r /usr/lib/libseq.a -a -r /lib/cpp ]
-then
- # might be a DYNIX/ptx 2.x system, which has a broken uname
- if strings /lib/cpp | grep _SEQUENT_ > /dev/null
- then
- os=PTX
- fi
-elif [ -d /usr/nec ]
-then
- # NEC machine -- what is it running?
- if [ "$os" = "UNIX_System_V" ]
- then
- os=EWS-UX_V
- elif [ "$os" = "UNIX_SV" ]
- then
- os=UX4800
- fi
-elif [ "$arch" = "mips" ]
-then
- case $rel
- in
- 4_*)
- if [ `uname -v` = "UMIPS" ]
- then
- os=RISCos
- fi;;
- esac
-fi
-
-# see if there is a "user suffix" specified
-if [ "${SENDMAIL_SUFFIX-}x" = "x" ]
-then
- sfx=""
-else
- sfx=".${SENDMAIL_SUFFIX}"
-fi
-
-echo "Configuration: os=$os, rel=$rel, rbase=$rbase, rroot=$rroot, arch=$arch, sfx=$sfx"
-
-
-SMROOT=${SMROOT-..}
-BUILDTOOLS=${BUILDTOOLS-$SMROOT/BuildTools}
-export SMROOT BUILDTOOLS
-
-# see if we are in a Build-able directory
-if [ ! -f Makefile.m4 ]; then
- echo "Makefile.m4 not found. Build can only be run from a source directory."
- exit $EX_UNAVAILABLE
-fi
-
-# now try to find a reasonable object directory
-if [ -r obj.$os.$rel.$arch$sfx ]; then
- obj=obj.$os.$rel.$arch$sfx
-elif [ -r obj.$os.$rroot.$arch$sfx ]; then
- obj=obj.$os.$rroot.$arch$sfx
-elif [ -r obj.$os.$rbase.x.$arch$sfx ]; then
- obj=obj.$os.$rbase.x.$arch$sfx
-elif [ -r obj.$os.$rel$sfx ]; then
- obj=obj.$os.$rel$sfx
-elif [ -r obj.$os.$rbase.x$sfx ]; then
- obj=obj.$os.$rbase.x$sfx
-elif [ -r obj.$os.$arch$sfx ]; then
- obj=obj.$os.$arch$sfx
-elif [ -r obj.$rel.$arch$sfx ]; then
- obj=obj.$rel.$arch$sfx
-elif [ -r obj.$rbase.x.$arch$sfx ]; then
- obj=obj.$rbase.x.$arch$sfx
-elif [ -r obj.$os$sfx ]; then
- obj=obj.$os$sfx
-elif [ -r obj.$arch$sfx ]; then
- obj=obj.$arch$sfx
-elif [ -r obj.$rel$sfx ]; then
- obj=obj.$rel$sfx
-elif [ -r obj$sfx ]; then
- obj=obj$sfx
-fi
-if [ -z "$obj" -o "$cflag" ]
-then
- if [ -n "$obj" ]
- then
- echo "Clearing out existing $obj tree"
- rm -rf $obj
- else
- # no existing obj directory -- try to create one if Makefile found
- obj=obj.$os.$rel.$arch$sfx
- fi
- if [ -r $BUILDTOOLS/OS/$os.$rel.$arch$sfx ]; then
- oscf=$os.$rel.$arch$sfx
- elif [ -r $BUILDTOOLS/OS/$os.$rel.$arch ]; then
- oscf=$os.$rel.$arch
- elif [ -r $BUILDTOOLS/OS/$os.$rroot.$arch$sfx ]; then
- oscf=$os.$rroot.$arch$sfx
- elif [ -r $BUILDTOOLS/OS/$os.$rroot.$arch ]; then
- oscf=$os.$rroot.$arch
- elif [ -r $BUILDTOOLS/OS/$os.$rbase.x.$arch$sfx ]; then
- oscf=$os.$rbase.x.$arch$sfx
- elif [ -r $BUILDTOOLS/OS/$os.$rbase.x.$arch ]; then
- oscf=$os.$rbase.x.$arch
- elif [ -r $BUILDTOOLS/OS/$os.$rel$sfx ]; then
- oscf=$os.$rel$sfx
- elif [ -r $BUILDTOOLS/OS/$os.$rel ]; then
- oscf=$os.$rel
- elif [ -r $BUILDTOOLS/OS/$os.$rroot$sfx ]; then
- oscf=$os.$rroot$sfx
- elif [ -r $BUILDTOOLS/OS/$os.$rroot ]; then
- oscf=$os.$rroot
- elif [ -r $BUILDTOOLS/OS/$os.$rbase.x$sfx ]; then
- oscf=$os.$rbase.x$sfx
- elif [ -r $BUILDTOOLS/OS/$os.$rbase.x ]; then
- oscf=$os.$rbase.x
- elif [ -r $BUILDTOOLS/OS/$os.$arch$sfx ]; then
- oscf=$os.$arch$sfx
- elif [ -r $BUILDTOOLS/OS/$os.$arch ]; then
- oscf=$os.$arch
- elif [ -r $BUILDTOOLS/OS/$rel.$arch$sfx ]; then
- oscf=$rel.$arch$sfx
- elif [ -r $BUILDTOOLS/OS/$rel.$arch ]; then
- oscf=$rel.$arch
- elif [ -r $BUILDTOOLS/OS/$rroot.$arch$sfx ]; then
- oscf=$rroot.$arch$sfx
- elif [ -r $BUILDTOOLS/OS/$rroot.$arch ]; then
- oscf=$rroot.$arch
- elif [ -r $BUILDTOOLS/OS/$rbase.x.$arch$sfx ]; then
- oscf=$rbase.x.$arch$sfx
- elif [ -r $BUILDTOOLS/OS/$rbase.x.$arch ]; then
- oscf=$rbase.x.$arch
- elif [ -r $BUILDTOOLS/OS/$os$sfx ]; then
- oscf=$os$sfx
- elif [ -r $BUILDTOOLS/OS/$os ]; then
- oscf=$os
- elif [ -r $BUILDTOOLS/OS/$arch$sfx ]; then
- oscf=$arch$sfx
- elif [ -r $BUILDTOOLS/OS/$arch ]; then
- oscf=$arch
- elif [ -r $BUILDTOOLS/OS/$rel$sfx ]; then
- oscf=$rel$sfx
- elif [ -r $BUILDTOOLS/OS/$rel ]; then
- oscf=$rel
- elif [ -r $BUILDTOOLS/OS/$rel$sfx ]; then
- oscf=$rel$sfx
- else
- echo "Cannot determine how to support $arch.$os.$rel" >&2
- exit $EX_UNAVAILABLE
- fi
- M4=`sh $BUILDTOOLS/bin/find_m4.sh`
- ret=$?
- if [ $ret -ne 0 ]
- then
- exit $ret
- fi
- echo "Using M4=$M4"
- export M4
- if [ "$mflag" ]
- then
- echo "Will run in virgin $obj using $BUILDTOOLS/OS/$oscf"
- exit 0
- fi
- if [ "$ABI" ]
- then
- echo "Using ABI $ABI"
- fi
- echo "Creating $obj using $BUILDTOOLS/OS/$oscf"
- mkdir $obj
- (cd $obj; ln -s ../*.[ch158] .)
- if [ -f sendmail.hf ]
- then
- (cd $obj; ln -s ../sendmail.hf .)
- fi
-
- rm -f $obj/.settings$$
- echo 'divert(-1)' > $obj/.settings$$
- cat $BUILDTOOLS/M4/header.m4 >> $obj/.settings$$
- if [ "$ABI" ]
- then
- echo "define(\`confABI', \`$ABI')" >> $obj/.settings$$
- fi
- cat $BUILDTOOLS/OS/$oscf >> $obj/.settings$$
-
- if [ -z "$siteconfig" ]
- then
- # none specified, use defaults
- if [ -f $BUILDTOOLS/Site/site.$oscf$sfx.m4 ]
- then
- siteconfig=$BUILDTOOLS/Site/site.$oscf$sfx.m4
- elif [ -f $BUILDTOOLS/Site/site.$oscf.m4 ]
- then
- siteconfig=$BUILDTOOLS/Site/site.$oscf.m4
- fi
- if [ -f $BUILDTOOLS/Site/site.config.m4 ]
- then
- siteconfig="$BUILDTOOLS/Site/site.config.m4 $siteconfig"
- fi
- fi
- if [ ! -z "$siteconfig" ]
- then
- echo "Including $siteconfig"
- cat $siteconfig >> $obj/.settings$$
- fi
- if [ "$libdirs" ]
- then
- echo "define(\`confLIBDIRS', confLIBDIRS \`\`$libdirs'')" >> $obj/.settings$$
- fi
- if [ "$incdirs" ]
- then
- echo "define(\`confINCDIRS', confINCDIRS \`\`$incdirs'')" >> $obj/.settings$$
- fi
- echo 'divert(0)dnl' >> $obj/.settings$$
- libdirs=`(cat $obj/.settings$$; echo "_SRIDBIL_= confLIBDIRS" ) | \
- sed -e 's/\(.\)include/\1_include_/g' -e 's/#define/#_define_/g' | \
- ${M4} -DconfBUILDTOOLSDIR=$BUILDTOOLS - | \
- grep "^_SRIDBIL_=" | \
- sed -e 's/#_define_/#define/g' -e 's/_include_/include/g' -e "s/^_SRIDBIL_=//"`
- libsrch=`(cat $obj/.settings$$; echo "_HCRSBIL_= confLIBSEARCH" ) | \
- sed -e 's/\(.\)include/\1_include_/g' -e 's/#define/#_define_/g' | \
- ${M4} -DconfBUILDTOOLSDIR=$BUILDTOOLS - | \
- grep "^_HCRSBIL_=" | \
- sed -e 's/#_define_/#define/g' -e 's/_include_/include/g' -e "s/^_HCRSBIL_=//"`
- echo 'divert(-1)' >> $obj/.settings$$
- LIBDIRS="$libdirs" LIBSRCH="$libsrch" SITECONFIG="$siteconfig" sh $BUILDTOOLS/bin/configure.sh $sflag $oscf >> $obj/.settings$$
- echo 'divert(0)dnl' >> $obj/.settings$$
- sed -e 's/\(.\)include/\1_include_/g' -e 's/#define/#_define_/g' $obj/.settings$$ | \
- ${M4} -DconfBUILDTOOLSDIR=$BUILDTOOLS - Makefile.m4 | \
- sed -e 's/#_define_/#define/g' -e 's/_include_/include/g' > $obj/Makefile
- if [ $? -ne 0 -o ! -s $obj/Makefile ]
- then
- echo "ERROR: ${M4} failed; You may need a newer version of M4, at least as new as System V or GNU" 1>&2
- rm -rf $obj
- exit $EX_UNAVAILABLE
- fi
- rm -f $obj/.settings$$
- echo "Making dependencies in $obj"
- (cd $obj; ${MAKE-make} depend)
-fi
-
-if [ "$mflag" ]
-then
- makefile=`ls -l $obj/Makefile | sed 's/.* //'`
- if [ -z "$makefile" ]
- then
- echo "ERROR: $obj exists but has no Makefile" >&2
- exit $EX_NOINPUT
- fi
- echo "Will run in existing $obj using $makefile"
- exit 0
-fi
+# $Id: Build,v 8.4 1999/03/02 02:34:57 peterh Exp $
-echo "Making in $obj"
-cd $obj
-eval exec ${MAKE-make} $makeargs
+exec ../devtools/bin/Build $*
diff --git a/contrib/sendmail/smrsh/Makefile b/contrib/sendmail/smrsh/Makefile
new file mode 100644
index 0000000..a9c4af7
--- /dev/null
+++ b/contrib/sendmail/smrsh/Makefile
@@ -0,0 +1,17 @@
+# $Id: Makefile,v 8.5 1999/09/23 22:36:43 ca Exp $
+
+SHELL= /bin/sh
+BUILD= ./Build
+OPTIONS= $(CONFIG) $(FLAGS)
+
+all: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
+clean: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
+install: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) $@
+
+fresh: FRC
+ $(SHELL) $(BUILD) $(OPTIONS) -c
+
+FRC:
diff --git a/contrib/sendmail/smrsh/Makefile.m4 b/contrib/sendmail/smrsh/Makefile.m4
index 5cae3f0..7e4718f 100644
--- a/contrib/sendmail/smrsh/Makefile.m4
+++ b/contrib/sendmail/smrsh/Makefile.m4
@@ -1,96 +1,18 @@
-#
-# This Makefile is designed to work on the old "make" program.
-#
-# @(#)Makefile.m4 8.14 (Berkeley) 7/12/1998
-#
+include(confBUILDTOOLSDIR`/M4/switch.m4')
-# C compiler
-CC= confCC
+# sendmail dir
+SMSRCDIR= ifdef(`confSMSRCDIR', `confSMSRCDIR', `${SRCDIR}/sendmail')
+PREPENDDEF(`confENVDEF', `confMAPDEF')
+PREPENDDEF(`confINCDIRS', `-I${SMSRCDIR} ')
-# Shell
-SHELL= confSHELL
+bldPRODUCT_START(`executable', `smrsh')
+define(`bldINSTALL_DIR', `E')
+define(`bldSOURCES', `smrsh.c ')
+bldPUSH_SMLIB(`smutil')
+bldPRODUCT_END
-# use O=-O (usual) or O=-g (debugging)
-O= ifdef(`confOPTIMIZE', `confOPTIMIZE', `-O')
+bldPRODUCT_START(`manpage', `smrsh')
+define(`bldSOURCES', `smrsh.8')
+bldPRODUCT_END
-# location of sendmail source directory
-SRCDIR= ifdef(`confSRCDIR', `confSRCDIR', `../../src')
-
-# environment definitions (e.g., -D_AIX3)
-ENVDEF= ifdef(`confENVDEF', `confENVDEF')
-
-# include directories
-INCDIRS=-I${SRCDIR} confINCDIRS
-
-# loader options
-LDOPTS= ifdef(`confLDOPTS', `confLDOPTS')
-
-# library directories
-LIBDIRS=confLIBDIRS
-
-# libraries required on your system
-LIBS= ifdef(`confLIBS', `confLIBS')
-
-# location of smrsh binary (usually /usr/libexec or /usr/etc)
-EBINDIR=${DESTDIR}ifdef(`confEBINDIR', `confEBINDIR', `/usr/libexec')
-
-# additional .o files needed
-OBJADD= ifdef(`confOBJADD', `confOBJADD')
-
-undivert(1)
-
-################### end of user configuration flags ######################
-
-BUILDBIN=confBUILDBIN
-COPTS= -I. ${INCDIRS} ${ENVDEF}
-CFLAGS= $O ${COPTS}
-
-BEFORE= confBEFORE
-OBJS= smrsh.o ${OBJADD}
-
-# Which *roff program has -mandoc support
-NROFF= ifdef(`confNROFF', `confNROFF', `groff -Tascii')
-MANDOC= ifdef(`confMANDOC', `confMANDOC', `-mandoc')
-
-INSTALL=ifdef(`confINSTALL', `confINSTALL', `install')
-BINOWN= ifdef(`confUBINOWN', `confUBINOWN', `bin')
-BINGRP= ifdef(`confUBINGRP', `confUBINGRP', `bin')
-BINMODE=ifdef(`confUBINMODE', `confUBINMODE', `555')
-
-MANOWN= ifdef(`confMANOWN', `confMANOWN', `bin')
-MANGRP= ifdef(`confMANGRP', `confMANGRP', `bin')
-MANMODE=ifdef(`confMANMODE', `confMANMODE', `444')
-
-MANROOT=${DESTDIR}ifdef(`confMANROOT', `confMANROOT', `/usr/share/man/cat')
-MAN8= ${MANROOT}ifdef(`confMAN8', `confMAN8', `8')
-MAN8EXT=ifdef(`confMAN8EXT', `confMAN8EXT', `8')
-MAN8SRC=ifdef(`confMAN8SRC', `confMAN8SRC', `0')
-
-ALL= smrsh smrsh.${MAN8SRC}
-
-all: ${ALL}
-
-smrsh: ${BEFORE} ${OBJS}
- ${CC} -o smrsh ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS}
-
-undivert(3)
-
-smrsh.${MAN8SRC}: smrsh.8
- ${NROFF} ${MANDOC} smrsh.8 > smrsh.${MAN8SRC}
-
-install: install-smrsh install-docs
-
-install-smrsh: smrsh
- ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} smrsh ${EBINDIR}
-
-install-docs: smrsh.${MAN8SRC}
-ifdef(`confNO_MAN_INSTALL', `dnl',
-` ${INSTALL} -c -o ${MANOWN} -g ${MANGRP} -m ${MANMODE} smrsh.${MAN8SRC} ${MAN8}/smrsh.${MAN8EXT}')
-
-clean:
- rm -f ${OBJS} smrsh smrsh.${MAN8SRC}
-
-################ Dependency scripts
-include(confBUILDTOOLSDIR/M4/depend/ifdef(`confDEPEND_TYPE', `confDEPEND_TYPE',
-`generic').m4)dnl
-################ End of dependency scripts
+bldFINISH
diff --git a/contrib/sendmail/smrsh/README b/contrib/sendmail/smrsh/README
index fa4e2de..1e048c6 100644
--- a/contrib/sendmail/smrsh/README
+++ b/contrib/sendmail/smrsh/README
@@ -1,13 +1,8 @@
-
-
README smrsh - sendmail restricted shell.
- @(#)README 8.2 11/11/1995
-
-
This README file is provided as a courtesy of the CERT Coordination Center,
-Software Engineering Institute, Carnegie Mellon University. This file is
+Software Engineering Institute, Carnegie Mellon University. This file is
intended as a supplement to the CERT advisory CA-93:16.sendmail.vulnerability,
and to the software, smrsh.c, written by Eric Allman.
@@ -23,52 +18,65 @@ programs. When used in conjunction with sendmail, smrsh effectively
limits sendmail's scope of program execution to only those programs
specified in smrsh's configuration.
-smrsh has been written with portability in mind, and uses traditional
+smrsh has been written with portability in mind, and uses traditional
Unix library utilities. As such, smrsh should compile on most
Unix C compilers.
+smrsh should build on most systems with the enclosed Build script:
+ host.domain% sh Build
-To compile smrsh.c, use the following command:
+To compile smrsh.c by hand, use the following command:
-host.domain% cc -o smrsh smrsh.c
+ host.domain% cc -o smrsh smrsh.c
For machines that provide dynamic linking, it is advisable to compile
smrsh without dynamic linking. As an example with the Sun Microsystems
compiler, you should compile with the -Bstatic option.
-host.domain% cc -Bstatic -o smrsh smrsh.c
+ host.domain% cc -Bstatic -o smrsh smrsh.c
+ or
+ host.domain% sh Build LDOPTS=-Bstatic
+
+With gcc, the GNU C compiler, use the -static option.
+
+ host.domain% cc -static -o smrsh smrsh.c
+ or
+ host.domain% sh Build LDOPTS=-static
-Choose a directory that smrsh will reside in. We will use the traditional
-/usr/local/etc directory for the remainder of this document.
-As root, install smrsh in /usr/local/etc directory, with mode 511.
+As root, install smrsh in /usr/libexec. Using the Build script:
-host.domain# mv smrsh /usr/local/etc
-host.domain# chmod 511 /usr/local/etc/smrsh
+ host.domain# sh Build install
+
+For manual installation: install smrsh in the /usr/libexec
+directory, with mode 511.
+
+ host.domain# mv smrsh /usr/libexec
+ host.domain# chmod 511 /usr/libexec/smrsh
Next, determine the list of commands that smrsh should allow sendmail
to run. This list of allowable commands can be determined by:
- 1. examining your /etc/aliases file, to indicate what commands
- are being used by the system.
+ 1. examining your /etc/mail/aliases file, to indicate what commands
+ are being used by the system.
- 2. surveying your host's .forward files, to determine what
- commands users have specified.
+ 2. surveying your host's .forward files, to determine what
+ commands users have specified.
-See the man page for aliases(5) if you are unfamiliar with the format of
-these specifications. Additionally, you should include in the list,
+See the man page for aliases(5) if you are unfamiliar with the format of
+these specifications. Additionally, you should include in the list,
popular commands such as /usr/ucb/vacation.
You should NOT include interpreter programs such as sh(1), csh(1),
-perl(1), uudecode(1) or the stream editor sed(1) in your list of
+perl(1), uudecode(1) or the stream editor sed(1) in your list of
acceptable commands.
-You will next need to create the directory /usr/adm/sm.bin and populate
+You will next need to create the directory /usr/adm/sm.bin and populate
it with the programs that your site feels are allowable for sendmail
to execute. This directory is explicitly specified in the source
code for smrsh, so changing this directory must be accompanied with
@@ -83,11 +91,11 @@ to the directory, or establish links to the allowable programs from
can not be modified by non-root users. If you use links, you should
ensure that the target programs are not modifiable.
-To allow the popular vacation(1) program by creating a link in the
+To allow the popular vacation(1) program by creating a link in the
/usr/adm/sm.bin directory, you should:
-host.domain# cd /usr/adm/sm.bin
-host.domain# ln -s /usr/ucb/vacation vacation
+ host.domain# cd /usr/adm/sm.bin
+ host.domain# ln -s /usr/ucb/vacation vacation
@@ -96,18 +104,18 @@ After populating the /usr/adm/sm.bin directory, you can now configure
sendmail to use the restricted shell. Save the current sendmail.cf
file prior to modifying it, as a prudent precaution.
-Typically, the program mailer is defined by a single line in the
+Typically, the program mailer is defined by a single line in the
sendmail configuration file, sendmail.cf. This file is traditionally
-found in the /etc, /usr/lib or /etc/mail directories, depending on
+found in the /etc, /usr/lib or /etc/mail directories, depending on
the UNIX vendor.
If you are unsure of the location of the actual sendmail configuration
file, a search of the strings(1) output of the sendmail binary, will
help to locate it.
-In order to configure sendmail to use smrsh, you must modify the Mprog
-definition in the sendmail.cf file, by replacing the /bin/sh specification
-with /usr/local/etc/smrsh.
+In order to configure sendmail to use smrsh, you must modify the Mprog
+definition in the sendmail.cf file, by replacing the /bin/sh specification
+with /usr/libexec/smrsh.
As an example:
@@ -115,17 +123,17 @@ In most Sun Microsystems' sendmail.cf files, the line is:
Mprog, P=/bin/sh, F=lsDFMeuP, S=10, R=20, A=sh -c $u
which should be changed to:
-Mprog, P=/usr/local/etc/smrsh, F=lsDFMeuP, S=10, R=20, A=sh -c $u
- ^^^^^^^^^^^^^^^^^^^^
+Mprog, P=/usr/libexec/smrsh, F=lsDFMeuP, S=10, R=20, A=sh -c $u
+ ^^^^^^^^^^^^^^^^^^
A more generic line may be:
Mprog, P=/bin/sh, F=lsDFM, A=sh -c $u
and should be changed to;
-Mprog, P=/usr/local/etc/smrsh, F=lsDFM, A=sh -c $u
+Mprog, P=/usr/libexec/smrsh, F=lsDFM, A=sh -c $u
-After modifying the Mprog definition in the sendmail.cf file, if a frozen
+After modifying the Mprog definition in the sendmail.cf file, if a frozen
configuration file is being used, it is essential to create a new one.
You can determine if you need a frozen configuration by discovering
if a sendmail.fc file currently exists in either the /etc/, /usr/lib,
@@ -133,12 +141,16 @@ or /etc/mail directories. The specific location can be determined using
a search of the strings(1) output of the sendmail binary.
In order to create a new frozen configuration, if it is required:
-host.domain# /usr/lib/sendmail -bz
+ host.domain# /usr/lib/sendmail -bz
-Now re-start the sendmail process. An example of how to do this on
+Now re-start the sendmail process. An example of how to do this on
a typical system follows:
-
-host.domain# /usr/bin/ps aux | /usr/bin/grep sendmail
-root 130 0.0 0.0 168 0 ? IW Oct 2 0:10 /usr/lib/sendmail -bd -q
-host.domain# /bin/kill -9 130
-host.domain# /usr/lib/sendmail -bd -q30m
+
+ host.domain# cat /var/run/sendmail.pid
+ 130
+ /usr/sbin/sendmail -bd -q30m
+ host.domain# /bin/kill -15 130
+ host.domain# /usr/sbin/sendmail -bd -q30m
+
+
+$Revision: 8.6 $, Last updated $Date: 1999/04/28 01:09:51 $
diff --git a/contrib/sendmail/smrsh/smrsh.8 b/contrib/sendmail/smrsh/smrsh.8
index af08fc4..ebb3841 100644
--- a/contrib/sendmail/smrsh/smrsh.8
+++ b/contrib/sendmail/smrsh/smrsh.8
@@ -1,4 +1,5 @@
-.\" Copyright (c) 1998 Sendmail, Inc. All rights reserved.
+.\" Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
+.\" All rights reserved.
.\" Copyright (c) 1993 Eric P. Allman. All rights reserved.
.\" Copyright (c) 1993
.\" The Regents of the University of California. All rights reserved.
@@ -8,7 +9,7 @@
.\" the sendmail distribution.
.\"
.\"
-.\" @(#)smrsh.8 8.7 (Berkeley) 5/19/1998
+.\" $Id: smrsh.8,v 8.11 1999/06/09 16:51:07 ca Exp $
.\"
.TH SMRSH 8 11/02/93
.SH NAME
@@ -38,11 +39,14 @@ Briefly,
.I smrsh
limits programs to be in the directory
/usr/adm/sm.bin,
-allowing the system administrator to choose the set of acceptable commands.
+allowing the system administrator to choose the set of acceptable commands,
+and to the shell builtin commands ``exec'', ``exit'', and ``echo''.
It also rejects any commands with the characters
-`\`', `<', `>', `|', `;', `&', `$', `(', `)', `\er' (carriage return),
+`\`', `<', `>', `;', `$', `(', `)', `\er' (carriage return),
or `\en' (newline)
on the command line to prevent ``end run'' attacks.
+It allows ``||'' and ``&&'' to enable commands like:
+``"|exec /usr/local/bin/procmail -f- /etc/procmailrcs/user || exit 75"''
.PP
Initial pathnames on programs are stripped,
so forwarding to ``/usr/ucb/vacation'',
diff --git a/contrib/sendmail/smrsh/smrsh.c b/contrib/sendmail/smrsh/smrsh.c
index d4af285..be48ab1 100644
--- a/contrib/sendmail/smrsh/smrsh.c
+++ b/contrib/sendmail/smrsh/smrsh.c
@@ -1,5 +1,6 @@
/*
- * Copyright (c) 1998 Sendmail, Inc. All rights reserved.
+ * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers.
+ * All rights reserved.
* Copyright (c) 1993 Eric P. Allman. All rights reserved.
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
@@ -11,8 +12,17 @@
*/
#ifndef lint
-static char sccsid[] = "@(#)smrsh.c 8.11 (Berkeley) 5/19/1998";
-#endif /* not lint */
+static char copyright[] =
+"@(#) Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.\n\
+ All rights reserved.\n\
+ Copyright (c) 1993 Eric P. Allman. All rights reserved.\n\
+ Copyright (c) 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* ! lint */
+
+#ifndef lint
+static char id[] = "@(#)$Id: smrsh.c,v 8.31.4.4 2000/05/25 21:44:29 gshapiro Exp $";
+#endif /* ! lint */
/*
** SMRSH -- sendmail restricted shell
@@ -29,15 +39,15 @@ static char sccsid[] = "@(#)smrsh.c 8.11 (Berkeley) 5/19/1998";
**
** Leading pathnames are stripped from program names so that
** existing .forward files that reference things like
-** "/usr/ucb/vacation" will continue to work.
+** "/usr/bin/vacation" will continue to work.
**
** The following characters are completely illegal:
-** < > | ^ ; & $ ` ( ) \n \r
+** < > ^ & ` ( ) \n \r
+** The following characters are sometimes illegal:
+** | &
** This is more restrictive than strictly necessary.
**
-** To use this, edit /etc/sendmail.cf, search for ^Mprog, and
-** change P=/bin/sh to P=/usr/local/etc/smrsh, where this compiled
-** binary is installed /usr/local/etc/smrsh.
+** To use this, add FEATURE(`smrsh') to your .mc file.
**
** This can be used on any version of sendmail.
**
@@ -49,17 +59,23 @@ static char sccsid[] = "@(#)smrsh.c 8.11 (Berkeley) 5/19/1998";
#include <sys/file.h>
#include <string.h>
#include <ctype.h>
+#include <errno.h>
#ifdef EX_OK
# undef EX_OK
-#endif
+#endif /* EX_OK */
#include <sysexits.h>
#include <syslog.h>
#include <stdlib.h>
+#ifndef TRUE
+# define TRUE 1
+# define FALSE 0
+#endif /* ! TRUE */
+
/* directory in which all commands must reside */
#ifndef CMDDIR
# define CMDDIR "/usr/adm/sm.bin"
-#endif
+#endif /* ! CMDDIR */
/* characters disallowed in the shell "-c" argument */
#define SPECIALS "<|>^();&`$\r\n"
@@ -67,7 +83,56 @@ static char sccsid[] = "@(#)smrsh.c 8.11 (Berkeley) 5/19/1998";
/* default search path */
#ifndef PATH
# define PATH "/bin:/usr/bin:/usr/ucb"
-#endif
+#endif /* ! PATH */
+
+#ifndef __P
+# include "sendmail/cdefs.h"
+#endif /* ! __P */
+
+extern size_t strlcpy __P((char *, const char *, size_t));
+extern size_t strlcat __P((char *, const char *, size_t));
+
+char newcmdbuf[1000];
+char *prg, *par;
+
+/*
+** ADDCMD -- add a string to newcmdbuf, check for overflow
+**
+** Parameters:
+** s -- string to add
+** cmd -- it's a command: prepend CMDDIR/
+** len -- length of string to add
+**
+** Side Effects:
+** changes newcmdbuf or exits with a failure.
+**
+*/
+
+void
+addcmd(s, cmd, len)
+ char *s;
+ int cmd;
+ int len;
+{
+ if (s == NULL || *s == '\0')
+ return;
+
+ if (sizeof newcmdbuf - strlen(newcmdbuf) <=
+ len + (cmd ? (strlen(CMDDIR) + 1) : 0))
+ {
+ fprintf(stderr, "%s: command too long: %s\n", prg, par);
+#ifndef DEBUG
+ syslog(LOG_WARNING, "command too long: %.40s", par);
+#endif /* ! DEBUG */
+ exit(EX_UNAVAILABLE);
+ }
+ if (cmd)
+ {
+ (void) strlcat(newcmdbuf, CMDDIR, sizeof newcmdbuf);
+ (void) strlcat(newcmdbuf, "/", sizeof newcmdbuf);
+ }
+ (void) strlcat(newcmdbuf, s, sizeof newcmdbuf);
+}
int
main(argc, argv)
@@ -76,20 +141,26 @@ main(argc, argv)
{
register char *p;
register char *q;
+ register char *r;
register char *cmd;
int i;
+ int isexec;
+ int save_errno;
char *newenv[2];
char cmdbuf[1000];
char pathbuf[1000];
+ char specialbuf[32];
-#ifndef LOG_MAIL
+#ifndef DEBUG
+# ifndef LOG_MAIL
openlog("smrsh", 0);
-#else
+# else /* ! LOG_MAIL */
openlog("smrsh", LOG_ODELAY|LOG_CONS, LOG_MAIL);
-#endif
+# endif /* ! LOG_MAIL */
+#endif /* ! DEBUG */
- strcpy(pathbuf, "PATH=");
- strcat(pathbuf, PATH);
+ (void) strlcpy(pathbuf, "PATH=", sizeof pathbuf);
+ (void) strlcat(pathbuf, PATH, sizeof pathbuf);
newenv[0] = pathbuf;
newenv[1] = NULL;
@@ -97,10 +168,15 @@ main(argc, argv)
** Do basic argv usage checking
*/
+ prg = argv[0];
+ par = argv[2];
+
if (argc != 3 || strcmp(argv[1], "-c") != 0)
{
- fprintf(stderr, "Usage: %s -c command\n", argv[0]);
+ fprintf(stderr, "Usage: %s -c command\n", prg);
+#ifndef DEBUG
syslog(LOG_ERR, "usage");
+#endif /* ! DEBUG */
exit(EX_USAGE);
}
@@ -111,103 +187,193 @@ main(argc, argv)
** the address to 7 bits before checking.
*/
- strcpy(cmdbuf, SPECIALS);
- for (p = cmdbuf; *p != '\0'; p++)
- *p |= '\200';
- strcat(cmdbuf, SPECIALS);
- p = strpbrk(argv[2], cmdbuf);
- if (p != NULL)
+ if (strlen(SPECIALS) * 2 >= sizeof specialbuf)
{
- fprintf(stderr, "%s: cannot use %c in command\n",
- argv[0], *p);
- syslog(LOG_CRIT, "uid %d: attempt to use %c in command: %s",
- getuid(), *p, argv[2]);
+#ifndef DEBUG
+ syslog(LOG_ERR, "too many specials: %.40s", SPECIALS);
+#endif /* ! DEBUG */
exit(EX_UNAVAILABLE);
}
+ (void) strlcpy(specialbuf, SPECIALS, sizeof specialbuf);
+ for (p = specialbuf; *p != '\0'; p++)
+ *p |= '\200';
+ (void) strlcat(specialbuf, SPECIALS, sizeof specialbuf);
/*
** Do a quick sanity check on command line length.
*/
- i = strlen(argv[2]);
- if (i > (sizeof cmdbuf - sizeof CMDDIR - 2))
+ i = strlen(par);
+ if (i > (sizeof newcmdbuf - sizeof CMDDIR - 2))
{
- fprintf(stderr, "%s: command too long: %s\n", argv[0], argv[2]);
- syslog(LOG_WARNING, "command too long: %.40s", argv[2]);
+ fprintf(stderr, "%s: command too long: %s\n", prg, par);
+#ifndef DEBUG
+ syslog(LOG_WARNING, "command too long: %.40s", par);
+#endif /* ! DEBUG */
exit(EX_UNAVAILABLE);
}
- /*
- ** Strip off a leading pathname on the command name. For
- ** example, change /usr/ucb/vacation to vacation.
- */
-
- /* strip leading spaces */
- for (q = argv[2]; *q != '\0' && isascii(*q) && isspace(*q); )
- q++;
+ q = par;
+ newcmdbuf[0] = '\0';
+ isexec = FALSE;
- /* find the end of the command name */
- p = strpbrk(q, " \t");
- if (p == NULL)
- cmd = &q[strlen(q)];
- else
+ while (*q)
{
- *p = '\0';
- cmd = p;
- }
+ /*
+ ** Strip off a leading pathname on the command name. For
+ ** example, change /usr/ucb/vacation to vacation.
+ */
- /* search backwards for last / (allow for 0200 bit) */
- while (cmd > q)
- {
- if ((*--cmd & 0177) == '/')
+ /* strip leading spaces */
+ while (*q != '\0' && isascii(*q) && isspace(*q))
+ q++;
+ if (*q == '\0')
{
- cmd++;
+ if (isexec)
+ {
+ fprintf(stderr, "%s: missing command to exec\n",
+ prg);
+#ifndef DEBUG
+ syslog(LOG_CRIT, "uid %d: missing command to exec", getuid());
+#endif /* ! DEBUG */
+ exit(EX_UNAVAILABLE);
+ }
break;
}
- }
-
- /* cmd now points at final component of path name */
- /*
- ** Check to see if the command name is legal.
- */
+ /* find the end of the command name */
+ p = strpbrk(q, " \t");
+ if (p == NULL)
+ cmd = &q[strlen(q)];
+ else
+ {
+ *p = '\0';
+ cmd = p;
+ }
+ /* search backwards for last / (allow for 0200 bit) */
+ while (cmd > q)
+ {
+ if ((*--cmd & 0177) == '/')
+ {
+ cmd++;
+ break;
+ }
+ }
+ /* cmd now points at final component of path name */
- (void) strcpy(cmdbuf, CMDDIR);
- (void) strcat(cmdbuf, "/");
- (void) strcat(cmdbuf, cmd);
+ /* allow a few shell builtins */
+ if (strcmp(q, "exec") == 0 && p != NULL)
+ {
+ addcmd("exec ", FALSE, strlen("exec "));
+ /* test _next_ arg */
+ q = ++p;
+ isexec = TRUE;
+ continue;
+ }
+ else if (strcmp(q, "exit") == 0 || strcmp(q, "echo") == 0)
+ {
+ addcmd(cmd, FALSE, strlen(cmd));
+ /* test following chars */
+ }
+ else
+ {
+ /*
+ ** Check to see if the command name is legal.
+ */
+ (void) strlcpy(cmdbuf, CMDDIR, sizeof cmdbuf);
+ (void) strlcat(cmdbuf, "/", sizeof cmdbuf);
+ (void) strlcat(cmdbuf, cmd, sizeof cmdbuf);
#ifdef DEBUG
- printf("Trying %s\n", cmdbuf);
-#endif
- if (access(cmdbuf, X_OK) < 0)
- {
- /* oops.... crack attack possiblity */
- fprintf(stderr, "%s: %s not available for sendmail programs\n",
- argv[0], cmd);
+ printf("Trying %s\n", cmdbuf);
+#endif /* DEBUG */
+ if (access(cmdbuf, X_OK) < 0)
+ {
+ /* oops.... crack attack possiblity */
+ fprintf(stderr,
+ "%s: %s not available for sendmail programs\n",
+ prg, cmd);
+ if (p != NULL)
+ *p = ' ';
+#ifndef DEBUG
+ syslog(LOG_CRIT, "uid %d: attempt to use %s",
+ getuid(), cmd);
+#endif /* ! DEBUG */
+ exit(EX_UNAVAILABLE);
+ }
+
+ /*
+ ** Create the actual shell input.
+ */
+
+ addcmd(cmd, TRUE, strlen(cmd));
+ }
+ isexec = FALSE;
+
if (p != NULL)
*p = ' ';
- syslog(LOG_CRIT, "uid %d: attempt to use %s", getuid(), cmd);
- exit(EX_UNAVAILABLE);
- }
- if (p != NULL)
- *p = ' ';
+ else
+ break;
- /*
- ** Create the actual shell input.
- */
+ r = strpbrk(p, specialbuf);
+ if (r == NULL) {
+ addcmd(p, FALSE, strlen(p));
+ break;
+ }
+#if ALLOWSEMI
+ if (*r == ';') {
+ addcmd(p, FALSE, r - p + 1);
+ q = r + 1;
+ continue;
+ }
+#endif /* ALLOWSEMI */
+ if ((*r == '&' && *(r + 1) == '&') ||
+ (*r == '|' && *(r + 1) == '|'))
+ {
+ addcmd(p, FALSE, r - p + 2);
+ q = r + 2;
+ continue;
+ }
- strcpy(cmdbuf, CMDDIR);
- strcat(cmdbuf, "/");
- strcat(cmdbuf, cmd);
+ fprintf(stderr, "%s: cannot use %c in command\n", prg, *r);
+#ifndef DEBUG
+ syslog(LOG_CRIT, "uid %d: attempt to use %c in command: %s",
+ getuid(), *r, par);
+#endif /* ! DEBUG */
+ exit(EX_UNAVAILABLE);
+ } /* end of while *q */
+ if (isexec)
+ {
+ fprintf(stderr, "%s: missing command to exec\n", prg);
+#ifndef DEBUG
+ syslog(LOG_CRIT, "uid %d: missing command to exec", getuid());
+#endif /* ! DEBUG */
+ exit(EX_UNAVAILABLE);
+ }
+ /* make sure we created something */
+ if (newcmdbuf[0] == '\0')
+ {
+ fprintf(stderr, "Usage: %s -c command\n", prg);
+#ifndef DEBUG
+ syslog(LOG_ERR, "usage");
+#endif /* ! DEBUG */
+ exit(EX_USAGE);
+ }
/*
** Now invoke the shell
*/
#ifdef DEBUG
- printf("%s\n", cmdbuf);
-#endif
- execle("/bin/sh", "/bin/sh", "-c", cmdbuf, NULL, newenv);
+ printf("%s\n", newcmdbuf);
+#endif /* DEBUG */
+ (void) execle("/bin/sh", "/bin/sh", "-c", newcmdbuf, NULL, newenv);
+ save_errno = errno;
+#ifndef DEBUG
syslog(LOG_CRIT, "Cannot exec /bin/sh: %m");
+#endif /* ! DEBUG */
+ errno = save_errno;
perror("/bin/sh");
exit(EX_OSFILE);
+ /* NOTREACHED */
+ return EX_OSFILE;
}
OpenPOWER on IntegriCloud