Meidokon Wiki
  • Comments
  • Immutable Page
  • Menu
    • Navigation
    • RecentChanges
    • FindPage
    • Local Site Map
    • Help
    • HelpContents
    • HelpOnMoinWikiSyntax
    • Display
    • Attachments
    • Info
    • Raw Text
    • Print View
    • Edit
    • Load
    • Save
  • Login

Useful(?) links

  • furinkan's stuff

  • Postfix snippets


  • SystemInfo

  • This sidebar

Navigation

  • FrontPage
  • RecentChanges
  • FindPage
  • HelpContents

Upload page content

You can upload content for the page named below. If you change the page name, you can also upload content for another page. If the page name is empty, we derive the page name from the file name.

File to load page content from
Page name
Comment

MeidokonWiki:
  • Useful_shell_scripts

Various stuff used personally or at work

These might be out of date, no warranty, etc.

Contents

  1. Various stuff used personally or at work
    1. adduser.local
    2. check-aacraid.py
    3. check-for-orphans
    4. check-for-updates
    5. check-iptables-firewall
    6. check_kernel
    7. db-export-mysql
    8. db-export-pgsql
    9. inflate.sh
    10. new_all.sh
    11. new_db.sh
    12. new_user.sh
    13. new_vhost.sh
    14. snmp-diskio-collector
    15. vhost_template
    16. webalize

adduser.local

Goes in /usr/local/sbin/

echo "username is $1"
echo "uid is $2"
echo "gid is $3"
echo "homedir is $4"

# Give new users an initial quota of 1gig
quotatool -v -u $1 -b -l '1024 MB' /

check-aacraid.py

   1 #!/usr/bin/python
   2 #
   3 # THIS FILE IS DISTRIBUTED BY CFENGINE! LOCAL CHANGES WILL BE DESTROYED!
   4 #
   5 # check-aacraid.py
   6 #
   7 # Grabs the output from "/usr/local/sbin/arcconf GETCONFIG 1 AL" then
   8 # determines the health of various status indicators from the card
   9 # and drives.
  10 #
  11 # v0.1 - only checks card information so far, not drives yet
  12 
  13 import sys, os, re, string
  14 
  15 c_status_re = re.compile('^\s*Controller Status\s*:\s*(.*)$')
  16 c_defunct_re = re.compile('^\s*Defunct disk drive count\s:\s*([0-9]+).*$')
  17 c_degraded_re = re.compile('^\s*Logical devices/Failed/Degraded\s*:\s*([0-9]+)/([0-9]+)/([0-9]+).*$')
  18 b_status_re = re.compile('^\s*Status\s*:\s*(.*)$')
  19 b_temp_re = re.compile('^\s*Over temperature\s*:\s*(.*)$')
  20 b_capacity_re = re.compile('\s*Capacity remaining\s*:\s*([0-9]+)\s*percent.*$')
  21 b_time_re = re.compile('\s*Time remaining \(at current draw\)\s*:\s*([0-9]+) days, ([0-9]+) hours, ([0-9]+) minutes.*$')
  22 
  23 cstatus = cdefunct = cdegraded = bstatus = btemp = bcapacity = btime = ""
  24 check_status = 0
  25 result = ""
  26 
  27 for line in os.popen4("/usr/bin/sudo /usr/local/sbin/arcconf GETCONFIG 1 AD")[1].readlines():
  28         # Match the regexs
  29         cstatus = c_status_re.match(line)
  30         if cstatus:
  31                 if cstatus.group(1) != "Optimal":
  32                         check_status = 2
  33                 result += "Controller " + cstatus.group(1) + ","
  34 
  35         cdefunct = c_defunct_re.match(line)
  36         if cdefunct:
  37                 if int(cdefunct.group(1)) > 0:
  38                         check_status = 2
  39                         result += "Defunct drives " + cdefunct_group(1) + ","
  40 
  41         cdegraded = c_degraded_re.match(line)
  42         if cdegraded:
  43                 if int(cdegraded.group(2)) > 0:
  44                         check_status = 2
  45                         result += "Failed drives " + cdegraded.group(2) + ","
  46                 if int(cdegraded.group(3)) > 0:
  47                         check_status = 2
  48                         result += "Degraded drives " + cdegraded.group(3) + ","
  49 
  50         bstatus = b_status_re.match(line)
  51         if bstatus:
  52                 if bstatus.group(1) == "Charging":
  53                         if check_status < 2:
  54                                 check_status = 1
  55                 elif bstatus.group(1) != "Optimal":
  56                         check_status = 2
  57                 result += "Battery Status " + bstatus.group(1) + ","
  58         
  59         btemp = b_temp_re.match(line)
  60         if btemp:
  61                 if btemp.group(1) != "No":
  62                         check_status = 2
  63                         result += "Battery Overtemp " + btemp.group(1) + ","
  64 
  65         bcapacity = b_capacity_re.match(line)
  66         if bcapacity:
  67                 result += "Battery Capacity " + bcapacity.group(1) + "%,"
  68                 if bcapacity.group(1) < 50:
  69                         if check_status < 2:
  70                                 check_status = 1
  71                 if bcapacity.group(1) < 25:
  72                         check_status = 2
  73 
  74         btime = b_time_re.match(line)
  75         if btime:
  76                 timemins = int(btime.group(1)) * 1440 + int(btime.group(2)) * 60 + int(btime.group(3))
  77                 if timemins < 1440:
  78                         if check_status < 2:
  79                                 check_status = 1
  80                 if timemins < 720:
  81                         check_status = 2
  82                 result += "Battery Time "
  83                 if timemins < 60:
  84                         result += str(timemins) + "mins,"
  85                 else:
  86                         result += str(timemins/60) + "hours,"
  87 
  88 if result == "":
  89         result = "No output from arcconf!"
  90         check_status = 3
  91 
  92 print result
  93 sys.exit(check_status)

check-for-orphans

#
# THIS FILE IS ROLLED OUT BY CFENGINE! ALL LOCAL MODIFICATIONS WILL BE DESTROYED!
#
# use favourite package tool and see if there are orphaned packages

tmpfile=`mktemp ${TMPDIR:-/tmp}/check-for-updates.XXXXXX` || exit 2

mailguy () {
    ( cat <<EOF
From: root@$HOSTNAME
To: X@example.com
Subject: Orphans Check $HOSTNAME

EOF
    cat $tmpfile) #| /usr/sbin/sendmail -t -i
}

