#!/bin/sh # # OverQuota Early Warning email script # Emails the address detailed below (or to STDOUT if no email address entered) # all users & sites that are close to their quota limit (triggered by either # 'warning_percent' or 'warning_kb') # This script can be run either manually or from crond (MUST be run from 'root') # Script has been written to work specifically on Cobalt/Sun RaQ3/4's only # although this may with modification work elsewhere (mail me it if you succeed) # # Authored by Kul - http://akakul.co.uk/ # Version 1.1.0 23rd November 2002 # Script Home - http://scripts.akakul.co.uk/early_warning_overquota # # the email address to receive this report (can be a LOCAL username as well!) mail_addy="" # enter EITHER 'warning_percent' (1-100) **OR** 'warning_kb' (1+) # 'warning_percent' takes precidence over 'warning_kb' # note: 'warning_kb' is not decimal kb. (ie 10240 = 10mb, dont mistakenly use 10000) #warning_percent=75 warning_percent=0 warning_kb=10240 # skip user 'users' (internals for gui sytem) either 'yes' or '' are valid skip_users="yes" # end of alterations needed # disallow other users running this script whoami=$(/usr/bin/id -un) if [ "$whoami" != "root" ]; then /bin/echo "Only 'root' can run this script: $0" exit 1 fi # force these variables to become numeric warning_percent=$(($warning_percent + 0)) warning_kb=$(($warning_kb + 0)) # set variables site_list=/tmp/$0.sitelist report_file=/tmp/$0.report # delete any previous run temp files /bin/rm -f $site_list $report_file >/dev/null 2>&1 # get a list of the sites (raq3/4) /bin/ls -lA /home/sites | /bin/grep "\->" | /bin/awk {'print $9":"$11'} | \ /bin/sed s~/.*/~~ > $site_list # loop through all entries in 'repquota' for hard in $(/usr/sbin/repquota -avug | /bin/awk {'print $1":"$3":"$5":"$2":"$4'}); do user_name=$(/bin/echo $hard | /bin/awk -F':' {'print $1'}) unwanted=$(/bin/echo $user_name | /bin/sed 's~^User$~~;s~^Block$~~') if [ ! -z "$skip_users" ]; then unwanted=$(/bin/echo $unwanted | /bin/sed 's~^users$~~') fi if [ -z "$unwanted" ];then # layout/formatting bits to be skipped continue fi # real users/groups (groups = sites on raq3/4's) user_name_is_long=0 unwanted=$(/bin/echo $user_name | /bin/sed 's~^.*--$~~') if [ ! -z "$unwanted" ]; then quota_used=$(/bin/echo $hard | /bin/awk -F':' {'print $2'}) quota_allowed=$(/bin/echo $hard | /bin/awk -F':' {'print $3'}) else # this is a hack to get around LONG usernames quota_used=$(/bin/echo $hard | /bin/awk -F':' {'print $4'}) quota_allowed=$(/bin/echo $hard | /bin/awk -F':' {'print $5'}) user_name=$(/bin/echo $user_name | /bin/sed s~--$~~) user_name_is_long=1 fi quota_used=$(($quota_used + 0)) quota_allowed=$(($quota_allowed + 0)) if [ $quota_allowed -eq 0 ]; then # system account, with a zero max quota (unlimited) continue fi # only interesting users/groups left now quota_diff=$(($quota_allowed - $quota_used)) quota_diff=$(($quota_diff + 0)) # find out if its a group or not (groups are either 'home' or 'siteX' (X = number) site_test=$(/bin/echo $user_name | /bin/sed 's~^site[0-9]*$~~;s~^home$~~') if [ -z "$site_test" ]; then # is a group if [ $user_name_is_long -eq 0 ]; then site=$(/bin/grep ":$user_name$" $site_list | /bin/sed s~:.*~~) else site=$(/bin/grep ":$user_name--$" $site_list | /bin/sed s~:.*~~) fi user_name="" else # is a user if [ $user_name_is_long -eq 0 ]; then # get site number for the user (short user) this_site=$(/bin/grep "^$user_name:" /etc/passwd | \ /bin/sed 's~.*:/home/sites/~~;s~/users/.*$~~') else # get site number for the user (LONG user) = guesswork # we shall have to take potluck here, and hope there is # only ONE LONG username that matches (bug alert) - so # use the first entry we find (ignores subsequent) this_site=$(/bin/grep "^$user_name.*:" /etc/passwd | \ /bin/sed 's~.*:/home/sites/~~;s~/users/.*$~~' | \ /usr/bin/head -1) fi # find the site NAME (ie www.akakul.co.uk) site=$(/bin/grep ":$this_site$" $site_list | /bin/sed s~:.*~~) fi alert_mess="" # see if the user/group is close to quota limit if [ $warning_percent -gt 0 ]; then # use 'percentages' to see if close to quota limit result=$(/bin/echo $quota_used $quota_allowed | /bin/awk '{printf "%i", ($1 / $2 * 100) + 0.5}') result=$(($result + 0)) warning_percent=$(($warning_percent + 0)) if [ $result -gt $warning_percent ]; then # user/group is close to limit (percenatge math) alert_mess="$result% used" fi else # use 'kb' to see if close to quota limit if [ $quota_diff -le $warning_kb ]; then # user/group is close to limit (kb math) alert_mess="within $warning_kb kb" fi fi if [ ! -z "$alert_mess" ]; then # user/group is close to limit, display a message if [ -z "$user_name" ]; then /bin/echo -n "$site" >> $report_file else if [ $user_name_is_long -ne 0 ]; then # is a LONG user, and cant be 100% trusted to be correctly listed # flag this with three * in the username (can't accuratly discover # the REAL LONG name) user_name="$user_name***" fi if [ ! -z "$site" ]; then /bin/echo -n "$site -> '$user_name'" >> $report_file else /bin/echo -n "User:$user_name" >> $report_file fi fi # display the remaining part of the line /bin/echo " $alert_mess - used $quota_used of $quota_allowed kb" >> $report_file fi done # if the report is NOT empty generate the email/STDOUT if [ -s "$report_file" ]; then if [ ! -z "$mail_addy" ]; then # mail the report /bin/sort $report_file | /bin/mail -s \ "Early Warning OverQuota Report for $(/bin/date)" $mail_addy else # display the report (STDOUT) /bin/sort $report_file fi fi # keep britain tidy /bin/rm -f $site_list $report_file >/dev/null 2>&1 exit # end of script