home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / perl / scripts-osu / cmail.shar < prev    next >
Encoding:
Internet Message Format  |  1989-10-26  |  5.2 KB

  1. Path: tut.cis.ohio-state.edu!gem.mps.ohio-state.edu!ctrsol!lll-winken!sun-barr!newstop!texsun!convex!tchrist@convex.COM
  2. From: tchrist@convex.COM (Tom Christiansen)
  3. Newsgroups: alt.sources
  4. Subject: Re: Cmail - check to see who's read their mail - UNIX
  5. Message-ID: <2332@convex.UUCP>
  6. Date: 24 Oct 89 05:46:15 GMT
  7. References: <1121@kl-cs.UUCP>
  8. Sender: usenet@convex.UUCP
  9. Reply-To: tchrist@convex.COM (Tom Christiansen)
  10. Followup-To: alt.sources.d
  11. Organization: CONVEX Software Development, Richardson, TX
  12. Lines: 130
  13.  
  14. In article <1121@kl-cs.UUCP> jonathan@cs.keele.ac.uk (Jonathan Knight) writes:
  15.  
  16. >Here's a neat little program which detects whether users on your
  17. >local machine have ready their mail recently.  It reports when they
  18. >last checked it and also whether any new mail has arrived since.
  19. >Very useful if your local machine uses userids which are based on
  20. >department or type of user or year of graduation.
  21.  
  22. Sigh.  Yet another piece of system administrative hackery written in C.
  23. This one took over 300 lines and contains various and sundry data structures
  24. and subroutines.  I don't mean to impune the competence of the original
  25. author.  It *is* a neat little program.  But it seems like terrific overkill
  26. to do this in C.  So as an exercise, I rewrote the program in perl (version
  27. 3.0).   It took *substantially* less code: around 15%.  I'll bet it was
  28. faster to write and faster to debug.  I'm sure it'll be faster to modify.
  29. Even if you don't have perl, check out my script here.  I think you'll agree
  30. that it's **MILES** clearer than the corresponding C code.
  31.  
  32. I wanted to do some timing comparisons, but found that the original program
  33. used SysV's regexp() routines rather than BSD's rexex().  So if anyone else
  34. wants to post timings to alt.sources.d, I'd be interested in seeing them.
  35.  
  36. Meanwhile, both to demonstrate the marvelousness of perl and also to chase
  37. off the non-source-posting haranguers, here is the code.  I have retained the
  38. basic structure, routine names, and variable names of the original code where
  39. reasonable to do so, perhaps more so than was optimal.  Two comments on the
  40. original C code: doing getpwent()s until you run out is terribly innefficient
  41. on systems with long passwd files; mine is ~1300 lines long, and it would be
  42. better to do readdir()s on SPOOL and then getpwnam()s on the results.
  43. Secondly, the author has what is to me an odd style to his code (comment
  44. placement, argument placement, curley placement), so I ran it through indent
  45. to put it in KNF (kernel normal form) before conversion.  This was purely
  46. aesthetic.
  47.  
  48. Recall that you will need version 3 of perl.  I include after the cmail.pl
  49. script code for the ctime() function, which is not a perl intrinsic.  The
  50. ctime.pl code was posted to the net some time ago, but I've unfortunately
  51. lost the info on the original author.  I thank him for his code and apologize
  52. for not having provided his proper credit.
  53.  
  54.  
  55. --tom
  56.  
  57. #!/bin/sh
  58. #    This is a shell archive.
  59. #    Run the following text with /bin/sh to extract.
  60.  
  61. echo x cmail.pl
  62. sed -e 's/^X//' << \EOFMARK > cmail.pl
  63. X#!/usr/local/bin/perl3
  64. X
  65. X$PRINT1        = "%-10.10s %-25.25s ";
  66. X$VERSION     = "1.2";
  67. X$DATE        = "23 October";
  68. X$YEAR        = "1989";
  69. X$SPOOL        = "/usr/spool/mail";
  70. X
  71. Xdo 'ctime.pl';
  72. X($myname = $0) =~ s%.*/%%;
  73. X
  74. Xif ($ARGV[0] eq "-v") {
  75. X   printf "%s Version %.1f, %s %d; Tom Christiansen <tchrist@convex.com>\n",
  76. X    $myname, $VERSION, $DATE, $YEAR;
  77. X   shift;
  78. X} 
  79. X
  80. Xexit 0 unless $#ARGV > $[-1;
  81. Xchdir $SPOOL || die "$myname: can't access mail spool directory: $!\n";
  82. Xdo build(@ARGV);
  83. Xdo printarray();
  84. Xexit 0;
  85. X
  86. Xsub build {
  87. X    setpwent;
  88. Xpw: while (($name, $passwd, $uid, 
  89. X        $gid, $quota, $comment,
  90. X        $gcos, $dir, $shell) = getpwent)
  91. X    {
  92. Xrexpr:  foreach $rexpr ( @_ ) {
  93. X        next rexpr unless $name =~ /^$rexpr/;
  94. X        $matched_rexprs{$rexpr}++;
  95. X        ( $fullname = $gcos ) =~ s/,.*//;
  96. X        $fullname{$name} = $fullname;
  97. X        next pw;
  98. X    } 
  99. X    } 
  100. X    endpwent;
  101. X
  102. X    foreach $rexpr ( @_ ) {
  103. X    next if $matched_rexprs{$rexpr};
  104. X    printf stderr "No users matched %s\n", $rexpr;
  105. X    } 
  106. X} 
  107. X
  108. Xsub printarray {
  109. X    foreach $user ( keys %fullname ) {
  110. X    printf $PRINT1, $user, $fullname{$user};
  111. X    if ( -e $user ) {
  112. X        ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
  113. X           $atime,$mtime,$ctime,$blksize,$blocks) = stat(_);
  114. X        printf "%.19s", &ctime($atime);
  115. X        print "  New Mail" if $atime < $mtime && $size;
  116. X    }
  117. X    print "\n";
  118. X    } 
  119. X} 
  120. EOFMARK
  121. echo x ctime.pl
  122. sed -e 's/^X//' << \EOFMARK > ctime.pl
  123. X@DoW = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
  124. X@MoY = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
  125. X
  126. Xsub ctime {
  127. X    local($time) = @_;
  128. X    local($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst);
  129. X    local($date);
  130. X
  131. X    ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
  132. X                              = localtime($time);
  133. X    $year += ($year < 70)? 2000: 1900;
  134. X    $date = sprintf("%s %s %2d %2d:%02d:%02d %s %4d\n",
  135. X          $DoW[$wday], $MoY[$mon], $mday, $hour, $min, $sec, 
  136. X          $ENV{'TZ'}, $year);
  137. X    return $date;
  138. X}
  139. EOFMARK
  140.  
  141.     Tom Christiansen                       {uunet,uiucdcs,sun}!convex!tchrist 
  142.     Convex Computer Corporation                            tchrist@convex.COM
  143.          "EMACS belongs in <sys/errno.h>: Editor too big!"
  144.  
  145.