if test -x /usr/bin/yum ; then
        # Yum system
        # Due to how they are installed, kernel and gpg-pubkey packages are always listed
        yum list extras | egrep -v "(kernel|gpg-pubkey)" > $tmpfile

        # We only care about packages listed below the Extra Packages line
        LINE=`cat $tmpfile | grep -n "Extra Packages" | cut -f1 -d:`
        if [ "x$LINE" != "x" ]
        then
                cat $tmpfile | sed -i -e "1,${LINE}d" $tmpfile
                if [ `cat $tmpfile | wc -l` -gt 0 ]
                then
                        mailguy
                fi
        fi
elif test -x /usr/bin/apt-cache ; then
        # APT system.
        # Use set theory to determine orphans. Unfortunately this doesn't take into account package versions yet.
        ((apt-cache pkgnames; COLUMNS=200 dpkg -l | sed -e '1,5d' | awk '{print $2}') | sort | uniq -d; COLUMNS=200 dpkg -l | sed -e '1,5d' | awk '{print $2}') | sort | uniq -u > $tmpfile
        if [ `cat $tmpfile | wc -l` -gt 0 ]
        then
                mailguy
        fi
else
    echo "Can't work out the OS on $HOSTNAME"
fi

rm -f $tmpfile

check-for-updates

# use favourite package tool and see if there are updates available for a machine.

tmpfile=`mktemp ${TMPDIR:-/tmp}/check-for-updates.XXXXXX` || exit 2

#export http_proxy=http://foo.proxy.com:3128/

mailguy () {
    ( cat <<EOF
From: root@$HOSTNAME
To: X@example.com
Subject: Update Check $HOSTNAME

EOF
    cat $tmpfile) #| /usr/sbin/sendmail -t -i
}

if test -f /etc/fedora-release ; then
    # Fedora Core
    yum check-update > $tmpfile
    r=$?
    if test "$r" -eq 100 ; then
        mailguy
    fi
elif test -f /etc/redhat-release ; then
    # RHEL/CentOS
    if egrep -q "(Red Hat Enterprise Linux Server release 5|ES release [234]|CentOS)" /etc/redhat-release ; then
        # Yum-based RHEL/CentOS
        yum check-update > $tmpfile
        r=$?
        if test "$r" -eq 100 ; then
            mailguy
        fi
    else
        echo "Can't work out RHEL/CentOS OS on this machine $HOSTNAME, or unsupported release."
    fi
elif test -f /etc/debian_version ; then
    # Debian
    apt-get update > $tmpfile
    apt-get -s upgrade >> $tmpfile
    if grep -q "The following packages will be upgraded" $tmpfile ; then
        mailguy
    fi
else
    echo "Can't work out the OS on $HOSTNAME"
fi

rm -f $tmpfile

check-iptables-firewall

# at the moment, the status of the firewall is unknown
output="FIREWALL UNKNOWN"
r=3

if [ -f /etc/redhat-release ]; then
    IPTABLESSAVE="/etc/sysconfig/iptables"
elif [ -f /etc/debian_version ]; then
    IPTABLESSAVE="/etc/network/iptables"
fi

if /usr/bin/sudo /sbin/iptables -L -n | grep ^Chain | grep -q "policy ACCEPT"; then
    # there's chains with a default policy of ACCEPT
    # which suggests that there isn't a firewall running
    output="FIREWALL CRITICAL: evidence of no firewall running"
    r=2
elif [ -f $IPTABLESSAVE ]; then
    # there's a saved iptables ruleset
    if [ -f /etc/pyfi/ruleset.py ]; then
        files=`find /etc/pyfi -type f -name '*.py'`
        flag=0
        d=`/usr/bin/sudo /bin/date +%s -r $IPTABLESSAVE`
        ood=""
        for f in $files; do
            fdate=`date +%s -r $f`
            if [ "$d" -lt "$fdate" ]; then
                ood="$ood $f"
                flag=1
            fi
        done
        if [ "$flag" -eq 1 ]; then
            output="FIREWALL WARNING: running firewall is out of date wrt configuration: $ood"
            r=1
        else
            saved=`/usr/bin/sudo /usr/bin/head -n 1 $IPTABLESSAVE | sed 's/^.*on //'`
            output="FIREWALL OK: last saved at $saved"
            r=0
        fi
    else
        # no filtergen...
        output="FIREWALL UNKNOWN: no barrier jacket configuration found"
    fi
fi

echo $output
exit $r

check_kernel

This is kinda arse, and not robust against minor output format changes.

kver=`uname -a | awk '{print $3}'`

if test -f /etc/fedora-release || test -f /etc/redhat-release ; then

case $kver in
        *smp)
                kernel="kernel-smp"
                ;;
        *xen)
                kernel="kernel-xen"
                ;;
        *PAE)
                kernel="kernel-PAE"
                ;;
        *)
                kernel="kernel"
                ;;
esac

kver=`echo $kver | sed 's/smp$//;s/xen$//;s/PAE$//'`

buildtime=0
for item in `rpm -q $kernel --qf '%{VERSION}-%{RELEASE}#%{BUILDTIME}\n'`
do
        bt=`echo $item | cut -d# -f2`
        if [ "$buildtime" -lt "$bt" ]
        then
                buildtime=$bt
                lver=`echo $item | cut -d# -f1`
        fi
done

krunning="$kernel-$kver"
lver="$kernel-$lver"

elif test -f /etc/debian_version ; then
    # FIXME: still need to test sub-version of kernels on debian/ubuntu
    kernel="kernel"

    lver=`(COLUMNS=200 dpkg -l 'kernel-image*' 2>/dev/null|| COLUMNS=200 dpkg -l 'linux-image*' 2>/dev/null) | grep ^ii | awk '{print $2}' | grep '[0-9]' | tail -n 1`
    #echo $lver

    if dpkg -l 'kernel-image*' 2>/dev/null >/dev/null
    then
        krunning="kernel-image-$kver"
    else
        krunning="linux-image-$kver"
    fi

fi

if test "x$krunning" != "x$lver" ; then
        echo "KERNEL WARNING: running version $krunning doesn't match latest installed version $lver"
        r=1
else
        echo "KERNEL OK - $kernel-$kver"
        r=0
fi

exit $r

db-export-mysql

Compressed SQL dumps ftw.

#
# Backup the entire MySQL
#
#

MY_BACKUP=/var/lib/mysqlbackup

if [ ! -d $MY_BACKUP ]
then
        mkdir -m 0700 $MY_BACKUP
fi

