[alt.sources] Alias Lister For Users

scs@lokkur.dexter.mi.us (Steve Simmons) (11/17/90)

At work we live and die by email, and we've got mail aliases coming
out our ears.  I get regular requests to know who's on a given alias.
Our user community is pretty computer-naive, so telling them to grep
the alias file isn't real useful.  In a flash of inspiration, I threw
together the following shell script.  Install it as 'printalias' (or
the name of your choice) on a sendmail-based system, and it'll give
you nice listings of who is in any given alias.  It's slow, but what
the hell.  Check the values of ALIASES and SENDMAIL to be sure they're
right for your installation.  Enjoy.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  printalias
# Wrapped by scs@lokkur.dexter.mi.us on Fri Nov 16 21:29:22 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'printalias' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'printalias'\"
else
echo shar: Extracting \"'printalias'\" \(1117 characters\)
sed "s/^X//" >'printalias' <<'END_OF_FILE'
X:
X# Script to tear apart a sendmail alias and list the recipients.
X# Written by Steve Simmons at home.  Public domain.
X#
X# $RCSfile: printalias,v $	$Revision: 1.1 $
X#
X# $Author: scs $	$Date: 90/11/16 17:03:06 $
X#
X# $State: Exp $	$Locker:  $
X#
X# $Log:	printalias,v $
X# Revision 1.1  90/11/16  17:03:06  scs
X# Initial revision
X# 
X#
XSCRIPT=`basename $0`
XTEMP=/tmp/$$.${SCRIPT}
XALIASES=/usr/lib/aliases
XSENDMAIL=/usr/lib/sendmail
Xif [ ! -r $ALIASES ] ; then
X	echo "${SCRIPT}: Sorry, I cannot find the aliases list ($ALIASES)."
X	exit 1
Xfi
Xif [ ! -r $SENDMAIL ] ; then
X	echo "${SCRIPT}: Sorry, I cannot find the alias processor ($SENDMAIL)."
X	exit 1
Xfi
Xtrap "rm -f $TEMP ; exit" 0 1 2
Xfor ALIAS in $*
Xdo
X	if grep "^$ALIAS:" $ALIASES 1>/dev/null 2>&1 ; then
X		$SENDMAIL -bv $ALIAS > $TEMP
X		echo "The \`$ALIAS' alias will send to:"
X		exec < $TEMP 
X		while read NAME1 TRASH
X		do
X			read NAME2 TRASH
X			read NAME3 TRASH
X			read NAME4 TRASH
X			read NAME5 TRASH
X			read NAME6 TRASH
X			echo "  " $NAME1 $NAME2 $NAME3 $NAME4 $NAME5 $NAME6
X		done | sed -e 's/\.\.\.//g'
X	else
X		echo "There is no such alias as \`$ALIAS'."
X	fi
Xdone
END_OF_FILE
if test 1117 -ne `wc -c <'printalias'`; then
    echo shar: \"'printalias'\" unpacked with wrong size!
fi
chmod +x 'printalias'
# end of 'printalias'
fi
echo shar: End of shell archive.
exit 0
-- 
"When your neighbour loses his job, it's a slowdown; when you lose your own
 job, it's a recession; when an economist loses his job it's a depression."
	-- "Six Ways To Define A Recession", The Economist, Nov. 3 1990.

rickert@mp.cs.niu.edu (Neil Rickert) (11/18/90)

In article <1990Nov17.023351.16824@lokkur.dexter.mi.us> scs@lokkur.dexter.mi.us (Steve Simmons) writes:
>
>At work we live and die by email, and we've got mail aliases coming
>out our ears.  I get regular requests to know who's on a given alias.
>Our user community is pretty computer-naive, so telling them to grep
>the alias file isn't real useful.  In a flash of inspiration, I threw
>together the following shell script.  Install it as 'printalias' (or
>the name of your choice) on a sendmail-based system, and it'll give
>you nice listings of who is in any given alias.  It's slow, but what
>the hell.  Check the values of ALIASES and SENDMAIL to be sure they're
>right for your installation.  Enjoy.
>
 You might want to check out the IDA sendmail kit, available at several
ftp sites (uxc.cso.uiuc.edu for example).  It includes a neat little
command 'dbm' which can be used for the same purpose.  You would
just say:  dbm fetch aliasname alias-file-name
and get your listing.  It's fast, but what the hell.

