SelectNews.pl: Perl Script for Selective News Delivery
Art D'Adamo
You can use UNIX mail to send a message to a particular
user. You can
use UNIX news to send a message to all users. But what
about when you'd
like to send a message to a select group of users, for
example, to
everyone in accounting or programming? SelectNews.pl
is a perl script
that does just that.
SelectNews.pl is modeled on the UNIX news program. It
doesn't replace
news, however, but supplements it. Like news, SelectNews.pl
shows the
user all the news they haven't already seen. A user
sees a particular
message file only once, then it is "old news"
and not displayed again.
Background
news is a UNIX utility that has two parts. The first
part is news
creation, which happens when a systems administrator,
or any other
authorized user, creates a news item in the form of
an text file and
copies it into a directory, (/usr/news on an HP-UX system).
The second part is news reading, which happens when
a user runs the news
program (which for HP-UX is /usr/bin/news). The news
program is
typically run when the user logs in, as part of the
systemwide
/etc/profile file, or perhaps as part of their Korn
shell .profile file.
How does /usr/bin/news work? First, it checks the date
and time of
.news_time, a file in the user's home directory. It's
typical for a
configuration file (like .news_time) to have a name
that starts with a
period. The period prevents some versions of the ls
command from
displaying the file, although a ls -a will display it.
The logic is, I
suppose, that a user listing files usually isn't interested
in seeing
configuration files, too.
The .news_time configuration file is unusual in that
it has zero bytes;
its only purpose is to provide a time, ctime to be specific.
Like all
UNIX files, .news_time has not one but three times associated
with it:
atime, the time it was last read; ctime, the time its
inode information
(permissions, owner, group, etc.) was last changed;
and mtime, the time
it was last written to. (By the way, mtime is sometimes
mistakenly
called the time of file creation. It isn't. UNIX doesn't
store the time
a file was created.) Of the three times, news uses ctime.
Once /usr/bin/news knows ctime, it displays all the
files in directory
/usr/news that have a more recent mtime. After the files
are displayed,
news updates the user's .news_time file, so that it
knows what files to
display next time.
Now for SelectNews.pl.
SelectNews.pl is similar to news. For example, SelectNews.pl
reads the
mtime of a file (named .SelectNews.pl) in the user's
directory. Then
like news, SelectNews.pl displays all the files with
a newer mtime.
However, instead of reading the news from just one directory,
SelectNews.pl has many directories to read news from.
It selects the
directory (or directories) based on the user's login
name.
SelectNews.pl looks in the appropriate directory(s)
and displays all the
news that is newer than the user's .SelectNews.pl file.
Then, like news,
it updates the time of .SelectNews.pl so it knows which
files to display
next time.
The ability to place a user in more than one SelectNews
group is useful.
For example, you may want to put a programmer who works
at the Anytown
branch office in both the Programmer group and the Anytown
group,
because sometimes you need to send a message to all
the programmers,
while other times you need to send a message to everyone
at the branch
office.
To handle multiple news directories, SelectNews.pl uses
a configuration
file, called /etc/SelectNews. Each line of /etc/SelectNews
has the same
form: a SelectNews directory and then one or more Perl
regular
expressions. Here's an example:
/u1/SelectNews/Operators ^O[0-9][0-9]$ ^ajd$
/u1/SelectNews/Programmers ^P[0-9][0-9]$ ^ajd$
/u1/SelectNews/Anytown ^O0[1-5]$ ^P[012][0-9]$ ^S[0-9][0-9]$
This /etc/SelectNews file says show user O34 the news
in
/u1/SelectNews/Operators, show user P45 the news in
/u1/SelectNews/Programmers, and show user ajd the news
in both
directories. News in /u1/SelectNews/Anytown is shown
to O02, O05, P00,
P29, S00 and S99, but not O06, P30, or SAB.
These nontypical login names are a holdover from the
Wang computer that
our HP replaced. A lot of our in-house applications
determine
permissions from login name, so the names had to stay.
Unfortunately,
they cause a problem when logging in over a serial line.
Refer to the
sidebar "Logging in with Nontypical Names."
There are a few things to notice about the configuration
file
/etc/SelectNews. First, spaces and tabs (i.e., whitespace)
are used as
delimiters. Second, a user can be in one or more lines
(and therefore
see the news that's in one or more directories). Finally,
and more
importantly, Perl regular expessions are used, not shell
regular
expressions.
SelectNews.pl's use of Perl regular expressions is perhaps
its biggest
stumbling block. It's very easy to forget, use a shell
regular
expression, and get unexpected results. For example,
a* as a regular
expession means something quite different to Perl than
it means to the
shell. (Refer to the sidebar "Perl Regular Expressions"
for more
details.)
With all that background, understanding SelectNews.pl
is
straightforward. Here is the algorithm.
1. When a user logs in, a line in a system login file,
/etc/profile or,
perhaps, his or her private login file, calls SelectNews.pl.
2. Function GetLoginName determines the user's login
name,.
3. Function GetBaseTime gets the time it last ran for
this user, which
is stored in the ctime of .SelectNews.pl, a file in
the user's home
directory.
4. Function SetNewsDirs makes a list of all directories
that have news
for the user. It finds the directories by looking in
/etc/SelectNews.
After it has the directories, it checks for and deletes
duplicates.
5. For each directory, function MakeDisplayFile concatenates
all files
that are more recent than the time determined in Step
3 into a
concatenation output file. The file is created in /tmp
and has the
user's PID as part of its name, to ensure uniqueness.
6. Function ShowDisplayFile displays the concatenated
output file, using
the UNIX pg command. If your system doesn't have pg,
modify the
"$DisplayCmd = ..." line, which is the first
executable line of
SelectNews.pl, to call some other display program.
7. Function UpdateDotFileTime updates the time of the
user's
.SelectNews.pl file. It also deletes the concatenated
output file.
Implementation
The Initialize and GetLoginName functions are straightforward.
The
GetBaseTime function creates a .SelectNews.pl file for
the user, if one
doesn't already exist, and then reads that file's ctime.
The SetNewsDirs
function examines the /etc/SelectNews file, picking
out the directories
that may have news for this user. It exits if it finds
no directories.
SetNewsDirs has a line:
if( $LoginName =~ /$NameRegExp/ ) {
that compares the user's login name to the Perl regular
expression from
/etc/SelectNews. If you'd rather not use Perl regular
expressions and
use literal login names instead, change this line to:
if( $LoginName eq $NameRegExp ) {
With this change, /etc/SelectNews would use literal
login names, rather
than Perl regular expressions. This approach would work
on small
systems. On my system, however, the /etc/passwd file
has more than 1,000
entries, so Perl regular expressions are definitely
the way to go.
The MakeDisplayFile gets all the recent news files in
the user's
directory(s) and concatenates them into one big file,
which is displayed
by ShowDisplayFile. It uses the UNIX function defined
by $DisplayCmd,
which is the first executable line of SelectNews.pl.
Systems that don't
have the UNIX pg command may have to change $DisplayCmd
to point to
more, less, or some other paging command. The UpdateDotFileTime
function
updates the time of the user's .SelectNews.pl file for
next time.
Another implementation feature is that debugging print
statements have
been left in SelectNews.pl, although they're commented
out. Uncomment
them if you want to see how SelectNews.pl works in more
detail.
Now that you've seen how SelectNews.pl works, and how
to configure
/etc/SelectNews, you should have no trouble getting
SelectNews.pl to
work for you. With a small investment in setup time,
SelectNews.pl can
help improve communication within your company in a
big way.
About the Author
Art D'Adamo has been working with computers professionally
since 1980.
He began as a scientific programmer using FORTRAN,
on an IBM mainframe
and then a VAX. Later, he did image processing in C
on a Sun 480 and
became the default parttime systems administrator.
For the past two
years he has been a full-time adminstrator for a HP
T500 with about 300
users, 2 Gb of RAM, and over 120 Gb of disk. Art can
be reached at
dadamo@voicenet.com. Any improved versions of SelectNews.pl
will be
available at http://www.voicenet.com/~dadamo.
|