At work I was asked to write a small script that allows users to get their quota from a Windows machine since apparently Windows doesn’t have an equivalent to the ‘quota‘ command. All these users also have accounts on UNIX boxes (running either SunOS 5.8 or Linux), so I figured the quickest way would be to SSH into one of these and make the output of the ‘quota‘ command easier to read.

This is composed of three parts, the first is a BAT script that calls putty with the hostname and points to a file with a list of commands to run. The second is this said list of commands to run. The third (and best part) is a short Perl script that will take the output of ‘quota -v‘ and format it depending on whether we’re running Solaris or Linux.

You will have to substitute HOSTNAME.DOMAINNAME.TLD with the Solaris/Linux box’s hostname. You may also have to change C:\Program~1\putty.exe with the path to your putty install. Place the following BAT file wherever. I put it in ‘Quota.bat‘ on the user’s desktop.

BAT file

REM - Quota.bat by Ryan Kavanagh <ryanakca@kubuntu.org>
@ECHO OFF
CLS
CALL C:\Program~1\putty.exe -ssh HOSTNAME.DOMAINNAME.TLD -l %USERNAME% -t -m C:\Program~1\winquota\quota

Now to the list of commands to run on the remote host, to be put in C:\Program~1\winquota\quota:

BASH script

#!/bin/bash
# By Ryan Kavanagh <ryanakca@kubuntu.org>
perl /usr/local/bin/quotacheck.pl
sh -c "echo -e 'This script will exit in:\t15 seconds\c'; sleep 1;"
sh -c 'for i in {14..10}; do echo -e "\b\b\b\b\b\b\b\b\b\b"$i" seconds\c"; sleep 1; done'
sh -c 'for i in {9..1}; do echo -e "\b\b\b\b\b\b\b\b\b\b "$i" seconds\c"; sleep 1; done'
sh -c 'echo ""'

This calls the Perl script. The rest of the script is to provide the user enough time (15 seconds) to read the output. If we didn’t have this, Putty would exit as soon as the display from quotacheck.pl had been displayed.

Place the following Perl script in /usr/local/bin/quotacheck.pl with executable permissions and you should be good to go.

Perl script

#!/usr/bin/perl
# quotacheck.pl -- Prettyfies the quota command's output
# Copyright (C) 2009  Ryan Kavanagh <ryanakca@kubuntu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.                            
 
use strict;
use English;
 
my @quota = `quota -v`;
 
sub fmt_quota {
    my $line = shift;
    # Get rid of leading whitespace so that we can work with Linux's quota
    # command as well.
    $line =~ s/^\s+//;
    my @a = split /\s+/, $line;
    my %data;
    my $os = $OSNAME;
    my $unit;
    if ($os == 'solaris') {
        # Solaris' quota uses 1kb as the unit
        $unit = 1024;
    } elsif ($os == 'linux') {
        # Linux's quota uses 512kb blocks as the unit
        $unit = 512;
    } else {
        $unit = 1;
        print "Disk usage unit might be incorrect";
    }
    if (($a[1] &gt; $a[2]) &amp;&amp; ($a[2] != 0)) {
        # The disk usage is over the quota, we'll receive a disk grace time
        %data = (
            'fs' =&gt; $a[0],
            'd_usage' =&gt; sprintf("%.2f", $a[1] / $unit) . 'M',
            'd_quota' =&gt; sprintf("%.2f", $a[2] / $unit) . 'M',
            'd_limit' =&gt; sprintf("%.2f", $a[3] / $unit) . 'M',
            'd_grace' =&gt; $a[4],
            'f_usage' =&gt; $a[5],
            'f_quota' =&gt; $a[6],
            'f_limit' =&gt; $a[7],
        );
    } else {
        # We won't receive a disk grace time.
        %data = (
            'fs' =&gt; $a[0],
            'd_usage' =&gt; sprintf("%.2f", $a[1] / $unit) . 'M',
            'd_quota' =&gt; sprintf("%.2f", $a[2] / $unit) . 'M',
            'd_limit' =&gt; sprintf("%.2f", $a[3] / $unit) . 'M',
            'f_usage' =&gt; $a[4],
            'f_quota' =&gt; $a[5],
            'f_limit' =&gt; $a[6],
        );
    }
    if (($data{'f_usage'} &gt; $data{'f_quota'}) &amp;&amp; ($data{'f_quota'} != 0)) {
        # The file usage is over the file quota, we'll receive a file grace
        # time.
        if (exists($data{'d_grace'})) {
            # The disk grace time is set, therefore we want $a[8].
            $data{'f_grace'} = $a[8];
        } else {
            $data{'f_grace'} = $a[7];
        }
    }
    my @lines;
    use integer;
    my $fs_pad = (80 - length ($data{'fs'})) / 2;
    no integer;
    # Push the header
    push(@lines, " " x $fs_pad . $data{'fs'} . " " x $fs_pad . "\n");
    push(@lines, " " x 15 . sprintf("%-15s%-15s%-15s%s", "YOUR USAGE",
            "YOUR QUOTA", "YOUR LIMIT", "GRACE TIME") . "\n");
    push(@lines, sprintf("%-15s%-15s%-15s%-15s%s", "DISK USAGE",
            $data{'d_usage'}, $data{'d_quota'}, $data{'d_limit'},
            $data{'d_grace'}) . "\n");
    push(@lines, sprintf("%-15s%-15s%-15s%-15s%s", "FILE COUNT",
            $data{'f_usage'}, $data{'f_quota'}, $data{'f_limit'},
            $data{'f_grace'}) . "\n");
    return @lines;
}
 
# Run fmt_quota on quota's output. Nothing interesting before line 2.
print $quota[0];
for (my $line = 2; $line != @quota; $line++) {
    print fmt_quota($quota[$line]);
}

I, the copyright holder of this work, hereby release the BAT file and the BASH script into the public domain. This applies worldwide. In case this is not legally possible, I grant any entity the right to use the BAT file and the BASH script work for any purpose, without any conditions, unless such conditions are required by law. The Perl script (quotacheck.pl) is released under the terms of the GNU General Public License version 2, or (at your option) any later version.