From 329949050501501c130d09efc3aee7c78c6d4f9c Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 3 Aug 1998 05:56:20 +0000 Subject: Import sendmail-8.9.1 (slightly trimmed) onto a fresh branch under src/contrib as per various discussions. I will copy across our changes and then point the Makefiles across once the dust has settled.. --- contrib/sendmail/rmail/Build | 513 +++++++++++++++++++++++++++++++++++++ contrib/sendmail/rmail/Makefile.m4 | 105 ++++++++ contrib/sendmail/rmail/rmail.8 | 49 ++++ contrib/sendmail/rmail/rmail.c | 430 +++++++++++++++++++++++++++++++ 4 files changed, 1097 insertions(+) create mode 100755 contrib/sendmail/rmail/Build create mode 100644 contrib/sendmail/rmail/Makefile.m4 create mode 100644 contrib/sendmail/rmail/rmail.8 create mode 100644 contrib/sendmail/rmail/rmail.c (limited to 'contrib/sendmail/rmail') diff --git a/contrib/sendmail/rmail/Build b/contrib/sendmail/rmail/Build new file mode 100755 index 0000000..ab8a49d --- /dev/null +++ b/contrib/sendmail/rmail/Build @@ -0,0 +1,513 @@ +#!/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. +# +# 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 + +echo "Making in $obj" +cd $obj +eval exec ${MAKE-make} $makeargs diff --git a/contrib/sendmail/rmail/Makefile.m4 b/contrib/sendmail/rmail/Makefile.m4 new file mode 100644 index 0000000..55468bd --- /dev/null +++ b/contrib/sendmail/rmail/Makefile.m4 @@ -0,0 +1,105 @@ +# +# This Makefile is designed to work on the old "make" program. +# +# @(#)Makefile.m4 8.16 (Berkeley) 6/18/98 +# + +# C compiler +CC= confCC + +# Shell +SHELL= confSHELL + +# use O=-O (usual) or O=-g (debugging) +O= ifdef(`confOPTIMIZE', `confOPTIMIZE', `-O') + +# location of sendmail source directory +SRCDIR= ifdef(`confSRCDIR', `confSRCDIR', `../../src') + +# environment definitions (e.g., -D_AIX3) +ENVDEF= ifdef(`confENVDEF', `confENVDEF') + +# see also conf.h for additional compilation flags + +# 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 rmail binary (usually /usr/sbin or /usr/etc) +BINDIR= ${DESTDIR}ifdef(`confUBINDIR', `confUBINDIR', `/usr/bin') + +# 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= snprintf.c confBEFORE +OBJS= rmail.o snprintf.o ${OBJADD} + +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= rmail rmail.${MAN8SRC} + +all: ${ALL} + +rmail: ${BEFORE} ${OBJS} + ${CC} -o rmail ${LDOPTS} ${OBJS} ${LIBDIRS} ${LIBS} + +snprintf.c: ${SRCDIR}/snprintf.c + -ln -s ${SRCDIR}/snprintf.c snprintf.c + +undivert(3) + +rmail.${MAN8SRC}: rmail.8 + ${NROFF} ${MANDOC} rmail.8 > rmail.${MAN8SRC} + +install: + @echo "NOTE: This version of rmail is not suited for some operating" + @echo " systems. You can force the install using" + @echo " '${MAKE} force-install'." + +force-install: install-rmail install-docs + +install-rmail: rmail + ${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} rmail ${BINDIR} + +install-docs: rmail.${MAN8SRC} +ifdef(`confNO_MAN_INSTALL', `dnl', +` ${INSTALL} -c -o ${MANOWN} -g ${MANGRP} -m ${MANMODE} rmail.${MAN8SRC} ${MAN8}/rmail.${MAN8EXT}') + +clean: + rm -f ${OBJS} rmail rmail.${MAN8SRC} + +################ Dependency scripts +include(confBUILDTOOLSDIR/M4/depend/ifdef(`confDEPEND_TYPE', `confDEPEND_TYPE', +`generic').m4)dnl +################ End of dependency scripts diff --git a/contrib/sendmail/rmail/rmail.8 b/contrib/sendmail/rmail/rmail.8 new file mode 100644 index 0000000..ad70e5b --- /dev/null +++ b/contrib/sendmail/rmail/rmail.8 @@ -0,0 +1,49 @@ +.\" Copyright (c) 1998 Sendmail, Inc. All rights reserved. +.\" Copyright (c) 1983, 1990 +.\" The Regents of the University of California. 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. +.\" +.\" +.\" @(#)rmail.8 6.14 (Berkeley) 5/19/98 +.\" +.Dd May 19, 1998 +.Dt RMAIL 8 +.Os BSD 4.2 +.Sh NAME +.Nm rmail +.Nd handle remote mail received via uucp +.Sh SYNOPSIS +.Nm rmail +.Ar user ... +.Sh DESCRIPTION +.Nm Rmail +interprets incoming mail received via +.Xr uucp 1 , +collapsing ``From'' lines in the form generated +by +.Xr mail.local 8 +into a single line of the form ``return-path!sender'', +and passing the processed mail on to +.Xr sendmail 8 . +.Pp +.Nm Rmail +is explicitly designed for use with +.Xr uucp +and +.Xr sendmail . +.Sh SEE ALSO +.Xr uucp 1 , +.Xr mail.local 8 , +.Xr sendmail 8 +.Sh HISTORY +The +.Nm rmail +program appeared in +.Bx 4.2 . +.Sh BUGS +.Nm Rmail +should not reside in +.Pa /bin . diff --git a/contrib/sendmail/rmail/rmail.c b/contrib/sendmail/rmail/rmail.c new file mode 100644 index 0000000..9d58fcc --- /dev/null +++ b/contrib/sendmail/rmail/rmail.c @@ -0,0 +1,430 @@ +/* + * Copyright (c) 1998 Sendmail, Inc. All rights reserved. + * Copyright (c) 1988, 1993 + * The Regents of the University of California. 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. + * + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1988, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)rmail.c 8.17 (Berkeley) 5/19/98"; +#endif /* not lint */ + +/* + * RMAIL -- UUCP mail server. + * + * This program reads the >From ... remote from ... lines that UUCP is so + * fond of and turns them into something reasonable. It then execs sendmail + * with various options built from these lines. + * + * The expected syntax is: + * + * := [-a-z0-9]+ + * := ctime format + * := [-a-z0-9!]+ + * := "^\n$" + * := "From" + * [ "remote from" ] + * := ">" + * msg := * + * + * The output of rmail(8) compresses the lines into a single + * from path. + * + * The err(3) routine is included here deliberately to make this code + * a bit more portable. + */ +#include +#include +#include + +#include +#include +#ifdef BSD4_4 +# define FORK vfork +# include +#else +# define FORK fork +# ifndef _PATH_SENDMAIL +# define _PATH_SENDMAIL "/usr/lib/sendmail" +# endif +#endif +#include +#include +#include +#include +#ifdef EX_OK +# undef EX_OK /* unistd.h may have another use for this */ +#endif +#include + +#ifndef MAX +# define MAX(a, b) ((a) < (b) ? (b) : (a)) +#endif + +#ifndef __P +# ifdef __STDC__ +# define __P(protos) protos +# else +# define __P(protos) () +# define const +# endif +#endif + +#if defined(BSD4_4) || defined(linux) || SOLARIS >= 20600 || (SOLARIS < 10000 && SOLARIS >= 206) +# define HASSNPRINTF 1 +#endif + +#if defined(IRIX64) || defined(IRIX5) || defined(IRIX6) || \ + defined(BSD4_4) || defined(__osf__) || defined(__GNU_LIBRARY__) +# ifndef HASSTRERROR +# define HASSTRERROR 1 /* has strerror(3) */ +# endif +#endif + +#if !HASSTRERROR +extern char *strerror __P((int)); +#endif + +#if defined(sun) && !defined(BSD) && !defined(SOLARIS) && !defined(__svr4__) && !defined(__SVR4) +# define memmove(d, s, l) (bcopy((s), (d), (l))) +#endif + +#if !HASSNPRINTF +extern int snprintf __P((char *, size_t, const char *, ...)); +#endif /* !HASSNPRINTF */ + +u_char tTdvect[100]; + +void err __P((int, const char *, ...)); +void usage __P((void)); +char *xalloc __P((int)); + +#define newstr(s) strcpy(xalloc(strlen(s) + 1), s) + +char * +xalloc(sz) + register int sz; +{ + register char *p; + + /* some systems can't handle size zero mallocs */ + if (sz <= 0) + sz = 1; + + p = malloc((unsigned) sz); + if (p == NULL) + err(EX_TEMPFAIL, "out of memory"); + return (p); +} + +int +main(argc, argv) + int argc; + char *argv[]; +{ + extern char *optarg; + extern int errno, optind; + FILE *fp; + struct stat sb; + size_t fplen, fptlen, len; + off_t offset; + int ch, debug, i, pdes[2], pid, status; + char *addrp, *domain, *p, *t; + char *from_path, *from_sys, *from_user; + char *args[100], buf[2048], lbuf[2048]; + + debug = 0; + domain = "UUCP"; /* Default "domain". */ + while ((ch = getopt(argc, argv, "D:T")) != EOF) + switch (ch) { + case 'T': + debug = 1; + break; + case 'D': + domain = optarg; + break; + case '?': + default: + usage(); + } + argc -= optind; + argv += optind; + + if (argc < 1) + usage(); + + from_path = from_sys = from_user = NULL; + for (offset = 0;;) { + + /* Get and nul-terminate the line. */ + if (fgets(lbuf, sizeof(lbuf), stdin) == NULL) + exit (EX_DATAERR); + if ((p = strchr(lbuf, '\n')) == NULL) + err(EX_DATAERR, "line too long"); + *p = '\0'; + + /* Parse lines until reach a non-"From" line. */ + if (!strncmp(lbuf, "From ", 5)) + addrp = lbuf + 5; + else if (!strncmp(lbuf, ">From ", 6)) + addrp = lbuf + 6; + else if (offset == 0) + err(EX_DATAERR, + "missing or empty From line: %s", lbuf); + else { + *p = '\n'; + break; + } + + if (*addrp == '\0') + err(EX_DATAERR, "corrupted From line: %s", lbuf); + + /* Use the "remote from" if it exists. */ + for (p = addrp; (p = strchr(p + 1, 'r')) != NULL;) + if (!strncmp(p, "remote from ", 12)) { + for (t = p += 12; + *t && !(isascii(*t) && isspace(*t)); ++t); + *t = '\0'; + if (debug) + (void)fprintf(stderr, + "remote from: %s\n", p); + break; + } + + /* Else use the string up to the last bang. */ + if (p == NULL) { + if (*addrp == '!') + err(EX_DATAERR, + "bang starts address: %s", addrp); + else if ((t = strrchr(addrp, '!')) != NULL) { + *t = '\0'; + p = addrp; + addrp = t + 1; + if (*addrp == '\0') + err(EX_DATAERR, + "corrupted From line: %s", lbuf); + if (debug) + (void)fprintf(stderr, "bang: %s\n", p); + } + } + /* 'p' now points to any system string from this line. */ + if (p != NULL) { + /* Nul terminate it as necessary. */ + for (t = p; *t && !(isascii(*t) && isspace(*t)); ++t); + *t = '\0'; + + /* If the first system, copy to the from_sys string. */ + if (from_sys == NULL) { + from_sys = newstr(p); + if (debug) + (void)fprintf(stderr, + "from_sys: %s\n", from_sys); + } + + /* Concatenate to the path string. */ + len = t - p; + if (from_path == NULL) { + fplen = 0; + if ((from_path = malloc(fptlen = 256)) == NULL) + err(EX_TEMPFAIL, NULL); + } + if (fplen + len + 2 > fptlen) { + fptlen += MAX(fplen + len + 2, 256); + if ((from_path = + realloc(from_path, fptlen)) == NULL) + err(EX_TEMPFAIL, NULL); + } + memmove(from_path + fplen, p, len); + fplen += len; + from_path[fplen++] = '!'; + from_path[fplen] = '\0'; + } + + /* Save off from user's address; the last one wins. */ + for (p = addrp; *p && !(isascii(*p) && isspace(*p)); ++p); + *p = '\0'; + if (*addrp == '\0') + addrp = "<>"; + if (from_user != NULL) + free(from_user); + from_user = newstr(addrp); + + if (debug) { + if (from_path != NULL) + (void)fprintf(stderr, + "from_path: %s\n", from_path); + (void)fprintf(stderr, "from_user: %s\n", from_user); + } + + if (offset != -1) + offset = (off_t)ftell(stdin); + } + + i = 0; + args[i++] = _PATH_SENDMAIL; /* Build sendmail's argument list. */ + args[i++] = "-oee"; /* No errors, just status. */ + args[i++] = "-odq"; /* Queue it, don't try to deliver. */ + args[i++] = "-oi"; /* Ignore '.' on a line by itself. */ + + /* set from system and protocol used */ + if (from_sys == NULL) + (void)snprintf(buf, sizeof(buf), "-p%s", domain); + else if (strchr(from_sys, '.') == NULL) + (void)snprintf(buf, sizeof(buf), "-p%s:%s.%s", + domain, from_sys, domain); + else + (void)snprintf(buf, sizeof(buf), "-p%s:%s", domain, from_sys); + args[i++] = newstr(buf); + + /* Set name of ``from'' person. */ + (void)snprintf(buf, sizeof(buf), "-f%s%s", + from_path ? from_path : "", from_user); + args[i++] = newstr(buf); + + /* + * Don't copy arguments beginning with - as they will be + * passed to sendmail and could be interpreted as flags. + * To prevent confusion of sendmail wrap < and > around + * the address (helps to pass addrs like @gw1,@gw2:aa@bb) + */ + while (*argv) { + if (**argv == '-') + err(EX_USAGE, "dash precedes argument: %s", *argv); + if (strchr(*argv, ',') == NULL || strchr(*argv, '<') != NULL) + args[i++] = *argv; + else { + if ((args[i] = malloc(strlen(*argv) + 3)) == NULL) + err(EX_TEMPFAIL, "Cannot malloc"); + sprintf (args [i++], "<%s>", *argv); + } + argv++; + } + args[i] = 0; + + if (debug) { + (void)fprintf(stderr, "Sendmail arguments:\n"); + for (i = 0; args[i]; i++) + (void)fprintf(stderr, "\t%s\n", args[i]); + } + + /* + * If called with a regular file as standard input, seek to the right + * position in the file and just exec sendmail. Could probably skip + * skip the stat, but it's not unreasonable to believe that a failed + * seek will cause future reads to fail. + */ + if (!fstat(STDIN_FILENO, &sb) && S_ISREG(sb.st_mode)) { + if (lseek(STDIN_FILENO, offset, SEEK_SET) != offset) + err(EX_TEMPFAIL, "stdin seek"); + execv(_PATH_SENDMAIL, args); + err(EX_OSERR, "%s", _PATH_SENDMAIL); + } + + if (pipe(pdes) < 0) + err(EX_OSERR, NULL); + + switch (pid = FORK()) { + case -1: /* Err. */ + err(EX_OSERR, NULL); + case 0: /* Child. */ + if (pdes[0] != STDIN_FILENO) { + (void)dup2(pdes[0], STDIN_FILENO); + (void)close(pdes[0]); + } + (void)close(pdes[1]); + execv(_PATH_SENDMAIL, args); + _exit(127); + /* NOTREACHED */ + } + + if ((fp = fdopen(pdes[1], "w")) == NULL) + err(EX_OSERR, NULL); + (void)close(pdes[0]); + + /* Copy the file down the pipe. */ + do { + (void)fprintf(fp, "%s", lbuf); + } while (fgets(lbuf, sizeof(lbuf), stdin) != NULL); + + if (ferror(stdin)) + err(EX_TEMPFAIL, "stdin: %s", strerror(errno)); + + if (fclose(fp)) + err(EX_OSERR, NULL); + + if ((waitpid(pid, &status, 0)) == -1) + err(EX_OSERR, "%s", _PATH_SENDMAIL); + + if (!WIFEXITED(status)) + err(EX_OSERR, + "%s: did not terminate normally", _PATH_SENDMAIL); + + if (WEXITSTATUS(status)) + err(status, "%s: terminated with %d (non-zero) status", + _PATH_SENDMAIL, WEXITSTATUS(status)); + exit(EX_OK); +} + +void +usage() +{ + (void)fprintf(stderr, "usage: rmail [-T] [-D domain] user ...\n"); + exit(EX_USAGE); +} + +#ifdef __STDC__ +#include +#else +#include +#endif + +void +#ifdef __STDC__ +err(int eval, const char *fmt, ...) +#else +err(eval, fmt, va_alist) + int eval; + const char *fmt; + va_dcl +#endif +{ + va_list ap; +#if __STDC__ + va_start(ap, fmt); +#else + va_start(ap); +#endif + (void)fprintf(stderr, "rmail: "); + (void)vfprintf(stderr, fmt, ap); + va_end(ap); + (void)fprintf(stderr, "\n"); + exit(eval); +} + +#if !HASSTRERROR + +char * +strerror(eno) + int eno; +{ + extern int sys_nerr; + extern char *sys_errlist[]; + static char ebuf[60]; + + if (eno >= 0 && eno < sys_nerr) + return sys_errlist[eno]; + (void) sprintf(ebuf, "Error %d", eno); + return ebuf; +} + +#endif /* !HASSTRERROR */ -- cgit v1.1