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
|