if [ ! -d $MY_BACKUP ]
then
        echo "ERROR: database backup directory '$MY_BACKUP' does not exist." 1>&2
        exit 1
fi

# Compress data in a manner that will enable rsync
# to sync efficiently.
if gzip --help | grep -q -- --rsyncable
then
        # gzip reads this environment variable automatically
        export GZIP="--rsyncable"
fi

DATE=`date -I`
/usr/bin/mysqldump -q -c -A -Q | gzip -9 > $MY_BACKUP/$DATE.gz

if [ -f /etc/redhat-release ]
then
        /usr/sbin/tmpwatch --mtime 72 $MY_BACKUP
elif [ -f /etc/debian_version ]
then
        /usr/sbin/tmpreaper --mtime 72h $MY_BACKUP
fi


# Purge the binary log
if /usr/bin/mysqladmin variables | grep -q log_bin.*ON
then
        /usr/bin/mysql -e 'RESET MASTER;'
fi

db-export-pgsql

Compressed SQL dumps ftw.

#
# Backup the entire PostgreSQL cluster
#
# NB: password set in $PGUSER startup files

PG_BACKUP=/var/lib/postgresql/8.3/main/backups
PGUSER=postgres

case `whoami` in
root)
        if [ ! -d $PG_BACKUP ]
        then
                mkdir -m 0700 $PG_BACKUP
                chown $PGUSER $PG_BACKUP
        fi
        exec su - $PGUSER $0
        ;;
$PGUSER)
        ;;
*)
        echo "$0 must be run as root" 1>&2
        exit 1
        ;;
esac

if [ ! -d $PG_BACKUP ]
then
        echo "ERROR: database backup directory '$PG_BACKUP' does not exist." 1>&2
        exit 1
fi

# Compress data in a manner that will enable rsync
# to sync efficiently.
if gzip --help | grep -q -- --rsyncable
then
        # gzip reads this environment variable automatically
        export GZIP="--rsyncable"
fi

DATE=`date -I`
/usr/bin/pg_dumpall | gzip -9 > $PG_BACKUP/$DATE.gz

if [ -f /etc/redhat-release ]
then
        /usr/sbin/tmpwatch --mtime 72 $PG_BACKUP
elif [ -f /etc/debian_version ]
then
        /usr/sbin/tmpreaper --mtime 72h $PG_BACKUP
fi

# Run clustering script if it exists
if [ -x /usr/local/sbin/pg-cluster ]
then
        /usr/local/sbin/pg-cluster
fi

inflate.sh

# Barney Desmond <barney@anchor.net.au> 2008-08-07
# For simpler filesystem growth, performing an lvextend and resize2fs

usage()
{
        echo "Expected two arguments, LV name and no. of gb to increase by. Eg."
        echo "  $0 LVNAME NUMGIGS"
        exit 2
}


