Listing 1: quota.pl
1 #!/usr/local/bin/perl
2
3 $AdminDir = "/u/arafel/adm/etc";
4 $WarnAt = 0.90;
5
6 # Read current quota map.
7
8 open(INFILE, "$AdminDir/quotas")
9 || die "Can't open $AdminDir/quotas" ;
10
11 open(LOGFILE, " | tee -a $AdminDir/quota.log
12 |/usr/ucb/Mail -s \"Quota Action report \" root")
13 || die "Can't open $AdminDir/quota.log";
14
15 print(LOGFILE "\nQuota run at ",`date`);
16
17 while (<INFILE>) {
18 ($user,$hisquota,$hishistory)=split(/\s+/);
19 $history{$user}=$hishistory;
20 $quota{$user}=$hisquota;
21 }
22 close(INFILE);
23
24 #generate full userlist.
25
26 open(INFILE,"ypcat passwd |");
27 while (<INFILE>) {
28 ($ypuser,$yppasswd,$uid,$gid,$Full,$Home)=split(/:/);
29 if ($gid <= 100) {next;} # skip system accounts
30 push(@ypuserlist,$ypuser);
31 $FullName{$ypuser} = $Full;
32 $HomeDir{$ypuser} = $Home;
33 if ( $yppasswd !~ /^\*/ ) {
34 $passwd{$ypuser} = "enabled";
35 }
36 else {
37 $passwd{$ypuser} = "disabled";
38 }
39 }
40
41 #Process each user;
42
43 foreach $u ( @ypuserlist ){
44 $hisquota = $quota{$u};
45 $hishistory = $history{$u};
46 if ($passwd{$u} eq "disabled") {
47 next;
48 }
49
50 # get user's diskusage.
51 ($diskusage) = split(/\s+/,`du -s ~$HomeDir{$u}`);
52
53 # Is the user quotad?
54 if ($hisquota == 0){
55 print LOGFILE "NOTQ: $u\n";
56 next;
57 }
58
59 # He's over quota.
60 if ($hisquota < $diskusage) {
61 $hishistory = "O".$hishistory; #O is for Over
62 chop $hishistory;
63 $history{$u} = $hishistory;
64 printf LOGFILE "OVER: %-8s %s U=%-8s Q=%-8s\n",
65 $u,$hishistory, $diskusage,$hisquota;
66 # Decide which message is mailed to him.
67 $NumOver = (split(/O/,$hishistory."X") - 1); #Fence post
68 if ($NumOver == 1 ) {&FirstOver;}
69 elsif($NumOver < 6) {&MoreOver;}
70 elsif($NumOver = 6) {&LastOver;}
71 elsif($NumOver >= 7) {
72 &Disable;
73 printf LOGFILE "DSLB: %-8s %s U=%-8s Q=%-8s\n",
74 $u,$hishistory, $diskusage,$hisquota;
75 } #end elsif
76 } #endif
77
78 # He's getting close
79 elsif (($WarnAt *$hisquota) < $diskusage){
80 $percentquota = sprintf("%3d",(100.0*$diskusage/$hisquota));
81 $quotaleft = $hisquota - $diskusage;
82 $hishistory = "W".$hishistory;
83 chop $hishistory;
84 $history{$u}= $hishistory;
85 printf LOGFILE "Warn: %-8s %s U=%-8s Q=%-8s\n",
86 $u,$hishistory, $diskusage,$hisquota;
87 &WarnUser;
88 }
89
90 # He's ok.
91 elsif (($WarnAt *$hisquota) >= $diskusage){
92 $hishistory = "-".$hishistory;
93 chop $hishistory;
94 $history{$u}= $hishistory;
95 }
96 }
97
98 # We're done, so now finish up the loose ends
99
100 close(LOGFILE);
101
102 #Write out the new user history.
103 open(OUT,"|sort +1n >$AdminDir/quotas");
104 foreach $u ( @ypuserlist){
105 printf(OUT "%-10s%8d %s\n",
106 $u,$quota{$u},$history{$u});
107 }
108 close(OUT);
109
110 sub WarnUser{
111 open(MAILOUT, "|/usr/ucb/Mail -s \"Nearing Quota Limit \" $u");
112 print MAILOUT <<EOF;
113
114 You are currently using $percentquota% of your disk quota.
115 Currently you have only $quotaleft kilobytes left.
116 You might look into various space space saving tricks.
117 I'd be glad to show you some.
118
119 Sherwood
120 EOF
121 close MAILOUT;
122 }
123
124 sub FirstOver{
125 open(MAILOUT, "|/usr/ucb/Mail -s \"OVER QUOTA!!\" $u");
126 print MAILOUT <<EOF;
127 You are OVER your disk quota.
128 Please take the time to clean out your files.
129 You might also compress or zipdir files that you don't
130 use often, move files to tape, or use the scratch disk.
131 EOF
132 close MAILOUT;
133 }
134
135 sub MoreOver{
136 open(MAILOUT, "|/usr/ucb/Mail -s \"OVER QUOTA!!\" $u");
137 print MAILOUT <<EOF;
138 Ahem...
139 You were sent a note regarding being over quota.
140 You are still over quota. Please reduce your file usage
141 until you are using less than $hisquota kilobytes. We have
142 various tools to help you do this. Ask me for help if you need
143 assistance.
144
145 EOF
146 close MAILOUT;
147 }
148
149 sub LastOver{
150 open(MAILOUT, "|/usr/ucb/Mail -s \"OVER QUOTA!!\" $u");
151 print MAILOUT <<EOF;
152
153 Please be aware that you remain over quota.
154 If you are not under quota ($hisquota kilobytes) by
155 next time this program runs, your account will be disabled.
156 It will then be deleted after the next archival backup.
157 EOF
158 close MAILOUT;
159 }
160
161
162 sub Disable{
163 system("sed -e \"/$u/ s-\:-\:\*-\"
164 < /etc/passwd.yp > /etc/passwd.new");
165 system("mv /etc/passwd.new /etc/passwd.yp; cd /etc/yp; make");
166 }
|