#! /usr/bin/perl -w # member_watch.pl use strict; my ($repdate,$date,$ufile1,$ufile2,$track1,$track2,$tmpfile); chomp($repdate = `/bin/date "+%A %d %B %Y"`); $date = `date +%d/%m/%y`; $ufile1 = "/path/to/htpasswd-ONE"; $ufile2 = "/path/to/htpasswd-TWO"; $track1 = "/path/to/log/location/service1"; $track2 = "/path/to/log/location/service2"; $tmpfile= "/tmp/member.report"; chomp($date); # get users from PREVIOUS htpasswd my @traw1 = parse_trackfile($track1); my @traw2 = parse_trackfile($track2); my @tusers_service1 = sort @traw1; my @tusers_service2 = sort @traw2; # get current users from htpasswd my @uraw1 = parse_htpasswd($ufile1,$track1); my @uraw2 = parse_htpasswd($ufile2,$track2); # sort lexically -- (alphabetically) my @cusers_service1 = sort @uraw1; my @cusers_service2 = sort @uraw2; calculate_users("Service 1",\@cusers_service1,\@tusers_service1); calculate_users("Service 2",\@cusers_service2,\@tusers_service2); # --------------- # subroutines # --------------- sub parse_trackfile { my $trackfile = shift; chomp (my $now = `date +%Y.%m.%d`); my @users; open FILE,$trackfile or die "Cannot open $trackfile: $!"; while (<FILE>) { next if $_ =~ /^$/; next if $_ =~ /^\#$/; chomp($_); push @users,$_; } close FILE or warn $!; system("cp","$trackfile","${trackfile}-$now"); return @users; } sub parse_htpasswd { my ($ufile,$trackfile) = @_; my (@users,$user,$pass); open TRACK,">$trackfile" or die "Cannot open $trackfile: $!\n"; open FILE,$ufile or die "Cannot open $ufile: $!\n"; while (<FILE>) { next if $_ =~ /^$/; next if $_ =~ /^\#$/; ($user,$pass) = split /:/; print TRACK "$user\n"; push @users, $user; } close FILE or warn $!; close TRACK or warn $!; return @users; } sub calculate_users { my ($service,$current,$previous) = @_; my %current = map { $_ => 1 } @$current; my %previous = map { $_ => 1 } @$previous; # calculate NEW users my @new_users = grep (!defined $previous{$_},@$current); # calculate CANCELLED users my @cancelled_users = grep (!defined $current{$_},@$previous); # calculate REMAINING users my @remaining_users = grep($current{$_},@$previous); my ($new_cnt,$canc_cnt,$rem_cnt); if (@new_users) { $new_cnt = $#new_users; } else { $new_cnt = "0"; } if (@cancelled_users) { $canc_cnt = $#cancelled_users; } else { $canc_cnt = "0"; } if (@remaining_users) { $rem_cnt = $#remaining_users; } else { $rem_cnt = "0"; } # open temp file for writing: open TMP, ">$tmpfile" or die $!; # print the report suitable for emailing print TMP "$service: Member Information for $repdate\n\n"; print TMP "New Members:\t\t $new_cnt\n"; print TMP "Cancelled Members:\t $canc_cnt\n"; print TMP "Remaining Members:\t $rem_cnt\n"; print TMP "\n"; print TMP "------- New ------------------\n"; print TMP "\t$_\n" for @new_users; print TMP "------------------------------\n\n"; print TMP "------- Cancelled ------------\n"; print TMP "\t$_\n" for @cancelled_users; print TMP "------------------------------\n\n"; print TMP "------- Remaining ------------\n"; print TMP "\t$_\n" for @remaining_users; print TMP "------------------------------\n"; close TMP or warn $!; email_daily_report($service); clean_up(); } sub email_daily_report { my ($service) = @_; chomp (my $hostname = `/bin/hostname`); open TMP,$tmpfile or die "Cannot open $tmpfile: $!\n"; open(SENDMAIL, "|/usr/lib/sendmail -oi -t") or die "Cannot fork for sendmail: $!\n"; print SENDMAIL "From: MemberWatch <nobody\@${hostname}>\n"; print SENDMAIL "To: Webmaster <webmaster\@somedomain.dom>\n"; print SENDMAIL "Cc: Accounting <accounting\@somedomain.dom>\n"; print SENDMAIL "Subject: [$service] Members: $repdate\n"; print SENDMAIL "\n"; while (<TMP>) { print SENDMAIL "$_"; } close(SENDMAIL) or warn "Oops, sendmail did not close nicely"; close TMP or warn $!; } sub clean_up { unlink $tmpfile or die "Cannot unlink $tmpfile: $!\n"; }

In reply to Member Watcher by penguinfuz

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.