if [ $# -ne 2 ]
then
        usage
fi

LVNAME="$1"
MOREGIGS="$2"



HOSTNAME=`hostname --short`
FQDN=`hostname --fqdn`
echo -n "Looking for LVM mounts in /dev... "
if [ -d "/dev/${HOSTNAME}" ]
then
        echo "found /dev/${HOSTNAME}"
        LVDIR="/dev/${HOSTNAME}/"
elif [ -d "/dev/${FQDN}" ]
then
        echo "found /dev/${FQDN}"
        LVDIR="/dev/${FQDN}/"
else
        echo "can't find /dev/${HOSTNAME} or /dev/${FQDN}, bailing..."
        exit 1
fi


if [ ! -L "${LVDIR}${LVNAME}" ]
then
        echo "Can't find an LV at ${LVDIR}${LVNAME}, please check the name of the volume. Bailing..."
        exit 2
fi


# test if the no. of gigs is numeric, probably imperfect test...
if ! expr "${MOREGIGS}" + 0 > /dev/null 2>/dev/null
then
        echo "No. of gigs \"${MOREGIGS}\" was not numeric, bailing..."
        exit 2
fi


echo "Ready to go, will lvextend ${LVDIR}${LVNAME} by ${MOREGIGS}gb"
echo

echo "Starting lvextend..."
lvextend -L "+${MOREGIGS}G" "${LVDIR}${LVNAME}"
if [ $? -ne 0 ]
then
        echo "Error during lvextend, bailing..."
        exit 1
fi

echo "Starting resize2fs..."
resize2fs -p "${LVDIR}${LVNAME}"

echo "All done!"
df -h | grep "${LVNAME}"

new_all.sh

Make a user, mysql db, vhost.

# Creates a whole new account on the system, as calling all the scripts is kinda tiring already, checking if the domain is already on the system, etc.
# Takes the suggested username and domain, does all sanity checking, then calls the separate scripts.

# Barney Desmond, Anchor Systems
# 2008-06-23 - rev1 - initial hack-up

ACCOUNTS_LOGFILE=/root/newaccounts
DATABASES_LOGFILE=/root/newdatabases

usage()
{
        echo "Usage: $0 expects two arguments: system username, domain name"
}

if [ $# -ne 2 ]
then
        usage
        exit 1
fi

USERNAME=$1
CLEAN_USERNAME=`echo $1 | tr -cd a-zA-Z0-9`
DOMAIN=`echo $2 | tr 'A-Z' 'a-z' | sed -r 's,.*http://,,' | awk '{ print $1 }' | sed -r 's/^www\.//'`



## LOGGING CHECKS
# Must be able to touch the newaccounts output file
if ! /bin/touch "$ACCOUNTS_LOGFILE"
then
        echo "Could not touch ${ACCOUNTS_LOGFILE}, are you root?. Exiting..."
        exit 1
fi
# Must be able to touch the newdatabases output file
if ! /bin/touch "$DATABASES_LOGFILE"
then
        echo "Could not touch ${DATABASES_LOGFILE}, are you root?. Exiting..."
        exit 1
fi

## USERNAME CHECKS
# Sanity-check the username
if [ ${#USERNAME} -gt 16 ] # mysql doesn't like long usernames
then
        echo "New username must be no longer than 16 characters. Exiting..."
        exit 2
fi
if [ x$USERNAME != x$CLEAN_USERNAME ]
then
        echo "New username is not sane, must be alphanumeric. Exiting..."
        exit 2
fi
if [ x$USERNAME = "xroot" ] # root is not okay
then
        echo "Username of root is not acceptable. Exiting..."
        exit 2
fi

# Username must not already exist
if /usr/bin/id "$USERNAME" 2> /dev/null > /dev/null
then
        echo "Username already exists. Exiting..."
        exit 2
fi


## DATABASE CHECKS
# DB of same name must NOT already exist
if /usr/bin/mysql -D "$USERNAME" -e '\q' 2>/dev/null
then
        echo "Database $USERNAME already exists. Exiting..."
        exit 2
fi

# .my.cnf file for user must not already exist
if [ -f "/home/${USERNAME}/.my.cnf" ]
then
        echo "~/.my.cnf already exists, don't want to clobber it. Exiting..."
        exit 1
fi


## VHOST CHECKS
# vhost file must not already exist
if [ -f "/etc/httpd/conf/users/${USERNAME}.conf" ]
then
        echo "vhost ${USERNAME}.conf already exists. Exiting..."
        exit 1
fi

# domain must not already be configured
#free4lifeclub.com
if /bin/grep -q "[      ]$DOMAIN" /etc/httpd/conf/users/*.conf
then
        echo "The domain is already configured on the system. Exiting..."
        exit 2
fi


echo "GOOD TO GO"

/root/new_user.sh "${USERNAME}"
echo "1. Created new user"
/root/new_db.sh "${USERNAME}"
echo "2. Created new database"
/root/new_vhost.sh "${USERNAME}" "${DOMAIN}"
echo "3. Created new vhost"
/root/rowan_reply.sh "${USERNAME}"

new_db.sh

# Create a new MySQL db for a user, setting a random password and granting all privs
# New database will have name == system-username == db-username
# Sets up ~/.my.cnf for the user so they can use mysql shell immediately
# 
# Should be improved to handle adding secondary databases,
# appending a number (1,2,3,etc) as needed

# Barney Desmond, Anchor Systems
# 2008-06-12 - v1 - initial hack-up

LOGFILE=/root/newdatabases

usage()
{
        #echo "Usage: $0 expects two arguments: system username, name for new db"
        echo "Usage: $0 expects one argument: system username, which will be used as the name for the new DB"
}

if [ $# -ne 1 ]
then
        usage
        exit 1
fi

USERNAME=$1
DBNAME=$1
CLEAN_DBNAME=`echo $DBNAME | tr -cd a-zA-Z0-9`

# DB for root is not okay
if [ x$USERNAME = "xroot" ]
then
        echo "Username of root is not acceptable. Exiting..."
        exit 2
fi

# DBname must be alphanumeric
if [ x$DBNAME != x$CLEAN_DBNAME ]
then
        echo "New dbname is not sane, must be alphanumeric. Exiting..."
        exit 2
fi

# The username must exist
if ! /usr/bin/id "$USERNAME" 2> /dev/null > /dev/null
then
        echo "System username doesn't exist. Exiting..."
        exit 2
else
        echo -n ""
        #echo "username exists, cool"
fi

# DB of same name must NOT already exist
if /usr/bin/mysql -D "$DBNAME" -e '\q' 2>/dev/null
then
        echo "Database $DBNAME already exists. Exiting..."
        exit 2
fi
#echo "database $DBNAME can be created"

# Setup .my.cnf file for user, must not already exist
if [ -f "/home/${USERNAME}/.my.cnf" ]
then
        echo "~/.my.cnf already exists, don't want to clobber it. Exiting..."
        exit 1
fi
if ! /usr/bin/sudo -u $USERNAME touch "/home/${USERNAME}/.my.cnf"
then
        echo "Count not create blank .my.cnf in user's homdir. Exiting..."
        exit 1
fi
if ! /bin/chmod 600 "/home/${USERNAME}/.my.cnf"
then
        echo "Count not chmod .my.cnf to 600 in user's homdir. Exiting..."
        exit 1
fi

# Must be able to touch the output file
if ! /bin/touch "$LOGFILE"
then
        echo "Count not touch ${LOGFILE}, are you root?. Exiting..."
        exit 1
fi

# Make up a password
PASSWORD=`openssl rand -base64 12 | tr -cd a-zA-Z0-9`

# Write out .my.cnf for user
echo "[client]" >> "/home/${USERNAME}/.my.cnf"
echo "user=${USERNAME}" >> "/home/${USERNAME}/.my.cnf"
echo "password=${PASSWORD}" >> "/home/${USERNAME}/.my.cnf"
echo "" >> "/home/${USERNAME}/.my.cnf"
echo "[mysql]" >> "/home/${USERNAME}/.my.cnf"
echo "database=${DBNAME}" >> "/home/${USERNAME}/.my.cnf"


# Create the DB
echo "CREATE DATABASE $DBNAME; GRANT ALL PRIVILEGES ON ${DBNAME}.* TO '${USERNAME}'@'localhost' IDENTIFIED BY '${PASSWORD}' WITH GRANT OPTION; FLUSH PRIVILEGES;" | mysql

# Give visual feedback
echo "DATABASE l:p is:  $DBNAME // $PASSWORD"

# Log information to file
chmod 600 "$LOGFILE"
echo "dbname: $DBNAME" >> "$LOGFILE"
echo "dbpass: $PASSWORD" >> "$LOGFILE"
echo "" >> "$LOGFILE"

new_user.sh

# Adds a new user to the system (RHEL), setting a random password
# Adds entries to ssh_users and ftp_users, may not always be desired.
# Also sets the shell to the default, allowing ssh login. May not be desired.

# Barney Desmond, Anchor Systems
# 2008-06-12 - v1 - initial hack-up
# 2008-06-23 - v2 - bugfix for checking if username already exists; corrected full path to openssl; adds ftp_users and ssh_users entries

LOGFILE=/root/newaccounts

usage()
{
        echo "Usage: $0 expects one argument, the name for the new user"
}

if [ $# -ne 1 ]
then
        usage
        exit 1
fi

NEW_USERNAME=$1
CLEAN_NEW_USERNAME=`echo $1 | tr -cd a-zA-Z0-9`

# Sanity-check the username
if [ x$NEW_USERNAME != x$CLEAN_NEW_USERNAME ]
then
        echo "New username is not sane, must be alphanumeric. Exiting..."
        exit 2
fi

# Username must not already exist
if /usr/bin/id "$NEW_USERNAME" 2> /dev/null > /dev/null
then
        echo "Username already exists. Exiting..."
        exit 2
fi

# Generate a password
NEWPASSWD=`/usr/bin/openssl rand -base64 20 | tr -cd a-zA-Z0-9`

# Must be able to touch the output file
if ! /bin/touch "$LOGFILE"
then
        echo "Count not touch ${LOGFILE}, are you root?. Exiting..."
        exit 1
fi

# Add the user and set password
/usr/sbin/adduser --shell /bin/bash --disabled-password --gecos "$NEW_USERNAME" $NEW_USERNAME
/usr/sbin/usermod -p "$NEWPASSWD" $NEW_USERNAME

# Give the user SSH and FTP access
/bin/sed -i "1s/^/+\:${NEW_USERNAME}\:ALL\n/" /etc/security/ssh_users
#/bin/sed -i "1s/^/+\:${NEW_USERNAME}\:ALL\n/" /etc/security/ftp_users

# Log the new details
chmod 600 "$LOGFILE"
echo "username: ${NEW_USERNAME}" >> "$LOGFILE"
echo "password: ${NEWPASSWD}" >> "$LOGFILE"
echo "" >> "$LOGFILE"

# Visual output, could add a facility to silence it
echo "SYSTEM l:p is     ${NEW_USERNAME} // ${NEWPASSWD}"

new_vhost.sh

# Adds a vhost to the system in standard Anchor location (/etc/httpd/conf/users/username.conf)
# vhost file takes the name of the user
# Does not attempt to touch the running apache, you have to "bounce" it yourself

# Barney Desmond, Anchor Systems
# 2008-06-12 - rev1 - initial hack-up
# 2008-06-12 - rev2 - chown and chgrp the placeholder index.html, apparently sudo may not create it as the user
# 2008-06-19 - rev3 - added some parsing for the domain name to strip http://, www., etc. allows us to be smarter about pumping in domain names from a list
# 2008-06-24 - rev4 - added vhost_template
# 2009-02-11 - rev5 - Debian-ised

VHOST_TEMPLATE=/etc/apache2/sites-available/template

usage()
{
        echo "Usage: $0 expects two arguments: system username, domain name"
}

if [ $# -ne 2 ]
then
        usage
        exit 1
fi

# Switch to the config dir
cd /etc/apache2/sites-enabled

USERNAME=$1
DOMAIN=`echo $2 | tr 'A-Z' 'a-z' | sed -r 's,.*http://,,' | awk '{ print $1 }' | sed -r 's/^www\.//'`

# root is not okay
if [ x$USERNAME = "xroot" ]
then
        echo "Username of root is not acceptable. Exiting..."
        exit 2
fi

# The user muxt exist
if ! /usr/bin/id "$USERNAME" 2> /dev/null > /dev/null
then
        echo "System username doesn't exist. Exiting..."
        exit 2
else
        echo -n ""
        #echo "username exists, cool"
fi

# vhost file must not already exist
if [ -f "/etc/apache2/sites-available/${USERNAME}" ]
then
        echo "vhost ${USERNAME}.conf already exists. Exiting..."
        exit 1
fi

# vhost_template must exist
if [ ! -f "${VHOST_TEMPLATE}" ]
then
        echo "Couldn't find template vhost file at ${VHOST_TEMPLATE}. Exiting..."
        exit 1
fi

# Copy across the template vhost .conf
if ! /bin/cp "${VHOST_TEMPLATE}" "/etc/apache2/sites-available/${USERNAME}"
then
        echo "Couldn't not copy vhost template to /etc/apache2/sites-available/${USERNAME}. Exiting..."
        exit 1
fi
if ! /bin/ln -s "../sites-available/${USERNAME}" "${USERNAME}"
then
        echo "Couldn't create vhost symlink in /etc/apache2/sites-enabled/. Exiting..."
        exit 1
fi

# Search/replace the username and domain name in the vhost file
/bin/sed -r -i "s,USER,${USERNAME},g" /etc/apache2/sites-available/${USERNAME}
/bin/sed -r -i "s,DOMAIN,${DOMAIN},g" /etc/apache2/sites-available/${USERNAME}

# Fix up the user's homedir so apache can get in
/bin/chmod o+x "/home/${USERNAME}"

# Create a placeholder page to show it's working, must NOT already exist
if [ -f "/home/${USERNAME}/public_html/index.html" ]
then
        echo "/home/${USERNAME}/public_html/index.html already exists. Exiting..."
        exit 1
fi
/usr/bin/sudo -u $USERNAME echo "$USERNAME ok" > "/home/${USERNAME}/public_html/index.html"
/bin/chown $USERNAME "/home/${USERNAME}/public_html/index.html"
/bin/chgrp $USERNAME "/home/${USERNAME}/public_html/index.html"

snmp-diskio-collector

# by Jamie Wilkinson <jamie@anchor.net.au>
# this code is in the public domain
# based on passtest from the net-snmp distribution examples
# WARNING there is shitloads of IO required to get this information :)

debug_flag=0

debug () {
    if [ $debug_flag -eq 1 ]; then
        echo $* >> /tmp/snmp-diskio-collector-debug.log
    fi
}

PLACE=".1.3.6.1.4.1.2021.13.15"
REQ="$2"

debug
debug "new run" 
debug "args $*" 
if [ "$1" = "-s" ]; then
  exit 0
fi

# the 'tail' of the oid, everything after $PLACE
oidtail=`echo $REQ | sed "s/^$PLACE//"`
debug "oidtail=$oidtail" 

# number of devices we can export
if [ -f /proc/diskstats ]; then
    devcount=`wc -l /proc/diskstats | sed 's/^ *//' | cut -f1 -d' '`
else
    devcount=`wc -l /proc/partitions | sed 's/^ *//' | cut -f1 -d' '`
    devcount=`expr $devcount - 2`
fi
debug "devcount=$devcount" 

item=`echo $oidtail | cut -f4 -d.`
index=`echo $oidtail | cut -f5 -d.`
debug "oidtail=$oidtail, item=$item, index=$index" 

if [ "$1" = "-n" ]; then
    if [ -z "$item" ]; then
        item=1
        index=1
    elif [ -z "$index" ]; then
        index=1
    else
        index=`expr $index + 1`
        if [ "$index" -gt "$devcount" ]; then
            index=1
            item=`expr $item + 1`
            if [ "$item" -gt 6 ]; then
                # break out of the loop
                exit 0;
            fi
        fi
    fi
    RET=$PLACE.1.1.$item.$index
else
    case "$REQ" in
        $PLACE) exit 0;;
        *) RET=$REQ ;;
    esac
fi

debug "after -n, item=$item, index=$index" 
debug "RET is now $RET" 

echo "$RET"

debug "oidtail=$oidtail, item=$item, index=$index" 

# awk uses this variable in the environment below
export index
# see linux kernel Documentation/iostats.txt for format
if [ -n "$index" ]; then
    case "$item" in
        1)
            # diskIOIndex
            debug "result: diskIOIndex $index" 
            echo "integer"
            echo $index
            exit 0
            ;;
        2)
            # diskIODevice
            debug "result: diskIODevice $index" 
            echo "string"
            if [ -f /proc/diskstats ]; then
                awk 'FNR == ENVIRON["index"] { print $3 }' /proc/diskstats
            else
                awk 'FNR == ENVIRON["index"] + 2 { print $4 }' /proc/partitions
            fi
            exit 0
            ;;
        3)
            # diskIONRead
            debug "result: diskIONRead $index" 
            echo "counter"
            if [ -f /proc/diskstats ]; then
                awk 'FNR == ENVIRON["index"] { if (NR==14) print $6; else print $5 }' /proc/diskstats
            else
                awk 'FNR == ENVIRON["index"] + 2 { print $7 }' /proc/partitions
            fi
            exit 0
            ;;
        4)
            # diskIONWritten
            debug "result: diskIONWritten $index" 
            echo "counter"
            if [ -f /proc/diskstats ]; then
                awk 'FNR == ENVIRON["index"] { if (NR==14) print $10; else print $7 }' /proc/diskstats
            else
                awk 'FNR == ENVIRON["index"] + 2 { print $11 }' /proc/partitions
            fi
            exit 0
            ;;
        5)
            # diskIOReads
            debug "result: diskIOReads $index" 
            echo "counter"
            if [ -f /proc/diskstats ]; then
                awk 'FNR == ENVIRON["index"] { if (NR==14) print $4; else print $4 }' /proc/diskstats
            else
                awk 'FNR == ENVIRON["index"] + 2 { print $5 }' /proc/partitions
            fi
            exit 0
            ;;
        6)
            # diskIOWrites
            debug "result: diskIOWrites $index" 
            echo "counter"
            if [ -f /proc/diskstats ]; then
                awk 'FNR == ENVIRON["index"] { if (NR==14) print $8; else print $6 }' /proc/diskstats
            else
                awk 'FNR == ENVIRON["index"] + 2 { print $9 }' /proc/partitions
            fi
            exit 0
            ;;
        *) exit 0; #echo "string"; echo "debug... $RET $REQ"; exit 0 ;;
    esac
