#!/usr/local/bin/perl
#
# /usr/local/bin/sortu - sort and count users by login name
# - display the terminal info as well
# - only display folks with more than a certain
# - number of logins (4 by default)
#
# Author: Jim Wildman, 3X HealthCare Solutions Group
# Date: 12/23/1999
# Revised: 2/10/2000 - Added comments, etc
#
# This code is released under the GNU Software License. See
# http://www.gnu.org for details
use Getopt::Std;
getopts('hsl:') || die "Usage: sortu [-h] | [-s] [-l n]\n'n' defaults to 5\n";
# the 's' option is to generate only the summary information
if($opt_h){
printf("Usage: sortu [-h] | [-s] [-l n] \n");
printf(" Sort and count logins by userid\n");
printf(" -h display this help message\n");
printf(" -s display summary counts only\n");
printf(" -l n set the cutoff level for display of logins\n");
printf(" (defaults to 5 or more)\n\n");
exit;
}
# the 'l' option allows us to set the threshold level for display and
# summarization
($opt_l > 0) ? ($num_logins = $opt_l) : ($num_logins = 5) ;
# slurp up the passwd file to get user names.
# sure would be nice to have complete info in here!!
# We could do this with the getpw* functions, but I already have this
# done.
@pwlist = `cat /etc/passwd` ;
foreach $item (@pwlist) {
chomp $item ;
($logname,$f1,$f2,$f3,$username) = split(/\:/,$item) ;
# all we are after is the login id and real user name
$uname{$logname} = $username ;
}
# Get our list of users
# This is where the big delay in the program is. 'who -u' takes a
# couple of seconds
# The output looks like...
# brcmwb1 pty/ttyb9 Feb 10 06:59 0:52 22217 brcdtc21
# brckdv1 pty/ttybc Feb 10 06:27 0:03 14495 b0gw6238
# brcshp2 pty/ttybd Feb 10 08:13 0:15 6909 brcdtc13
#
@users = `who -u`;
# For each user analyze the lines.
foreach $item (@users) {
chomp $item;
# split the who output. All we want is the first field
($user) = split(/\s+/,$item) ;
# count the instances of each user
$total{$user}++ ;
# count the total number of logins so far
$tot_logins++ ;
# store the lines for output
# we strip off the login name so it doesn't get repeated
if ($total{$user} == 1) {
$myterm{$user} = sprintf("\t%s\n", substr($item, 11)) ;
}
else {
# this builds up a list with embedded newlines and tabs
$myterm{$user} = sprintf("%s\t%s\n", $myterm{$user},
substr($item, 11)) ;
}
}
# This uses the defined subroutine to sort by the count
foreach $i (sort by_count (keys %total)) {
# total users
$tot_users++;
# This is limited by the value given with the -l option
if($total{$i} >= $num_logins) {
# If the summary flag is set, don't print all the details
# But we still have to do this to roll up the subtotals right
if($opt_s == 0) {
printf("%d %s %s\n%s", $total{$i}, $i, $uname{$i},
$myterm{$i});
}
$totgethannumlogins++ ;
}
}
# This is the 'summary' block
printf("\t %d total logins\n",$tot_logins) ;
printf("\t %d distinct users with %s having %s or more logins\n",
$tot_users, $totgethannumlogins, $num_logins) ;
# Define our own sort routine to sort by the second element (the count)
sub by_count {
return $total{$a} <=> $total{$b} ;
}