Cover V05, I05
Article
Listing 1
Sidebar 1
Sidebar 2

may96.tar


Listing 1: Source code for SelectNews.pl

#!/usr/local/bin/perl

# /u1/perl/SelectNews.pl		2 feb 1996

# @(#) SelectNews.pl shows the user news based on who the user is.
#      It's not meant to replace the Unix news command, but rather
#      to be run in addition to it.

# Associated files:
#    1. /etc/SelectNews has lines of the form
#	    directory user user user ...
#       where directory is where the news for this group of users is kept
#       and user is a Perl regular expression for a class of
#       user login names. For example,
#	  /u1/SelectNews/Operators       ^O[0-9][0-9]$    ^ajd$
#           /u1/SelectNews/Programmers  ^P[0-9][0-9]$     ^ajd$
#       says show user ajd and users like O12 and O34 the news in
#	/u1/SelectNews/Operators, and show user ajd and users like P34
#	and P95 the news in /u1/SelectNews/Programmers.
#       (note: the same user can appear on multiple lines.)
#    2. Each user gets a file named .SelectNews.pl in their home directory.
#       (If it doesn't already exist, SelectNews.pl creates it.) The file
#       is used to record the time the news was last displayed by SelectNews.pl

# Note: /etc/SelectNews uses Perl regular expressions, not Shell regular
#       expressions!

# Author: Art D'Adamo, dadamo@voicenet.com,
#         BISYS Plan Services (215)-542-2522
#         Look for corrections/updated versions at
#         http://www.voicenet.com/~dadamo

# Set the display commands. This version uses 'pg'. Systems that don't
# have 'pg' may need to use 'more'
$DisplayCmd = "/usr/bin/pg -p \"pg: q to exit > \" ";

&Initialize;

$LoginName = &GetLoginName;  # gets user's login name

$BaseTime = &GetBaseTime;   # get base time from this user's
# .SelectNews.pl

&SetNewsDirs;  # make list of news directory(s) for this user

# make list of news files to be displayed
foreach $Dir ( @NewsDir ) { &MakeDisplayFile( $Dir ); }

&ShowDisplayFile;  # display the news

&UpdateDotFileTime;   # update $DotFile time

exit;

#------------------------------- functions --------------------------------
sub Initialize {
$RealUID = $<;	# get user's real UID
$HomeDir = $ENV{"HOME"};
$DotFile = $HomeDir . "/" . ".SelectNews.pl"; # has time of last news showing
$TimeOfDay = $^T;
# print " - UID: $RealUID, dir: $HomeDir, dot: $DotFile, time: $TimeOfDay\n";
$ClearCmd = "/usr/bin/clear";
$Date = `/bin/date \"+%A, %d %b %Y\"`;  chop($Date);
$Host1 = `/bin/uname -a`;  ($p0,$Host) = split(/ +/,$Host1);
$DirUserList = "/etc/SelectNews";  # system-wide list of users & news dirs.
$Pid = getppid;  $DisplayFile = "/tmp/SelectNews.pl.$Pid";
system("/bin/rm -f $DisplayFile");
$ShowDisplayFile = 0;
1;  # set return value
}

sub GetLoginName {
# get and return login name of this real UID
local($LogName);   $LogName = "";  local($NotFound);  $NotFound = 1;
open(PASSWD, "/etc/passwd") || die " - Can't open /etc/passwd";
while( ($Line = <PASSWD>) && $NotFound ) {
chop;   ($login,$passwd,$uid) = split(/:/,$Line);
# printf "RealUID: $RealUID, login: $login, passwd: $passwd, uid: $uid\n";
if( $RealUID eq $uid ) { $LogName = $login; $NotFound = 0; }
}
close(PASSWD);
if( "" eq $LogName ) { die " - Can't determine login name"; }
# printf " - LoginName: [$LogName]\n";
$LogName;  # set return value
}

sub GetBaseTime {
# get base time
local($RetVal);
# create .SelectNews.pl if necessary.
unless ( -e $DotFile ) {
$Cmd = "/bin/touch -t 197001010101 $DotFile";
system($Cmd) && die "(1) Command [$Cmd] failed.";
# print " - created $DotFile\n";
}
# get base time from this user's .SelectNews.pl
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks) = stat($DotFile);
$RetVal = $atime;   # print " - BaseTime: $RetVal []\n";
$RetVal;  # set return value
}

sub SetNewsDirs {
# make list of all news directory(s) for this user
open(DUL,$DirUserList) ||
die " - SelectNews.pl fatal error: Couldn't open [$DirUserList]";
@NewsDir = "";   $NewsDirCount = 0;
while( <DUL> ) {
@Line = split(/\s+/,$_);  # printf "[@Line]\n";
$Dir = shift(@Line);      # printf "{$Dir}\n";
while( ($NameRegExp = shift(@Line) ) ) {
# printf " NameRegExp: {$NameRegExp} - ";
if( $LoginName =~ /$NameRegExp/ ) {
# printf "<$LoginName> ";
$NewsDir[$NewsDirCount++] = $Dir;
}
# printf "\n";
}
}
close(DUL);
# printf "$NewsDirCount, [@NewsDir]\n";
if( $NewsDirCount < 1 ) { exit; }  # no news directories, so exit
# remove any duplicates from @NewsDir
@TempDir = sort @NewsDir;  @NewsDir = "";
$LastDir = "";  $DirCount = 0;
foreach $Dir ( @TempDir ) {
if( $Dir ne $LastDir ) { $NewsDir[$DirCount++] = $Dir; }
$LastDir = $Dir;
}
# printf " - {@NewsDir}\n";
1;  # set return value
}

sub MakeDisplayFile {
# concatenate news files to be displayed into one display file
local($ThisDir);  $ThisDir=$_[0];
opendir(DIR,$ThisDir) || die "Could open [$ThisDir]";
while( $aFile = readdir(DIR) ) {
$NewsFile = $ThisDir . "/" . $aFile;
unless( -T $NewsFile ) { next; }
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
$atime,$mtime,$ctime,$blksize,$blocks) = stat($NewsFile);
# print "NewsFile: $NewsFile, atime: $atime\n";
if( $mtime > $BaseTime ) {
# add this file to display list
$Cmd = "/bin/cat $NewsFile >> $DisplayFile"; system($Cmd);
$ShowDisplayFile = 1;
}
}
1;  # set return value
}

sub ShowDisplayFile {
# display file; get prompt before exiting
$DisplayCmd = $DisplayCmd . " $DisplayFile";
# print "$DisplayCmd"; exit;
if( $ShowDisplayFile ) {
# print " - DisplayCmd: $DisplayCmd\n";
print " - Select News for $Host on $Date \n";
system($DisplayCmd); # && die " - problem displaying Select News";
print "\n - End of Select News for $Host on $Date \n";
print " - press ENTER key to continue\n";
$Continue = <STDIN>;
}
1;  # set return value
}

sub UpdateDotFileTime {
# update time of user's .SelectNews.pl before exiting
$Cmd = "/bin/touch $DotFile";
system($Cmd) && die "(2) Command [$Cmd] failed.";
system("/bin/rm -f $DisplayFile");  # remove the display file
1;   # set return value
}

#end of file