else
    exit 0
fi

vhost_template

# -*- apache -*- vim: syntax=apache
#
# %s,DOMAIN,X,g
# %s,USER,Y,g
<VirtualHost *:80>
        ServerName DOMAIN
        ServerAlias www.DOMAIN

        ServerAdmin webmaster@DOMAIN

        DocumentRoot /home/USER/public_html
        CustomLog /var/log/apache2/access_logs/DOMAIN_log combined
        ErrorLog /var/log/apache2/error_logs/USER_log

        <IfModule mod_suexec.c>
                SuexecUserGroup USER USER
        </IfModule>

        <IfModule mod_deflate.c>
                AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
        </IfModule>
</VirtualHost>

## HOWTO:
## * correct the IP address on the <VirtualHost> line
## * put your cursor on _THIS_ line
## * :.,$s/^#//
##
#<VirtualHost *:443>
#        ServerName DOMAIN
#        ServerAlias www.DOMAIN
#
#        ServerAdmin webmaster@DOMAIN
#
#        DocumentRoot /home/USER/public_html
#        CustomLog /var/log/apache2/access_logs/DOMAIN_log combined
#        ErrorLog /var/log/apache2/error_logs/USER_log
#
#       <IfModule mod_suexec.c>
#               SuexecUserGroup USER USER
#       </IfModule>
#
#       <IfModule mod_deflate.c>
#               AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
#       </IfModule>
#       <IfModule mod_ssl.c>
#               SSLEngine on
#
#               # :.,+3s,DOMAIN,THE_DOMAIN,
#               SSLCertificateFile /etc/ssl/www.DOMAIN_crt
#               SSLCertificateKeyFile /etc/ssl/www.DOMAIN_key
#
#               SSLCACertificateFile    /etc/ssl/foo.crt
#       </IfModule>
#</VirtualHost>

