0: #!/usr/bin/perl -w
1:
2: require 5;
3: use strict;
4: use Getopt::Std;
5: use File::Find;
6: use vars qw(%opts @mailboxen $file $access $mod $user $unread $i $j @passwd $name @oldusers $mailbytes $mailsize $homebytes $homesize @sorted @units @multipliers $limit $outputstring $length);
7:
8: getopts('ho:al:', \%opts);
9:
10: sub usage(){
11: print <<EOF;
12: Usage: $0 [options]
13: Example: $0 -om -l m=10m
14: Synopsis: Checks the age and size of all mailboxen on the system, to help you isolate dead accounts, or disk hogs.
15:
16: -h : Displays this help screen.
17: -o : Order of results[1].
18: -a : List all users, not just those with unread mail.
19: -l : Limit. Format is 'F=LLU', comma seperated, where 'F' is the field[2], 'L' the limit, and 'U' the unit[3].
20: Example: $0 -l u=1w,m=5m
21: (This lists all users with unread mail who haven't checked there mailbox in over a week, and which is over 5 megabytes in size)
22:
23: [1]: Can be ordered by 'a' (alphabetic), 'u' (time mailbox unread), 'm' (mailbox size), 'h' (home dir size) or 't' (total disk usage).
24: [2]: Field can be any listed above, except 'a'.
25: [3]: Unit is the first letter of whichever unit you wish to use.
26: i.e. for times: 's' (second), 'm' (minute), 'h' (hour), 'd' (day), 'w' (week) or 'y' (year).
27: or for memory: 'b' (bytes), 'k' (Kb), 'm' (Mb) or 'g' (Gb).
28:
29: EOF
30: exit;
31: }
32: <READMORE>
33: if ($opts{'h'}){
34: usage();
35: }
36:
37: sub subdivide ($$\@\@$) {
38:
39: my ($ordinal, $unit, $result);
40: my $time = shift;
41: my $depth = shift;
42: my $mult_ref = shift;
43: my @multipliers = @$mult_ref;
44: my $unit_ref = shift;
45: my @Units = @$unit_ref;
46: my $pluralise = shift;
47:
48: my $k;
49: my $l = 1;
50: for ($k=0; $k<@units; $k++) {
51:
52: if ($k == @multipliers || $time < $l * $multipliers[$k]) {
53: $ordinal = int ( $time / $l );
54: $unit = $units[$k];
55: $time -= $ordinal * $l;
56: last;
57: }
58:
59: $l *= $multipliers[$k];
60: }
61:
62: if ($pluralise && ($ordinal > 1)) {
63: $unit .= 's';
64: }
65:
66: $result = "$ordinal $unit";
67:
68: if ($depth && $time) {
69: $result .= ", " . subdivide($time, --$depth, \@multipliers, \@units, $pluralise);
70: }
71:
72: return $result;
73: }
74:
75: sub multiplyup ($\@\@) {
76:
77: my $time = shift;
78: my $result = substr ($time, 0, -1);
79: my $unit = substr ($time, -1, 1);
80: my $mult_ref = shift;
81: my @multipliers = @$mult_ref;
82: my $unit_ref = shift;
83: my @Units = @$unit_ref;
84:
85: my $k;
86: for ($k=0; $k<@units; $k++) {
87:
88: if ($unit eq $units[$k]) {
89: last;
90: }
91:
92: $result *= $multipliers[$k];
93: }
94:
95: return $result;
96: }
97:
98: open PASSWD, "/etc/passwd" or die "Could now open /etc/passwd, wtf?";
99: @passwd = <PASSWD>;
100:
101: opendir MAIL, "/var/spool/mail" or die "Could not open /var/spool/mail, wtf?";
102: @mailboxen = grep { ! /^\..*$/ } readdir MAIL;
103: closedir MAIL;
104:
105: my $longestname = 0;
106:
107: for ($i=0; $i<@mailboxen; $i++) {
108:
109: $user = $mailboxen[$i];
110: $file = "/var/spool/mail/$user";
111:
112: $access = (-A $file);
113: $mod = (-M $file);
114:
115: if ($access > $mod || $opts{'a'}) {
116:
117: @multipliers = (60, 60, 24, 7, 365/7);
118: @units = ('second', 'minute', 'hour', 'day', 'week', 'year');
119: $unread = $access > $mod ? subdivide(int($access * 86400), 1, @multipliers, @units, 1) : "no time";
120:
121: for ($j=0; $j<@passwd; $j++) {
122: if ($passwd[$j] =~ /^$user:[^:]+:[^:]+:[^:]+:([^,:]+).+$/) {
123: $name = $1;
124: $name =~ s/\\//;
125: $name =~ s/(\b)(\w+)/$1\u\L$2/g;
126: last;
127: }
128: }
129:
130: if (length($name) > $longestname) { $longestname = length($name) }
131:
132: @multipliers = (1024, 1024, 1024);
133: @units = ('bytes', 'Kb', 'Mb', 'Gb');
134: $mailbytes = -s $file;
135: $mailsize = subdivide($mailbytes, 0, @multipliers, @units, 0);
136:
137: $homebytes = 0;
138: find sub { $homebytes += -s }, "/home/$user";
139: $homesize = subdivide($homebytes, 0, @multipliers, @units, 0);
140:
141: push @oldusers, { user => "$user",
142: unread => "$unread",
143: name => "$name",
144: access => $access > $mod ? "$access" : 0,
145: mailbytes => "$mailbytes",
146: mailsize => "$mailsize",
147: homebytes => "$homebytes",
148: homesize => "$homesize" };
149:
150: }
151: }
152:
153: if ( $opts{'l'} ) {
154: my %limits = split /[,=]/, $opts{'l'};
155:
156: if ( $limits{'u'} ) {
157: @multipliers = (60, 60, 24, 7, 365/7);
158: @units = ('s', 'm', 'h', 'd', 'w', 'y');
159: $limit = multiplyup($limits{'u'}, @multipliers, @units) / 86400;
160: @oldusers = grep { $_->{access} > $limit } @oldusers;
161: }
162:
163: if ( $limits{'m'} ) {
164: @multipliers = (1024, 1024, 1024);
165: @units = ('b', 'k', 'm', 'g');
166: $limit = multiplyup($limits{'m'}, @multipliers, @units);
167: @oldusers = grep { $_->{mailbytes} > $limit } @oldusers;
168: }
169:
170: if ( $limits{'h'} ) {
171: @multipliers = (1024, 1024, 1024);
172: @units = ('b', 'k', 'm', 'g');
173: $limit = multiplyup($limits{'h'}, @multipliers, @units);
174: @oldusers = grep { $_->{homebytes} > $limit } @oldusers;
175: }
176:
177: if ( $limits{'t'} ) {
178: @multipliers = (1024, 1024, 1024);
179: @units = ('b', 'k', 'm', 'g');
180: $limit = multiplyup($limits{'t'}, @multipliers, @units);
181: @oldusers = grep { $_->{mailbytes} + $_->{homebytes} > $limit } @oldusers;
182: }
183:
184: }
185:
186:
187: if ( !defined( $opts{'o'} ) || $opts{'o'} eq 'u') {
188: @sorted = sort { $b->{access} <=> $a->{access} } @oldusers;
189: }
190: elsif ($opts{'o'} eq 'm') {
191: @sorted = sort { $b->{mailbytes} <=> $a->{mailbytes} } @oldusers;
192: }
193: elsif ($opts{'o'} eq 'h') {
194: @sorted = sort { $b->{homebytes} <=> $a->{homebytes} } @oldusers;
195: }
196: elsif ($opts{'o'} eq 't') {
197: @sorted = sort { $b->{mailbytes} + $b->{homebytes} <=> $a->{mailbytes} + $a->{homebytes} } @oldusers;
198: }
199: elsif ($opts{'o'} eq 'a') {
200: @sorted = sort { $a->{name} cmp $b->{name} } @oldusers;
201: }
202: else {
203: warn "Bad ordering option, returning results unordered.";
204: }
205:
206: print "Name" . ' ' x ($longestname+1) ."Unread For Mailbox Size Home Dir Size\n";
207:
208: for ($i=0; $i<@sorted; $i++) {
209: $outputstring = "$sorted[$i]{name} " . '-' x $longestname;
210: $outputstring = substr($outputstring, 0, $longestname + 4);
211:
212: $outputstring .= " $sorted[$i]{unread} ----------------------";
213: $outputstring = substr($outputstring, 0, $longestname + 40 - length($sorted[$i]{mailsize}));
214:
215: $outputstring .= " $sorted[$i]{mailsize} ------------";
216: $outputstring = substr($outputstring, 0, $longestname + 56 - length($sorted[$i]{homesize}));
217:
218: $outputstring .= " $sorted[$i]{homesize}\n";
219:
220: print $outputstring;
221: }
222:
223: exit; In reply to mailcheck.pl by kilinrax
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |