Slackers' Network Internal Documentation |
|
Armed with a basic knowledge of what Zephyr is, and how it can be used, let's step through a short session with our sample user, jb0r (Jello Biafra).
In order to start Zephyr, Jello must have
Kerberos credentials (called
"tickets"). For now, we'll assume that these were either issued
when he logged in, or he's already
obtained them for other
purposes. But Jello has been logged in for a while, and wants to
check that his tickets haven't expired. He does this using the
klist(1)
command:
[~/] % klist Ticket file: /tmp/tkt666 Principal: jb0r@SLACKERS.NET Issued Expires Principal May 23 05:23:05 May 23 17:23:14 krbtgt.SLACKERS.NET@SLACKERS.NET
Well and good, he's off and running. To register himself with
the Zephyr server, and start accepting messages, Jello uses
zstart(1)
command.
Provided there are no error messages reported in the next few
seconds, Jello should now be receiving incoming messages:
[~/] % zstart [~/] %
(Note:
zstart(1)
simply makes
sure a Zephyr Host Manager
(zhm(8)
) is running and
invokes zwgc(1)
with the
correct arguments.)
If you are running X11, and have your $DISPLAY
environment variable set,
zstart(1)
will tell
Zephyr to create a small window for each message you
receive. Clicking a message dismisses it. There are many
advantages to this interface (See Advanced
Topics for some hints on abusing it), but it is not always
desirable. To prevent this from happening, clear
$DISPLAY
. You can do this easily without disrupting
your current environment thus:
[~/] % ( unset DISPLAY ; zstart )
or, for (t)csh users:
[~/] % ( unsetenv DISPLAY ; zstart )
Now that Jello can receive messages, he can send messages to
others. (Note: Jello doesn't have to be
zstarted to send a zephyrgram. But, on the other
hand, his name is not Faisal, either.) Using the
zwrite(1)
command, Jello
sends a message to the user klaus (Klaus Fluoride):
[~/] % zwrite klaus Type your message now. End with control-D or a dot on a line by itself. I've got your "cost-effective message" right here, buddy! . klaus: Message sent
Provided Klaus is at his terminal (and conscious), he'll get the message and respond. Jello will get a message:
Personal Message at 14:05:32 on Fri May 23 'Bout time you showed up... Klaus Fluoride <klaus> on tentacle
hint:
zwrite(1)
is by far the
most often used Zephyr command. It's also rather long to type
every time you want to use it. That makes it a perfect candidate
to be aliased to something shorter! See your shell's manpage
for additional help.
Zephyr also provides a means to keep track of a list of users.
znol(1)
will give you
Zephyr statistics for the people in your list when you first run it,
and then let you know whenever one of them starts or stops
Zephyr. By default,
znol(1)
looks in the file
$HOME/.anyone
for a list of users to spy on.
For instance, if ~jb0r/.anyone looks something like this:
[~/] % cat ~/.anyone ebray klaus ted jb0r
and he ran znol now, he'd get this: (Note: znol takes a few seconds to run)
[~/] % znol klaus: tentacle.slackers.net console Fri May 23 12:34:56 1986 jb0r: skulhedface.slackers.net ttyq0 Fri May 23 16:49:38 1986
If klaus logged out (or just zstop(1)
'ed) he would
see a message similar to this:
klaus logged out from tentacle on console at Fri May 23 16:50:58 1986
In order to pass data between the different programs, and to
save it between sessions, Zephyr uses variables (sometimes
called "zvars"), which are stored in the file
$HOME/.zephyr.vars
One of the functions provided by the
zctl(1)
command is the
inspection and modification of Zephyr variables, through the
show
and
set
options respectively.
A Zephyr variable name consists of one or more non-whitespace (space, tab, newline, etc...) characters. The value of a Zephyr variable consists of any number of characters except newline, but leading whitespace will be truncated.
Within these guidelines, you can set any Zephyr variable to any
value you choose. One reason for doing so is to affect a
customized behavior of
zwgc(1)
. But a few Zephyr
variables are used by other Zephyr programs:
zwrite(1)
allows the user
to specify a "Signature" that appears with the username in the
from-line. The default value is the user's full name from
/etc/paswd
. For example, if Jello wants to change
his signature, he'll probably send messages to himself to test
it: (The -m
option specifies the message on the
command line, so that he doesn't have to type a message every
time)
[~/] % zwrite jb0r -m test Personal Message at 14:06:42 on Fri May 23 test Jello Biafra <jb0r> on skulhedface jb0r: Message sent [~/] % zwrite jb0r -s jello -m test Personal Message at 14:06:42 on Fri May 23 test jello <jb0r> on skulhedface jb0r: Message sent [~/] % zwrite jb0r -s j3110 -m test Personal Message at 14:06:42 on Fri May 23 test j3110 <jb0r> on skulhedface jb0r: Message sent
Now, even if he DID alias it, it would be rather clumsy for him
to use the -s
option on EVERY zwrite command.
Fortunately, zwrite(1)
will use the zwrite-signature
Zephyr variable, it it exists.
[~/] % zctl set zwrite-signature jello [~/] % zwrite jb0r -m test Personal Message at 14:06:42 on Fri May 23 test jello <jb0r> on skulhedface jb0r: Message sent [~/] % zwrite jb0r -s OVERRIDE -m test Personal Message at 14:06:42 on Fri May 23 test OVERRIDE <jb0r> on skulhedface jb0r: Message sent
The second example shows that -s
takes precedence
over zwrite-signature
.
The exposure
Zephyr variable
affects a user's visibility, and is magic in that it can only be
set to the following values:
zwgc(1)
.
Zephyr also supports sending zephyrgrams to multiple recipients.
The simplest way to do this is to specify more than one user on
a zwrite(1)
command line.
But Zephyr also supports sending to a generalized list. Let's
step back. Every zephyrgram (Zephyr message) has several
attributes. Three of those attributes are it's
class
,
instance
, and
recipient
. The default
class
is message
, the
default instance
is
Personal
and the default
recipient
is *
(everyone subscribed). These three attributes form a tuple that
is known as the "distribution" of a message. Distribution tuples
are usually grouped
class
,instance
,recipient
zwrite(1)
requires that
at least one of those three be overridden for a message to be
sent. When Jello sent a Personal message to Klaus, he overrode
the recipient
attribute. In effect, although he
didn't specify it, he sent a zephyrgram to the
message,Personal,klaus@SLACKERS.NET
distribution.
The reason this works is that klaus has a subscription to
message,Personal,%me%
(%me%
is a
special recipient that is expanded to the current
Kerberos principal). This is one of
the default subscriptions. Slackers' Network default
subscriptions include:
message,Personal,%me%
message,urgent,%me%
operations,message,*
official,*,*
NOTE: operations,message,*
and
official,*,*
are restricted, and zephyrgrams can
only be sent to them by Operations staff.
You can subscribe to other broadcast distributions using
zctl(1)
. The
sub[scribe]
,
add
,
unsub[scribe]
, and
add_unsub[scription]
commands
control a user's subscriptions. Each take the three elements of
a distribution tuple as arguments.
sub[scribe]
and
unsub[scribe]
add or remove the
subscription for the session.
add
,
add_unsub[scription]
also add or
remove the subscription for the session, but also the
[un]subscription to $HOME/.zephyr.subs
, which is
read at startup, or any time the zctl load
command
is issued.
NOTE: If you are issuing zctl
commands on your shell command line (as opposed to
zctl
's interactive mode), you'll have to escape any
shell meta characters (like *
, or &
)
to keep your shell from expanding them. See the manpage for your
shell for details.
If Jello was looking for help, he might send a zephyrgram to
message,help,*
. To see the responses, he would have
to be subscribed himself:
[~/] % zctl sub message help \* [~/] %
Using the -i
option on
zwrite(1)
overrides the
instance
of a Zephyrgram tuple. This is the most
common way to send a broadcast message. For instance:
[~/] % zwrite -i help Type your message now. End with control-D or a dot on a line by itself. How do I stop all these cornholio messages I don't care about? . help: Message sent help {Broadcast} Message at 18:10:56 on Mon Fri May 23 How do I stop all these cornholio broadcast messages I don't care about? jello <jb0r> on skulhedface
And with luck, the reply will come soon:
help {Broadcast} Message at 18:10:59 on Mon Fri May 23 zctl punt cornholio East Bay Ray <ebray> on skulhedface [~/] % zctl punt cornholio Punting <message,cornholio,*> [~/] % zwrite -i help -m thanks help {Broadcast} Message at 18:11:01 on Mon Fri May 23 thanks jello <jb0r> on skulhedface help: Message sent
Finally we have some Zephyr tools that don't fit any of the above categories, aren't worth a section of their own, but are worth mentioning.
zlocate(1)
can be used
to find out Zephyr statistics for a user. Statistics are similar
to znol(1)
, except you are not
subscribed to user's login/out messages, and you don't need to
be running Zephyr.
For those users running an X11 server,
zwatch(1)
provides a nice
X interface to Personal zephyrgrams. It's great for two-click
composition in an X window.
zrepeat(1)
tells
zwgc(1)
to replay the last
zephyrgram you received. If given a numeric argument n,
it tells zwgc
to replay the nth previous
message (not counting replays).
NOTE: By default, zwgc only keeps the last
message, and needs to be instructed to keep more. The default
zwgc.desc
instructs zwgc
to save the
previous m messages, where m is defined as the
length of the Zephyr variable
replay-count
.
zaway(1)
automatically
answers Personal zephyrgrams for you when you're away from your
terminal.
zleave(1)
sends you
reminders about events.
Much of the power and versatility of Zephyr comes from the
customization of zwgc(1)
.
A tutorial with some useful .zwgc.desc
hacks is in
the works.
We run the CMU hacked version of MIT Zephyr. Recently
Zarf's
zwgcplus
hack was folded into the main trunk of the
CMU development tree. This is a
Good Thing™.
zwgcplus
provides many advantages (for X users)
over the standard zwgc
. A zwgcplus
tutorial is also forthcoming.
Well, if we knew of pointers to more information, why would I have written this tutorial??