webalize

This shit is ballin'!

#!/usr/bin/perl

# webalize version 4

use strict;
use warnings;

use User::pwent;
use Getopt::Long;
use Tie::File;  # this module rocks
use File::Basename;
use File::Copy;

# virtualhosting wrapper for webalizer and awstats

# The canonical source of information for log files is the virtualhost
# configuration, in /etc/httpd/conf/users/ .
# Each file in that directory, named after the user account responsible,
# contains a list of virtualhosts; in each virtual host block there may be
# several domain names served, and one access log defined.

# The sources of information for processing logs, then, is:
# - user account name comes from the filename
# - domain name comes from one of ServerName or ServerAlias inside the file
# - access log path comes from the CustomLog directive in the file.

# based on the original webalize-users by Jamie Wilkinson and the
# process-logs script by Emmanuel Galanos
#
# updated by Barney Desmond <barney@anchor.net.au> - 2009-04-08
#   minor cleanup, enhancements and documentation, I want to run it on Ubuntu as well

#my $root = "/home/jaq/kayak";
my $root = "";
#my $awstats = '/var/www/awstats/awstats.pl';
my $awstats = '/usr/lib/cgi-bin/awstats.pl';
my $access_logs;
my $conffiledir;
my $logfiledir; # nastily redhat-specific in later usage
if (-e "$root/etc/debian_version") {
  $access_logs = "$root/var/log/apache2/access_logs";
  $conffiledir = "$root/etc/apache2/sites-enabled";
  $logfiledir = "$root/var/log/apache2";
} else {
  $access_logs = "$root/var/log/httpd/access_logs";
  $conffiledir = "$root/etc/httpd/conf/users";
  $logfiledir = "$root/etc/httpd";
}

my $outputdir;
if (-d "$root/var/www/html/statistics") {
  $outputdir = "$root/var/www/html/statistics";
} else {
  $outputdir = "$root/var/www/html/usage";
  if ( ! -d $outputdir ) {
      mkdir $outputdir or die "couldn't create $outputdir";
  }
}

sub usage () {
  print <<USAGE
usage: $0 [ --domain domain | --log access_log | --user username ]
USAGE
}

sub debug (@) {
  print @_ if -t STDOUT;
}

