[alt.sources] A Perl version of "wall"

chip@tct.uucp (Chip Salzenberg) (05/04/90)

[This article is a good example of why we need "comp.unix.admin".]

Dismayed by the weird behavior of SCO Xenix "wall" (write to all
users), I wrote a Perl version that I like a lot better:

1.  It has nice prompts.
2.  It tells you who you're writing to.
3.  It skips pseudo-ttys, which is nice since we use pty-based
    multiscreens.  (You may want to remove this feature.)

Shar and 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:  wall
# Wrapped by root@tct on Fri May  4 09:40:24 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'wall' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'wall'\"
else
echo shar: Extracting \"'wall'\" \(911 characters\)
sed "s/^X//" >'wall' <<'END_OF_FILE'
Xeval 'exec /bin/perl -wS $0 ${1+"$@"}'
X	if 0;
X
X#
X# A Perl version of the rather screwy Xenix "wall" command.
X# Written by Chip Salzenberg, 3 May 1990.
X#
X
X$| = 1;
X
X$_ = `who am i 2>/dev/null`;
Xchop;
X($me) = split;
X$me = "Somebody" unless $me;
X
Xprint "Enter the message to broadcast.  End with ^D.\n" if -t STDIN;
Xfor (;;) {
X	print ">> ";
X	$_ = <STDIN>;
X	unless (defined($_)) {
X		print "<EOF>\n" if -t STDIN;
X		last;
X	}
X	chop;
X	push(@MSG, "$_ \r\n");
X}
Xunless (@MSG) {
X	print stderr "wall: no message.\n";
X	exit;
X}
Xunshift(@MSG, "\007\r\nBroadcast Message from $me: \r\n");
X
Xopen(WHO, "who|");
Xwhile (<WHO>) {
X	chop;
X	@F = split;
X	$tty = $F[1];
X
X	next if $tty =~ /^ttyp.$/;
X
X	$TTY = "/dev/$tty";
X	unless (-c $TTY) {
X		print stderr "wall: $tty: no such device\n";
X		next;
X	}
X	unless (open(TTY, ">> $TTY")) {
X		print stderr "wall: can't open /dev/$tty: $!\n";
X		next;
X	}
X	print TTY @MSG;
X	close(TTY);
X}
Xclose(WHO);
END_OF_FILE
if test 911 -ne `wc -c <'wall'`; then
    echo shar: \"'wall'\" unpacked with wrong size!
fi
chmod +x 'wall'
# end of 'wall'
fi
echo shar: End of shell archive.
exit 0


-- 
Chip Salzenberg at ComDev/TCT   <chip%tct@ateng.com>, <uunet!ateng!tct!chip>

kayvan@mrspoc.Transact.COM (Kayvan Sylvan) (05/05/90)

In article <264186E0.17B3@tct.uucp> chip@tct.uucp (Chip Salzenberg) writes:

[... a rather nice version of wall ...]

	$_ = `who am i 2>/dev/null`;
	chop;
	($me) = split;
	$me = "Somebody" unless $me;

Instead of the above, I would do:

	($me = getlogin) || (($me) = getpwuid($<)) || ($me = "Somebody");

No extra process.

			---Kayvan
-- 
| Kayvan Sylvan @ Transact Software, Inc. -*-  Los Altos, CA (415) 961-6112 |
| Internet: kayvan@{mrspoc.Transact.com, eris.berkeley.edu, largo.ig.com}   |
| UUCP: ...!{apple,pyramid,bionet,mips}!mrspoc!kayvan "Imagine Cute Saying" |

lwall@jato.Jpl.Nasa.Gov (Larry Wall) (05/06/90)

In article <KAYVAN.90May5003631@mrspoc.Transact.COM> kayvan@mrspoc.Transact.COM (Kayvan Sylvan) writes:
: In article <264186E0.17B3@tct.uucp> chip@tct.uucp (Chip Salzenberg) writes:
: 
: [... a rather nice version of wall ...]
: 
: 	$_ = `who am i 2>/dev/null`;
: 	chop;
: 	($me) = split;
: 	$me = "Somebody" unless $me;
: 
: Instead of the above, I would do:
: 
: 	($me = getlogin) || (($me) = getpwuid($<)) || ($me = "Somebody");

Granted that the manual says something like that, but it can be shortened,
since || always returns one or the other of its arguments, rather than 0 and 1.
[Gee, I suppose I should document that somewhere...]

I would say

	$me = getlogin || (getpwuid($<))[0] || "Somebody";

(Though, of course, that ()[] presumes patchlevel 18.)  You could even say

	$me = getlogin || (getpwuid($<))[0] || die "Intruder Alert!\n";

Larry