diff --git a/quotacheck/quotacheck.pl b/quotacheck/quotacheck.pl index 719c002..b6b0e85 100644 --- a/quotacheck/quotacheck.pl +++ b/quotacheck/quotacheck.pl @@ -1,16 +1,22 @@ -#!@@@perl@@@ +#!@@@perl@@@ -w + +use strict; use Getopt::Std; +my $time=time; +my @time=localtime($time); +my $hostname; sub warnmsg { - my ($mount, $usage, $soft, $hard, $grace, $unit) = @_; - %dosdrv = ( + my ($mount, $usage, $soft, $hard, $grace, $unit, $user) = @_; + my %dosdrv = ( '/wifosv/dosprogs' => 'H:', '/wsrdb/users' => 'J:', '/wifosv/users' => 'K:', '/usr/local/www' => 'W:', ); + my $wo; if ($dosdrv{$mount}) { $wo = 'Netzplatte ' . $dosdrv{$mount}; } else { @@ -19,8 +25,8 @@ sub warnmsg { my $msg = "Sie haben auf $wo Ihr in Disk Quotas gesetztes Limit\n" . - "überschritten. "; - + "überschritten. \n"; + if ($grace eq "EXPIRED" or $usage >= $hard-2) { $msg .= "Sie können dort KEINE Files mehr anlegen.\n" ; } else { @@ -29,10 +35,19 @@ sub warnmsg { $msg .= "Sie können noch " . (int (($hard - $usage) * 10 + 0.5) / 10) . " $unit anlegen.\n" ; } + my $mount_t = $mount; + $mount_t =~ s|/|_|g; + $msg .= "\nBei dringendem Bedarf können Sie sofort zusätzlichen Platz schaffen,\n" . "indem Sie auf $wo Files löschen, komprimieren oder auf eine\n" . "andere Netzplatte verschieben.\n" . "\n" . + "Sie können sich Ihre Verbrauchsgraphen unter\n" . + "http://sww.wsr.ac.at/intranet/quotas/$user$mount_t.gif ansehen. \n" . + "Die Quotas die Sie verwendet haben werden rot angezeigt. Außerdem zeigen\n" . + "die Softquotas, die Grenze an, die Sie überschritten haben und die Hardquotas\n" . + "die Obergrenze, die Sie nicht überschreiten können. \n" . + "\n" . "Lassen Sie sich bei Gelegenheit auch von einem der zuständigen\n" . "Systemadministratoren unterstützen:\n" . "Peter Holzer, hjp\@wsr.ac.at, Kl. 786\n" . @@ -40,26 +55,63 @@ sub warnmsg { return $msg; } +my %opts; + +sub sendmail +{ + my ($user, $msg, $mount) = @_; + + my @startgraph= + ("/usr/local/dfstat/quotagraph", + "--fs=$mount", + "--user=$user", + "--data=b", + glob("/usr/local/dfstat/quota.stat.????-??") + ); + if (system (@startgraph) != 0) { + die "cannot execute @startgraph"; + } + + if ($opts{'d'}) { + open (SENDMAIL, ">&1"); + } else { + open (SENDMAIL, "|@@@sendmail@@@ -t -i"); + } + if ($opts{'a'}) { + print SENDMAIL "To: \r\n"; + print SENDMAIL "Subject: User $user: Disk Quotas überschritten\r\n"; + } else { + print SENDMAIL "To: <$user\@wsr.ac.at>\r\n"; + print SENDMAIL "Cc: \r\n"; + print SENDMAIL "Subject: Disk Quotas überschritten\r\n"; + + } + print SENDMAIL "Reply-To: \r\n"; + print SENDMAIL "\r\n"; + print SENDMAIL "$msg\r\n"; +} + getopts('ad', \%opts); $hostname=`hostname`; chomp($hostname); open (DF, "@@@df@@@ |") or die "cannot call @@@df@@@: $!"; -$fs = $/; +my $fs = $/; undef ($/); -$df = ; +my $df = ; close(DF); $/ = $fs; $df =~ s/\n[ \t]+/ /mg; -@df = split(/\n/, $df); -for $ln (@df) { - ($fs, $total, $used, $free, $pct, $mount) = split(/\s+/, $ln); +my @df = split(/\n/, $df); +for my $ln (@df) { + my ($fs, $total, $used, $free, $pct, $mount) = split(/\s+/, $ln); if ($fs =~ m|^/dev/|) { open REPQUOTA, "@@@repquota@@@ $mount 2>/dev/null |" or die "cannot call @@@repquota@@@: $!"; while () { - $msg = ""; + my $msg = ""; + my $user; if (/(\w+) \s+ -- \s* (\d+)\s+(\d+)\s+(\d+)\s+ (\d+)\s+(\d+)\s+(\d+) @@ -71,7 +123,7 @@ for $ln (@df) { /x) { print "block limit: $1: $2 > ($3 $4) $5\n"; $user = $1; - $msg = warnmsg($mount, $2/1024, $3/1024, $4/1024, $5/1024, "MB"); + $msg = warnmsg($mount, $2/1024, $3/1024, $4/1024, $5, "MB", $user); } elsif (/(\w+) \s+ -\+ \s* (\d+)\s+(\d+)\s+(\d+)\s+ @@ -79,40 +131,46 @@ for $ln (@df) { /x) { print "file limit: $1: $5 > ($6 $7) $8\n"; $user = $1; - $msg = warnmsg($mount, $5, $6, $7, $8, "Files"); + $msg = warnmsg($mount, $5, $6, $7, $8, "Files", $user); } elsif (/(\w+) \s+ \+\+ \s* (\d+)\s+(\d+)\s+(\d+)\s+(NOT\sSTARTED|EXPIRED|\d+\.\d+\ (?:days|hours))\s+ (\d+)\s+(\d+)\s+(\d+)\s+(NOT\sSTARTED|EXPIRED|\d+\.\d+\ (?:days|hours)) /x) { print "block limit: $1: $2 > ($3 $4) $5\n"; $user = $1; - $msg = warnmsg($mount, $2/1024, $3/1024, $4/1024, $5/1024, "MB"); + $msg = warnmsg($mount, $2/1024, $3/1024, $4/1024, $5, "MB", $user); print "file limit: $1: $6 > ($7 $8) $9\n"; - $msg .= "\n\n" . warnmsg($mount, $6, $7, $8, $9, "Files"); + $msg .= "\n\n" . warnmsg($mount, $6, $7, $8, $9, "Files", $user); } else { if ($. > 2) { # ignore header lines print "$mount: $.: unparseable: $_"; } } if ($msg) { - if ($opts{'d'}) { - open (SENDMAIL, ">&1"); - } else { - open (SENDMAIL, "|@@@sendmail@@@ -t -i"); + my $timestamp = "/usr/local/dfstat/quotacheck-timestamps/$user"; + + if (!-e $timestamp) { + sendmail($user, $msg, $mount); + open (PMSG, ">$timestamp") + or die "cannot open $timestamp: $!"; + print PMSG (@time); + close (PMSG); + + } + else{ + my $comp = -A $timestamp; + print STDERR "comp = $comp\n"; + if ($comp > 5) + { + sendmail($user, $msg, $mount); + } } - if ($opts{'a'}) { - print SENDMAIL "To: \r\n"; - print SENDMAIL "Subject: User $user: Disk Quotas überschritten\r\n"; - } else { - print SENDMAIL "To: <$user\@wsr.ac.at>\r\n"; - print SENDMAIL "Cc: \r\n"; - print SENDMAIL "Subject: Disk Quotas überschritten\r\n"; - } - print SENDMAIL "Reply-To: \r\n"; - print SENDMAIL "\r\n"; - print SENDMAIL "$msg\r\n"; } - + else{ + my $user; + my @deletemsg = ("/usr/local/dfstat/quotacheck-timestamps/$user"); + unlink (@deletemsg); + } } close (REPQUOTA); } diff --git a/quotacheck/quotagraph b/quotacheck/quotagraph index 49d9d9d..39c7675 100755 --- a/quotacheck/quotagraph +++ b/quotacheck/quotagraph @@ -1,4 +1,6 @@ -#!/usr/bin/perl +#!/usr/bin/perl -w + +use strict; use Getopt::Long; use Time::Local; @@ -8,12 +10,16 @@ GetOptions(\%opts, "fs=s", "data=s", "user=s"); my $lastdate = ""; my @data = (); -my $ld; print STDERR "fs = ", $opts{"fs"}, "\n"; print STDERR "user = ", $opts{"user"}, "\n"; print STDERR "data = ", $opts{"data"}, "\n"; +sub usage { + print STDERR "Usage: $0 --fs= --user= --data=[bi]\n"; + exit(1); +} + while(<>) { my ($date, $fs, $user, $bused, $bsoft, $bhard, $iused, $isoft, $ihard) = split(/\t/); if ( @@ -22,6 +28,7 @@ while(<>) { ) { if ($date ne $lastdate) { + my $time; if ($date =~ /(\d{4})-(\d{2})-(\d{2})T(\d{1,2}):(\d{2}):(\d{2})/) { $time = timelocal($6, $5, $4, $3, $2-1, $1-1900); } else { @@ -29,36 +36,34 @@ while(<>) { } print "$date $time\n"; - $ld = {}; + my $ld; + if ($opts{data} eq "b") { + $ld = [ $bused, $bsoft, $bhard ]; + } elsif ($opts{data} eq "i") { + $ld = [ $iused, $isoft, $ihard ]; + } else { + usage(); + } push(@data, [ $time, $ld ]); $lastdate = $date; } - $ld->{$user . $fs} = $bused if ($opts{"data"} eq "bused"); - $ld->{$user . $fs} = $bsoft if ($opts{"data"} eq "bsoft"); - $ld->{$user . $fs} = $bhard if ($opts{"data"} eq "bhard"); - $ld->{$user . $fs} = $iused if ($opts{"data"} eq "iused"); - $ld->{$user . $fs} = $isoft if ($opts{"data"} eq "isoft"); - $ld->{$user . $fs} = $ihard if ($opts{"data"} eq "ihard"); } } -my @top = (sort { ($ld->{$b} <=> $ld->{$a}) } (keys %$ld))[0..9]; - -print "@top\n"; open (DATA, ">quotastat.data") or die "cannot open quotastat.data for output: $!"; for (my $i = 0; $i <= $#data; $i++) { my $time = ($data[$i])->[0]; my $data = ($data[$i])->[1]; print DATA $time; - for $j (@top) { - print DATA "\t", $data->{$j} + 0; + for my $j (@$data) { + print DATA "\t", $j + 0; } print DATA "\n"; } close(DATA); -open (CTL, ">quotastat.ctl") or die "cannot open quotastat.ctl for output: $!"; +open (CTL, ">quotacheck.ctl") or die "cannot open quotacheck.ctl for output: $!"; # generic settings @@ -73,12 +78,13 @@ my $firsttime = ($data[0])->[0]; my $lasttime = ($data[$#data])->[0]; if ($lasttime - $firsttime > 3 * 30 * 24 * 3600) { - ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($firsttime); + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($firsttime); $sec = $min = $hour = 0; $mday = 1; $firsttime = timelocal($sec,$min,$hour,$mday,$mon,$year); print CTL "set xtics rotate ("; - $comma = 0; + my $comma = 0; + my $time; for (;;) { $time = timelocal($sec,$min,$hour,$mday,$mon,$year); if ($comma) { @@ -95,14 +101,14 @@ if ($lasttime - $firsttime > 3 * 30 * 24 * 3600) { $lasttime = $time; print CTL ")\n"; } elsif ($lasttime - $firsttime > 30 * 24 * 3600) { - ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($firsttime); + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($firsttime); $firsttime -= 86400 * $wday; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($firsttime); $sec = $min = $hour = 0; - $time = $firsttime = timelocal($sec,$min,$hour,$mday,$mon,$year); + my $time = $firsttime = timelocal($sec,$min,$hour,$mday,$mon,$year); print CTL "set xtics rotate ("; - $comma = 0; + my $comma = 0; for (;;) { ($sec,$min,$hour,$mday,$mon,$year) = localtime($time); if ($comma) { @@ -115,7 +121,7 @@ if ($lasttime - $firsttime > 3 * 30 * 24 * 3600) { $time += 7 * 24 * 3600; ($sec,$min,$hour,$mday,$mon,$year) = localtime($time); - $toff = $hour * 3600 + $min * 60 * $sec; + my $toff = $hour * 3600 + $min * 60 * $sec; if ($toff != 0) { if ($toff > 12*3600) { $toff = 24 * 3600 - $toff; @@ -132,11 +138,11 @@ if ($lasttime - $firsttime > 3 * 30 * 24 * 3600) { $lasttime = $time; print CTL ")\n"; } else { - ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($firsttime); + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($firsttime); $sec = $min = $hour = 0; - $time = $firsttime = timelocal($sec,$min,$hour,$mday,$mon,$year); + my $time = $firsttime = timelocal($sec,$min,$hour,$mday,$mon,$year); print CTL "set xtics rotate ("; - $comma = 0; + my $comma = 0; for (;;) { ($sec,$min,$hour,$mday,$mon,$year) = localtime($time); if ($comma) { @@ -149,7 +155,7 @@ if ($lasttime - $firsttime > 3 * 30 * 24 * 3600) { $time += 24 * 3600; ($sec,$min,$hour,$mday,$mon,$year) = localtime($time); - $toff = $hour * 3600 + $min * 60 * $sec; + my $toff = $hour * 3600 + $min * 60 * $sec; if ($toff != 0) { if ($toff > 12*3600) { $toff = 24 * 3600 - $toff; @@ -169,28 +175,20 @@ if ($lasttime - $firsttime > 3 * 30 * 24 * 3600) { # what to plot -print CTL "plot "; -$comma = 0; -$col = 2; +print CTL qq{plot "quotastat.data" using 1:2 title "used", "quotastat.data" using 1:3 title "soft", "quotastat.data" using 1:4 title "hard"\n}; -for $i (@top) { - if ($comma) { - print CTL ", "; - } else { - $comma = 1; - } - print CTL "'quotastat.data' using 1:", $col++, " title '$i'"; -} - -print CTL "\n"; close (CTL); -my $rc = system("gnuplot", "quotastat.ctl"); +my $rc = system("gnuplot", "quotacheck.ctl"); print "system returned $rc\n"; + +my $fs = $opts{fs}; +$fs =~ s|/|_|g; + system("gs -sDEVICE=ppmraw -r150 -dBATCH -sOutputFile=- -q - < quotastat.ps |" . "pnmscale 0.5 |" . "pnmflip -cw |" . "pnmcrop |" . "ppmquant 256 |" . - "ppmtogif > quotastat.gif"); + "ppmtogif >/usr/local/www/wsr/intranet/quotas/$opts{user}$fs.gif");