sub process_with_awstats($$$) {
  my $user = shift;
  my $domain = shift;
  my $log = shift;

  my $target = $outputdir . "/" . $domain;

  debug "processing " . $log . "\n";

  if (! -d $target) {
    debug "making directory $target\n";
    mkdir $target, 0755 or die "couldn't create target directory $target";
    #copy "/var/www/html/usage/htaccess_awstats_template", $target; # this line is redundant, I think. no sense keeping a per-domain template
  }
  # copy the template htaccess if it doesn't exist
  if (! -f $target . "/.htaccess") {
    copy("$root/var/www/html/usage/htaccess_awstats_template", $target . "/.htaccess") or die "failed copying in htaccess template";

    # set up the password protection
    my @htaccess;
    tie @htaccess, 'Tie::File', $target . "/.htaccess";
    for (@htaccess) {
        s/USERNAME/$user/;
        s/DOMAIN/$domain/;
    }
    untie @htaccess;
  }

  # Most of the time we just use the system-wide condif
  # ensure $CONF/awstats.$DOMAIN.conf exists
  my $CONF = "$root/etc/awstats";
  my $conf = $CONF . "/awstats.$domain.conf";
  if (! -f $conf) {
    my @config;

    # ensure the permanent config for running the cgi exists and is correct
    tie @config, 'Tie::File', $conf;
    @config = ();
    if (-e "$root/etc/debian_version") {
      push @config, "Include \"$root/etc/awstats/awstats.conf\"";
    } else {
      push @config, "Include \"$root/etc/awstats/awstats.model.conf\"";
    }
    push @config, "";
    push @config, "SiteDomain=\"" . $domain . "\"";
    push @config, "DirData=\"". $target . "\"";
    push @config, "HostAliases=\"www.". $domain . "\"";

    # this log format is "anchor"
    #push @config, "LogFormat=\"%virtualname %host %method %logname %time1 %bytesd %url %code %refererquot %uaquot\"";
    untie @config;
  }

  # We also offer the option of per-user awstats.conf - if there is one, fiddle things to use it instead
  # confdir might point to /tmp, if we're using the user's config fragment
  my $confdir = "";
  # now create a config to build the database with
  $conf = "/home/$user/awstats.conf";
  if (-f $conf) {
    debug "using config fragment at $conf \n";
    $confdir = "-configdir=/tmp";

    my @config;
    tie @config, 'Tie::File', "/tmp/awstats.$domain.conf";
    @config = ();
    push @config, "Include \"/etc/awstats/awstats.model.conf\"";
    push @config, "";
    push @config, "SiteDomain=\"" . $domain . "\"";
    push @config, "DirData=\"". $target . "\"";
    push @config, "HostAliases=\"www.". $domain . "\"";

    # this log format is "anchor"
    #push @config, "LogFormat=\"%virtualname %host %method %logname %time1 %bytesd %url %code %refererquot %uaquot\"";

    my @user;
    tie @user, 'Tie::File', $conf;
    for (@user) {
      next if (m/DirData/);
      next if (m/SiteDomain/);
      next if (m/HostAliases/);
      next if (m/Include/);
      next if (m/LogFile/);
      next if (m/LogFormat/);
      push @config, $_;
    }
    untie @config;
    debug "written temporary config to /tmp/awstats.$domain.conf\n";
  }

  # We can use gzipped or plain logfiles, we're that cool
  my $logfile;
  if ($log =~ m/.gz$/) {
    $logfile = "\"gzip -cd $log |\"";
  } else {
    $logfile = $log;
  }

  my $updatecmd = "$awstats $confdir -config=$domain -dir=$target -update -LogFile=$logfile";
  debug "exec'ing $updatecmd\n";
  open AWSTATSUPDATE, $updatecmd . " 2>&1 >/dev/null |"
    or die "awstats update exec pipe failed: $!";
  while (<AWSTATSUPDATE>) {
    if (! -t STDOUT) {
      next if (m/^Update for config /);
      next if (m/^With data in log file /);
      next if (m/^Searching new records from beginning/);
      next if (m/^Phase 1 :/);
      next if (m/^Direct access to last /);
      next if (m/^So searching/);
      next if (m/^Phase 2 :/);
      next if (m/^Jumped lines/);
      next if (m/^Parsed lines/);
      next if (m/^ Found /);
      next if (m/^Direct access after last parsed record/);
    }
    print $_;
  }
  close AWSTATSUPDATE;

  debug "exec done\n";
}

sub process_with_webalizer($$$) {
  my $user = shift;
  my $domain = shift;
  my $log = shift;

  my $target = $outputdir . "/" . $domain;

  debug "processing " . $log . "\n";

  if (! -d $target) {
    debug "making directory $target\n";
    mkdir $target, 0755;
  }

  my $dnscache = $target . "/dns_cache.db";
  if (-f $dnscache) {
    debug "removing old dns cache\n";
    unlink $dnscache;
  }

  my $cmd = "/usr/bin/webalizer -o $target -D $dnscache -n $domain $log";
  debug "exec'ing $cmd\n";
  open WEBALIZER, $cmd . " 2>&1 |"
    or die "webalizer exec pipe failed: $!";
  while (<WEBALIZER>) {
    if (! -t STDOUT) {
      next if (m/Truncating oversized \w+ field/);
      next if (m/Truncating oversized hostname/);
      next if (m/String exceeds storage size/);
      next if (m/No valid records found/);
      next if (m/Skipping oversized log record/);
      next if (m/Skipping bad record/);
    }
    print $_;
  }
  close WEBALIZER;
  debug "exec done\n";
}

sub process($$$) {
  my $user = shift;
  my $domain = shift;
  my $log = shift;

  my $target = $outputdir . '/' . $domain;
  if (-f $target . '/webalizer.hist') {
    debug "found existing webalizer database\n";
    process_with_webalizer($user, $domain, $log)
  } elsif (-f $awstats) {
    debug "awstats is installed, using\n";
    process_with_awstats($user, $domain, $log)
  } else {
    debug "defaulting to webalizer\n";
    process_with_webalizer($user, $domain, $log)
  }
}

sub filelist ($$) {
  # returns a list of files in directory who match regex
  my $directory = shift;
  my $regex = shift;

  opendir DIR, $directory
    or die "can't opendir $directory: $!";
  my @files = grep { /$regex/ && -f "$directory/$_" } readdir DIR;
  closedir DIR;
  return @files;
}

sub bylrc {
  # logrotate's chronological order: highest number first, ignore the .gz
  ($b =~ /_log\.(\d+)/)[0] <=> ($a =~ /_log\.(\d+)/)[0]
    # then by case-insensitive compare
    || uc($a) cmp uc($b)
}