-- 
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
  Neil W. Rickert, Computer Science               <rickert@cs.niu.edu>
  Northern Illinois Univ.
  DeKalb, IL 60115.                                  +1-815-753-6940

scs@lokkur.dexter.mi.us (Steve Simmons) (11/18/90)

In article <1990Nov17.023351.16824@lokkur.dexter.mi.us> I wrote:

>Install it as 'printalias' (or the name of your choice) on a
>sendmail-based system, and it'll give you nice listings of who is in
>any given alias.  It's slow, but what the hell.

rickert@mp.cs.niu.edu (Neil Rickert) writes:
> You might want to check out the IDA sendmail kit, available at several
>ftp sites (uxc.cso.uiuc.edu for example).  It includes a neat little
>command 'dbm' which can be used for the same purpose.  You would
>just say:  dbm fetch aliasname alias-file-name
>and get your listing.  It's fast, but what the hell.

I live and die by IDA, and strongly recommend it to anyone dealing with
sendmail on a regular basis.

But its dbm utility doesn't do the job.  We (and many other sites)
often have heirarchical aliases -- mail to `all' is aliased to
departments, departmental mail is aliased to groups, group mail is
aliased to people, some of whom have their secretaries copied on
everything.  Doing 'dbm fetch all /usr/lib/aliases' would only list the
first level.  Even doing multiple probes would not get a full answer,
as it would not interpret aliases of the form "include filename".
Using the printalias scripot script to drive sendmail and get the
complete interpretation is the only full correct answer I know of
without requiring a suid program.

Plus the slow correct answer is better that fast wrong one.  :-)
-- 
"When your neighbour loses his job, it's a slowdown; when you lose your own
 job, it's a recession; when an economist loses his job it's a depression."
	-- "Six Ways To Define A Recession", The Economist, Nov. 3 1990.

tchrist@convex.COM (Tom Christiansen) (11/18/90)

I haven't posted these in a while, and they've grown a bit since last
time.  It does recursively resolve aliases, including following include
files and .forward files, and is pretty faster.

    pixel% getalias -V postmaster
    [ postmaster -> root ]
    [ root -> //.forward ]
    [ //.forward -> rhall, rmingee, tchrist ]
    [ rhall -> rhall@pixel ]
    [ rhall -> /mnt/rhall/.forward ]
    [ /mnt/rhall/.forward -> "| /usr/local/mh/lib/slocal -user rhall" ]
    [ rmingee -> rmingee@pixel ]
    [ tchrist -> tchrist@pixel ]
    postmaster -> "| /usr/local/mh/lib/slocal -user rhall", rmingee, tchrist

(stripped of @pixel at the end because that's where I ran the query.)


Also included is nfinger, which uses the same algorithm and fingers the
results of the alias expansion.  It passes finger switches on to finger.
I often due this to find out who's logged in from a particular project
group:

    % alias fu 'nfinger -sm'
    % fu mailing-list

Getalias has an embedded man page, so install /usr/local/bin/getalias
as a link to /usr/local/man/man1/getalias, or whatever your local
paths are.  Nfinger doesn't -- Use the Source.

ps: I admit to no longer recalling why nfinger didn't just call getalias.

--tom

#! /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:
#	getalias
#	nfinger
# This archive created: Sun Nov 18 08:32:39 1990
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'getalias'" '(4807 characters)'
if test -f 'getalias'
then
	echo shar: "will not over-write existing file 'getalias'"
else
sed 's/^	X//' << \SHAR_EOF > 'getalias'
	X#!/usr/local/bin/perl
	X'di';
	X'ig00';
	X
	Xdbmopen(ALIASES,'/usr/lib/aliases',undef) || die "can't dbmopen aliases";
	X
	Xrequire 'getopts.pl';;
	X
	X(&Getopts('vVs') && $#ARGV >= 0) || die "usage: $0 [-vVs] alias ...\n";
	X
	Xchop($host = `hostname`);
	X
	X($verbose, $showall, $short) = ($opt_v, $opt_V, $opt_s);
	X$verbose |= $showall;
	X
	Xwhile ($user = shift) {
	X    local(%seen);
	X    if ($short) {
	X	print join(' ', &resolve($user)), "\n";
	X    } else {
	X	print "$user -> ", join(', ', sort &resolve($user)), "\n";
	X    } 
	X}
	X
	Xsub resolve {
	X    local($addr,$alias,@list,@ilist);
	X
	X    while ($addr = shift) {
	X	if ($seen{$addr}++) {
	X	    #push(@list, $addr);
	X	    next;
	X	} 
	X	unless (defined $ALIASES{"$addr\0"}) {
	X	    push(@list, &forward($addr));
	X	    next;
	X	} 
	X	chop($alias = $ALIASES{"$addr\0"});
	X	$alias =~ s/^\s*(.*)\s*$/$1/;
	X	if ($alias eq $addr) {
	X	    push(@list, &forward($addr));
	X	    next;
	X	} 
	X	if ($alias =~ /^"/) {
	X	    push(@list, $alias);
	X	    next;
	X	} 
	X	print "[ $addr -> $alias ]\n" 
	X	    if $showall || ($verbose 
	X		&& ($alias !~ /^$addr@\w+$/ && 
	X		    $alias !~ /^[^!]+![^!]+$/));
	X	if ($alias eq "$addr@$host") {
	X	    push(@list, &forward($addr));
	X	    next;
	X	} 
	X	if ($alias =~ /^:include:(.*)/) {
	X	    unless (open(INC, $file = $1)) {
	X		print STDERR "$0: can't open $file: $!\n";
	X		next;
	X	    }
	X	    @ilist = grep(!/^#/, <INC>);
	X	    for (@ilist) { s/\s//g; } 
	X	    close(INC);
	X	    printf "[ %s -> %s ]\n", $file, join(' ', @ilist) if $verbose;
	X	    push(@list,&resolve(@ilist));
	X	} else {
	X	    push(@list,&resolve(split(/\s*,\s*/,$alias)));
	X	}
	X    } 
	X    return @list;
	X} 
	X
	X
	X##############################################################
	X
	Xsub forward {
	X     local($user) = @_;
	X     local($forward); 
	X
	X     return $user if $user =~ /^\s*"?[|\/]/;
	X     return $user if $user =~ /^\s*.+@.+$/;
	X     return $user if $user =~ /^\s*.+\\?!.+$/;
	X     return $user if $user =~ /^\s*\\/;
	X
	X     if (($forward = &logdir($user)) && -r $forward .= '/.forward') {
	X	if (!open forward) {
	X	    print STDERR "$0: cannot open $forward: $!\n";
	X	} else {
	X	    print "[ $user -> $forward ]\n" if $verbose;
	X	    chop($user = <forward>);
	X	    close forward;
	X	    print "[ $forward -> $user ]\n" if $verbose;
	X	    return &resolve(split(/\s*,\s*/,$user));
	X	}
	X     } else {
	X	#print "no forward for $user\n";
	X     } 
	X     $user = "$user <MAILER-DAEMON>" unless $forward;
	X     return $user;
	X
	X} 
	X
	X##############################################################
	X
	Xsub logdir {
	X    if (! $been_here_before++) { # might make it much faster
	X	setpwent unless $dbm_passwd = dbmopen(PASSWD,'/etc/passwd', undef);
	X    }
	X
	X    if ($dbm_passwd) {
	X	return '' unless defined $PASSWD{$_[0]};
	X	local(@a);
	X	@a = split(/[\000]+/,$PASSWD{$_[0]});
	X	return $a[$#a-1];
	X    } else {
	X	return (getpwnam($_[0]))[7];
	X    }
	X} 
	X##############################################################################
	X
	X	# These next few lines are legal in both Perl and nroff.
	X
	X.00;			# finish .ig
	X 
	X'di			\" finish diversion--previous line must be blank
	X.nr nl 0-1		\" fake up transition to first page again
	X.nr % 0			\" start at page 1
	X';<<'.ex'; #__END__ ############# From here on it's a standard manual page ############
	X.TH GETALIAS 1L
	X.de M		\" man page reference
	X\\fI\\$1\\fR\\|(\\$2\)\\$3
	X..
	X.SH NAME
	Xgetalias \- recursively resolve mail aliases
	X.SH SYNOPSIS
	X.B getalias
	X[
	X.B \-v
	X.B \-V
	X.B \-s
	X]
	X.I alias
	X\&...
	X.SH DESCRIPTION
	XThe 
	X.I getalias
	Xprogram consults the 
	X.M dbm 3X
	Xversion of the
	X.M aliases 5
	Xdatabase to rescursively resolve each of its arguments, printing
	Xthe alias's (alphabetically sorted) resolution to the standard output,
	Xseparated by commas.
	XInclude
	Xfiles referenced by the \fI:include:\fP syntax will be consulted, 
	Xas will local users'
	X.I ~/.forward
	Xfiles. 
	X.PP
	XArguemnts not appearing to be deliverable addresses
	Xare resolved to
	Xthe form ``\fIalias-name\fP <MAILER-DAEMON>'' to indicate
	Xthat such mail will probably be delivered to the mailer daemon
	Xfor subsequent complaint.
	X.PP
	XThe
	X.B \-v
	Xoption traces intermediary passes of the alias resolution for
	Xmailing lists.
	XWatching the recursion can occasionally be entertaining and informative.
	X.PP
	XThe
	X.B \-V
	Xoption is like 
	X.B \-v\c
	X, except that it also includes simple ``name -> name@host'' aliases as well.
	XThese are mailboxes that simply go to another machine, rather than 
	Xmailing lists requiring recursive expansion.
	X.PP
	XThe 
	X.B \-s
	Xoption suppresses printing of the original alias before its resolution.
	XIt also makes space the separator character.
	X.SH NOTES
	X.I Getalias
	Xis a 
	X.I perl 
	Xprogram, so you must have 
	X.I perl 
	Xon your system to run it.  Since it
	Xis not compiled, you may read the program to learn more about 
	Xhow it works internally.
	X.SH "SEE ALSO"
	X.M mail 1 ,
	X.M nfinger 1 ,
	X.M perl 1 ,
	X.M dbm 3X ,
	X.M aliases 5 ,
	X.M sendmail 8
	X.SH AUTHOR
	XTom Christiansen 
	X.I "<tchrist@convex.com>"
	X.ex
SHAR_EOF
if test 4807 -ne "`wc -c < 'getalias'`"
then
	echo shar: "error transmitting 'getalias'" '(should have been 4807 characters)'
fi
chmod 775 'getalias'
fi
echo shar: "extracting 'nfinger'" '(3329 characters)'
if test -f 'nfinger'
then
	echo shar: "will not over-write existing file 'nfinger'"
else
sed 's/^	X//' << \SHAR_EOF > 'nfinger'
	X#!/usr/local/bin/perl
	X#
	X# nfinger -- finger people at their home machines
	X#	     as defined in the /usr/lib/aliases 
	X#	     dbm file.  recursively resolve all
	X#	     aliases first, so works on lists
	X
	Xdbmopen(ALIAS,'/usr/lib/aliases',undef) || die "can't dbmopen aliases: $!";
	X
	Xchop($localhost = `hostname`);
	X
	X@finger_opts = ();
	Xwhile ($ARGV[0] =~ /^-/) { 
	X    if ($ARGV[0] eq '-v') {
	X	$verbose++;
	X	shift;
	X    } else {
	X	push(@finger_opts, shift); 
	X    }
	X} 
	X
	Xwhile ($user = shift) { 
	X    undef %seen;
	X    $seeking++;
	X    push(@finger, &resolve($user)); 
	X}
	X
	Xundef %seen;
	X@ofinger = @finger;
	Xfor (@finger) {
	X    s/^\\//;
	X    s/\s//g;
	X    push(@nfinger, $_) unless $seen{$_}++ || m#^\s*("\s*)?[|/]#;
	X} 
	X@finger = sort @nfinger;
	X
	Xif ($seeking && !@finger) {
	X    printf STDERR "$0: can't finger only pipes and files! (@ofinger)\n";
	X    exit 1;
	X} 
	X
	X$exec = "/usr/ucb/finger @finger_opts @finger\n";
	X
	Xprint $exec if $verbose;
	X
	X
	Xexec $exec unless grep(/-.*s/, @finger_opts);
	X    
	X
	Xopen (FINGER, "$exec 2>&1 |") || die "Can't open finger pipe\n";
	X
	X$mask = "%-8s%s";
	X$\ = "\n";
	X$| = 1;
	X$localhost = sprintf("%-8s", $localhost);
	X
	Xwhile (<FINGER>) {
	X    s/\s*$//;
	X    next if /^$/;
	X    if (/^\[([^\]]*)\]$/) {
	X	$host = sprintf("%-8s", $1);
	X	$sawhost = 1;
	X    } elsif (/^Login/) {
	X	if (!$printed++) {
	X	    substr($_, 9, 0) = 'Home    ';
	X	    s/   Name/Name   /;
	X	    print;
	X	}
	X	$host = $localhost unless $sawhost;
	X	$sawhost = 0;
	X    } elsif (/^\S+:/) {
	X	$sawhost = /^finger:/;
	X	print STDERR "$host <$_>";
	X    } else {
	X	substr($_, 9, 0) = $host;
	X	print;
	X    } 
	X} 
	Xclose FINGER || die "$0: error running finger, status was $?\n";
	X
	X##############################################################
	X
	Xsub resolve {
	X    local($addr,$alias,@list);
	X    local(@addrs) = @_;
	X
	X    for $addr (@addrs) {
	X	unless (defined $ALIAS{"$addr\0"}) {
	X	    push(@list, &forward($addr));
	X	    next;
	X	} 
	X	chop($alias = $ALIAS{"$addr\0"});
	X	    
	X	$alias =~ s/^\s*(.*)\s*$/$1/;
	X	$alias =~ s/^([^!]*)!([^!]+)$/$2@$1/;
	X
	X	if ($alias eq "$addr@$localhost" || $alias eq $addr) {
	X	    push(@list, &forward($addr));
	X	}  else {
	X	    print "[ $addr -> $alias ]\n" if $verbose;
	X	    push(@list,&resolve(split(/\s*,\s*/,$alias)));
	X	}
	X    } 
	X    return @list;
	X} 
	X
	X
	X##############################################################
	X
	Xsub forward {
	X     local($user) = @_;
	X     local($forward); 
	X
	X     $seen{$addr}++ && return $addr;
	X
	X     return $user if $user =~ /^\s*"?[|\/]/;
	X     return $user if $user =~ /^\s*.+@.+$/;
	X     return $user if $user =~ /^\s*.+\\?!.+$/;
	X     return $user if $user =~ /^\s*\\/;
	X
	X     if (($forward = &logdir($user)) && -r $forward .= '/.forward') {
	X	if (!open forward) {
	X	    print STDERR "$0: cannot open $forward: $!\n";
	X	} else {
	X	    print "[ $user -> $forward ]\n" if $verbose;
	X	    chop($user = <forward>);
	X	    close forward;
	X	    print "[ $forward -> $user ]\n" if $verbose;
	X	    return &resolve(split(/,/,$user));
	X	}
	X     } 
	X     return $user;
	X
	X} 
	X
	X##############################################################
	X
	Xsub logdir {
	X    if (! $been_here_before++) { # might make it much faster
	X	setpwent unless $dbm_passwd = dbmopen(PASSWD,'/etc/passwd', undef);
	X    }
	X
	X    if ($dbm_passwd) {
	X	return '' unless defined $PASSWD{$_[0]};
	X	local(@a);
	X	@a = split(/[\000]+/,$PASSWD{$_[0]});
	X	return $a[$#a-1];
	X    } else {
	X	return (getpwnam($_[0]))[7];
	X    }
	X} 
SHAR_EOF
if test 3329 -ne "`wc -c < 'nfinger'`"
then
	echo shar: "error transmitting 'nfinger'" '(should have been 3329 characters)'
fi
chmod 775 'nfinger'
fi
exit 0
#	End of shell archive

mic@ut-emx.uucp (Mic Kaczmarczik) (11/19/90)

In article <1990Nov17.023351.16824@lokkur.dexter.mi.us>
scs@lokkur.dexter.mi.us (Steve Simmons) posted a sendmail alias
expander that used sendmail -bv to verify the alias.  One advantage of
using sendmail instead of parsing the alias database directly is that
it works on systems where the alias file is distributed using Sun's
NIS (nee Yellow Pages) network database, instead of being a file on
disk. 

The script below uses the same idea as Steve's script (make *sendmail*
figure things out), but instead uses the SMTP EXPN command and parses
the server's response.  Since I haven't seen too much use of the
SMTP-through-a-pipe technique elsewhere (maybe for good reasons :-),
here 'tis. 

--mic--

------------------------------------CUT HERE-----------------------------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  expn
# Wrapped by mic@emx.utexas.edu on Sun Nov 18 22:02:23 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'expn' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'expn'\"
else
echo shar: Extracting \"'expn'\" \(634 characters\)
sed "s/^X//" >'expn' <<'END_OF_FILE'
X#!/bin/sh
X#
X# This hack runs sendmail in SMTP mode and uses the EXPN command to
X# expand an address into the real address(es) that the mail will be
X# delivered to.  It takes advantage of sendmail's ability to read
X# SMTP commands from standard input when you use the -bs flag.
X#
X#	Usage:
X#		expn alias
X#
X#	Output:
X#		the address(es) mail sent to ``alias'' will really go to
X
Xif [ -z "$1" ]; then
X	echo usage: `basename $0` sendmail-alias
X	exit 1
Xfi
Xecho "expn $1
Xquit" | /usr/lib/sendmail -bs | tr -d '\015' | \
X	sed -e 's/^250.*<\([^>]*\)>.*/\1/' \
X	    -e 's/^5[0-9][0-9].\(.*\)/\1/' \
X	    -e '/^[0-9][0-9][0-9] /d' | sort
Xexit 0
X
END_OF_FILE
if test 634 -ne `wc -c <'expn'`; then
    echo shar: \"'expn'\" unpacked with wrong size!
fi
chmod +x 'expn'
# end of 'expn'
fi
echo shar: End of shell archive.
exit 0
------------------------------------CUT HERE-----------------------------------

montnaro@spyder.crd.ge.com (Skip Montanaro) (11/22/90)

Everybody has a twist. Here's mine, written a couple of years ago.  It
handles aliases on remote machines and does full expansion by connecting to
the SMTP port of the node in the alias. It requires the Korn shell for "read
-p" and the "%%" operator on variables.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  vrfy
# Wrapped by montnaro@spyder on Wed Nov 21 13:02:16 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f vrfy -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"vrfy\"
else
echo shar: Extracting \"vrfy\" \(1670 characters\)
sed "s/^X//" >vrfy <<'END_OF_vrfy'
X#!/bin/ksh
X
Xulimit -c 0		# prevent creation of core dumps
X
X# verify the existence of a user name or alias on a given machine
X#
X# sample usage:
X#	vrfy cgsp@sprite
X#	vrfy montnaro
X#	vrfy lorensen@dwaskill egan smithwd@crd
X
Xif [ $# = 0 ] ; then
X    echo "usage: `basename $0` alias ..."
X    echo "       where alias can be of the form \"user@node\" or \"user\""
X    exit 1
Xfi
X
Xwhile [ $# -gt 0 ] ; do
X    alias=`echo $1 | sed -e 's/@.*//'`
X    node=`echo $1 | sed -e 's/^[^@]*$//' -e 's/\(.*\)@\(.*\)/\2/'`
X
X    if [ x$node = x ] ; then
X	node=`hostname`
X    fi
X
X    # try to open connection to SMTP server on $node. No real provision is
X    # made for errors in attempts to connect, unless the node is unknown.
X    /usr/ucb/telnet $node 25 2>/dev/null |&
X
X    read -p line	# Trying...
X    if [ "$line" = "$node: unknown host" ] ; then
X	print -p quit
X	echo $line
X	shift
X	continue
X    fi
X
X    read -p line	# Connected ...
X    read -p line	# Escape ...
X    read -p line	# 220 ...
X
X    # check to see if we connected okay
X    if [ "${line%% *}" != "220" ] ; then
X	echo Unable to connect to host $node:
X	shift
X	continue
X    fi
X
X    # ask the SMTP server about $alias
X    print -p "vrfy $alias"
X    read -p line
X
X    if [ "${line%% *}" = "550" ] ; then
X	# unknown user
X	echo "${line#* } on host $node."
X    elif [ "${line%%-*}" = "250" -o "${line%% *}" = "250" ] ; then
X	# one or more 250 lines follow with the alias expansion
X	print -n "$alias@$node == "
X	while [ "${line%%-*}" = "250" ] ; do
X	    echo "${line#*-}"
X	    print -n "	+ "
X	    read -p line
X	done
X	echo "${line#* }"
X    else
X	# unknown response from SMTP
X	echo "${line}"
X    fi
X
X    print -p "quit"
X
X    shift
Xdone
END_OF_vrfy
if test 1670 -ne `wc -c <vrfy`; then
    echo shar: \"vrfy\" unpacked with wrong size!
fi
chmod +x vrfy
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
--
Skip (montanaro@crdgw1.ge.com)