home *** CD-ROM | disk | FTP | other *** search
- Path: tut.cis.ohio-state.edu!gem.mps.ohio-state.edu!ctrsol!lll-winken!sun-barr!newstop!texsun!convex!tchrist@convex.COM
- From: tchrist@convex.COM (Tom Christiansen)
- Newsgroups: alt.sources
- Subject: Re: Cmail - check to see who's read their mail - UNIX
- Message-ID: <2332@convex.UUCP>
- Date: 24 Oct 89 05:46:15 GMT
- References: <1121@kl-cs.UUCP>
- Sender: usenet@convex.UUCP
- Reply-To: tchrist@convex.COM (Tom Christiansen)
- Followup-To: alt.sources.d
- Organization: CONVEX Software Development, Richardson, TX
- Lines: 130
-
- In article <1121@kl-cs.UUCP> jonathan@cs.keele.ac.uk (Jonathan Knight) writes:
-
- >Here's a neat little program which detects whether users on your
- >local machine have ready their mail recently. It reports when they
- >last checked it and also whether any new mail has arrived since.
- >Very useful if your local machine uses userids which are based on
- >department or type of user or year of graduation.
-
- Sigh. Yet another piece of system administrative hackery written in C.
- This one took over 300 lines and contains various and sundry data structures
- and subroutines. I don't mean to impune the competence of the original
- author. It *is* a neat little program. But it seems like terrific overkill
- to do this in C. So as an exercise, I rewrote the program in perl (version
- 3.0). It took *substantially* less code: around 15%. I'll bet it was
- faster to write and faster to debug. I'm sure it'll be faster to modify.
- Even if you don't have perl, check out my script here. I think you'll agree
- that it's **MILES** clearer than the corresponding C code.
-
- I wanted to do some timing comparisons, but found that the original program
- used SysV's regexp() routines rather than BSD's rexex(). So if anyone else
- wants to post timings to alt.sources.d, I'd be interested in seeing them.
-
- Meanwhile, both to demonstrate the marvelousness of perl and also to chase
- off the non-source-posting haranguers, here is the code. I have retained the
- basic structure, routine names, and variable names of the original code where
- reasonable to do so, perhaps more so than was optimal. Two comments on the
- original C code: doing getpwent()s until you run out is terribly innefficient
- on systems with long passwd files; mine is ~1300 lines long, and it would be
- better to do readdir()s on SPOOL and then getpwnam()s on the results.
- Secondly, the author has what is to me an odd style to his code (comment
- placement, argument placement, curley placement), so I ran it through indent
- to put it in KNF (kernel normal form) before conversion. This was purely
- aesthetic.
-
- Recall that you will need version 3 of perl. I include after the cmail.pl
- script code for the ctime() function, which is not a perl intrinsic. The
- ctime.pl code was posted to the net some time ago, but I've unfortunately
- lost the info on the original author. I thank him for his code and apologize
- for not having provided his proper credit.
-
-
- --tom
-
- #!/bin/sh
- # This is a shell archive.
- # Run the following text with /bin/sh to extract.
-
- echo x cmail.pl
- sed -e 's/^X//' << \EOFMARK > cmail.pl
- X#!/usr/local/bin/perl3
- X
- X$PRINT1 = "%-10.10s %-25.25s ";
- X$VERSION = "1.2";
- X$DATE = "23 October";
- X$YEAR = "1989";
- X$SPOOL = "/usr/spool/mail";
- X
- Xdo 'ctime.pl';
- X($myname = $0) =~ s%.*/%%;
- X
- Xif ($ARGV[0] eq "-v") {
- X printf "%s Version %.1f, %s %d; Tom Christiansen <tchrist@convex.com>\n",
- X $myname, $VERSION, $DATE, $YEAR;
- X shift;
- X}
- X
- Xexit 0 unless $#ARGV > $[-1;
- Xchdir $SPOOL || die "$myname: can't access mail spool directory: $!\n";
- Xdo build(@ARGV);
- Xdo printarray();
- Xexit 0;
- X
- Xsub build {
- X setpwent;
- Xpw: while (($name, $passwd, $uid,
- X $gid, $quota, $comment,
- X $gcos, $dir, $shell) = getpwent)
- X {
- Xrexpr: foreach $rexpr ( @_ ) {
- X next rexpr unless $name =~ /^$rexpr/;
- X $matched_rexprs{$rexpr}++;
- X ( $fullname = $gcos ) =~ s/,.*//;
- X $fullname{$name} = $fullname;
- X next pw;
- X }
- X }
- X endpwent;
- X
- X foreach $rexpr ( @_ ) {
- X next if $matched_rexprs{$rexpr};
- X printf stderr "No users matched %s\n", $rexpr;
- X }
- X}
- X
- Xsub printarray {
- X foreach $user ( keys %fullname ) {
- X printf $PRINT1, $user, $fullname{$user};
- X if ( -e $user ) {
- X ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
- X $atime,$mtime,$ctime,$blksize,$blocks) = stat(_);
- X printf "%.19s", &ctime($atime);
- X print " New Mail" if $atime < $mtime && $size;
- X }
- X print "\n";
- X }
- X}
- EOFMARK
- echo x ctime.pl
- sed -e 's/^X//' << \EOFMARK > ctime.pl
- X@DoW = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
- X@MoY = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
- X
- Xsub ctime {
- X local($time) = @_;
- X local($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
- X local($date);
- X
- X ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
- X = localtime($time);
- X $year += ($year < 70)? 2000: 1900;
- X $date = sprintf("%s %s %2d %2d:%02d:%02d %s %4d\n",
- X $DoW[$wday], $MoY[$mon], $mday, $hour, $min, $sec,
- X $ENV{'TZ'}, $year);
- X return $date;
- X}
- EOFMARK
-
- Tom Christiansen {uunet,uiucdcs,sun}!convex!tchrist
- Convex Computer Corporation tchrist@convex.COM
- "EMACS belongs in <sys/errno.h>: Editor too big!"
-
-