sub processbydomain($) {
  my $domain = shift;

  # find the config file that handles this domain
  # take the user from that
  # work out the logs for this domain (watch out for vhosts)
  # process logs in order
}

sub processbyuser($) {
  my $user = shift;
  my @conffiles;

  if (-e "$root/etc/debian_version") {
    @conffiles = filelist($conffiledir, '^' . $user . '$');
  } else {
    @conffiles = filelist($conffiledir, '^' . $user . '\.conf$');
  }
  # should only be one of them...
  print @conffiles;
  if ($#conffiles > 1) {
    print "warning: more than one config file found for $user\n";
  }

  # take the access logs for this user
  my %access_logs = ();
  foreach (@conffiles) {
    debug "processing $_ for $user\n";
    my @file;
    tie @file, 'Tie::File', $conffiledir . "/" . $_;
    my $access_log;
    my $domain;
    foreach (@file) {
      if (m/CustomLog\s+([^ ]*)\s+/) {
        # This relies on $access_log being relative to something - on redhat that's /etc/httpd, where 'logs' is symlinked.
        # Not the case on debian, the log path has to be absolute, which is caught by the "does it start with /" check
        $access_log = $1;
        $access_log = $logfiledir . "/" . $access_log unless $access_log =~ q{^/};
        debug "found log $access_log\n";
      }
      if (m/ServerName\s+([^ :]+)/) {
        $domain = $1;
        debug "found domain $domain\n";
      }
      if (defined($access_log) && -f $access_log && defined($domain)) {
        # only the first domain assigned to the access log,
        # this saves us from using the wrong ServerName for an access log
        # when there's an SSL only vhost with www. in the name
        # typically the SSL logs are shared with the non-ssl logs.
        if (!defined($access_logs{$access_log})) {
          debug "using $access_log for $domain\n";
          $access_logs{$access_log} = $domain;
        }
        # unset them both
        undef $access_log;
        undef $domain;
      }
    }
    if (defined($domain) && ! defined($access_log)) {
      # if we get here it's because *both* werent unset, which means we fell through without finding a CustomLog
      # This means we just *assume* where the Customlog is..?
      debug "fell through without a CustomLog\n";
      if (-e "$root/etc/debian_version") {
        $access_log = $logfiledir . "/access_logs/" . $domain . "_log";
      } else {
        $access_log = $logfiledir . "/logs/access_logs/" . $domain . "_log";
      }
      if (!defined($access_logs{$access_log})) {
        debug "using $access_log for $domain\n";
        $access_logs{$access_log} = $domain;
      }
      # unset them both
      undef $access_log;
      undef $domain;
    }
    untie @file;
  }
  # expand to all logs for these domains
  foreach (keys %access_logs) {
    debug "snuh $_\n";
    my $dir = dirname $_;
    my $log = basename $_;
    my $domain = $access_logs{$_};

    debug "dir is $dir\nlog is $log\ndomain is $domain\n";
    # find the log files in that directory that logrotate will have made
    # we now ignore the one we found in apache's config file because
    # apache will still be writing to it, so let's leave it alone
    my @dom_logs = filelist($dir, '^' . $log . '\.\d+(.gz)?');
    # sort the logs in logrotate-chronological order

    foreach (sort bylrc @dom_logs) {
      debug "found log $_\n";
      # now we have a log file, a domain, and a user
      process($user, $domain, $dir . "/" . $_);
    }
  }
}

sub processbylog($) {
  my $log = shift;

  # find which domain and user are responsible for this log
  # process this log
}

my $domain;
my $log;
my $user;
if (!GetOptions('domain=s' => \$domain,
                'log=s' => \$log,
                'user=s' => \$user,
                'help' => sub { usage(); exit 0; }
               )) {
  exit 1;
}

my @logs;
if (defined($domain)) {
  processbydomain($domain);
} elsif (defined($log)) {
  processbylog($log);
} elsif (defined($user)) {
  processbyuser($user);
} else {
  # nothing defined, work it out
  my $arg = shift;
  # if no args, then process *_log.1
  if (!defined($arg)) {

    # FIXME: go by domains in the apache config, becauase a log file may
    # exist for a recently removed domain.
    @logs = `ls $access_logs/*_log.1`
      or die "couldn't find any access logs";

    foreach $log (@logs) {
      chomp $log;
      $log =~ m,$access_logs/(.*)_log,;
      $domain = $1;
      my $conffile;
      my $breaker = 0;

      my $target = "$outputdir/$domain";

      if (-e "$root/etc/debian_version") {
        $conffile = `egrep -liH "ServerName[[:space:]]+$domain(:|\$|[[:space:]])" $conffiledir/* | head -1`
          or $breaker = 1;
      } else {
        $conffile = `egrep -liH "ServerName[[:space:]]+$domain(:|\$|[[:space:]])" $conffiledir/*.conf | head -1`
          or $breaker = 1;
      }
      if ($breaker) {
        # Don't care, too much noise
        #debug "couldn't find the virtualhost that creates access log for $domain\n";
        next;
      };
      chomp $conffile;

      if (-e "$root/etc/debian_version") {
        $conffile =~ m,$conffiledir/(.*),
        or $breaker = 1;
        $user = $1;
      } else {
        $conffile =~ m,$conffiledir/(.*)\.conf,
        or $breaker = 1;
        $user = $1;
      }
      if ($breaker) {
        print $conffile . "'s name doesn't look right\n";
        next;
      };

      # check that this user exists, if we're root
      my $pw = getpwnam $user
        or $breaker = 1;
      if ($breaker) {
          # Don't really care about listing these, too much noise
          #print "user $user doesn't exist\n" if $< == 0;
          next;
      };

      # print if we're on a TTY or not
      print "$user: $domain\n" if -t STDOUT;

      my @lines = process $user, $domain, $log;

      if ($#lines > 0) {
        # may already have printed this once
        print "$user: $domain" if ! -t STDOUT;
        print @lines;
      }
    }
  } elsif (isdomain($arg)) {
    # check if the arg is a domain
    processbydomain($arg);
  } elsif (islog($arg)) {
    # check if the arg is a log
    processbylog($log);
  } elsif (isuser($arg)) {
    # check if the arg is a user
    processbyuser($arg);
  } else {
    print "REDO FROM START";
    print "$arg is neither domain, log file, nor user account\n";
    usage();
    exit 1;
  }
}
exit 0;
  • MoinMoin Powered
  • Python Powered
  • GPL licensed
  • Valid HTML 4.01
MoinMoin Release 1.9.11 [Revision release], Copyright by Juergen Hermann et al.