Quota

Generate chart from quota files

It is possible to open and try to read the quota files that the kernel maintains, from userspace. This could be used used to provide filesystem users a utilily to compare filesystem usage.

We need a hint from the file quotaio_v2.h

#!/bin/bash

F="${1}"
while shift
do
	Q=(`hexdump -ve \"%08x\\\n\" "${F}"`)

	if test "${Q[0]}" != "d9c01f11"
	then
		echo We can read aquota.user files
		exit 1
	fi
        if test "${Q[1]}" == "00000000"
        then
                ilx=6
                ihx=7
                r=12
		qb=20
        elif test "${Q[1]}" == "00000001"
        then
                ilx=12
                ihx=13
                r=18
		qb=13
        else
                echo aquota.user version "${Q[1]}"
                exit 1
        fi

	S=$(( ${#Q[*]} / 256 - 1))

	for INDEX in `seq 1 $S`
	do
		for SUBINDEX in `seq 0 $qb`
		do
			SUBOFF=$(( $INDEX * 256 + $SUBINDEX * $r + 4))
			ID=${Q[$(( $SUBOFF + 0))]}
			IL=${Q[$(( $SUBOFF + $ilx))]}
			IH=${Q[$(( $SUBOFF + $ihx))]}

			WHO=$(( 0x$ID))
			OCTETS=$(( 0x$IH$IL )) 
			if test $WHO -gt 999
			then
				declare -i USAGE[$WHO]
				USAGE[$WHO]+=$OCTETS
			fi
		done
	done
	F="${1}"
done

eval `getent passwd | sed -s s/^\\\\\([^:]*\\\\\):[^:]*:\\\\\([^:]*\\\\\):.*$/USERS[\\\\2]=\\\\1/g`

echo $'<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC
    "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN"
    "http://www.w3.org/2002/04/xhtml-math-svg/xhtml-math-svg-flat.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" 
xmlns:svg="http://www.w3.org/2000/svg"
><head><title></title></head><body><svg:svg width="'$(( ${#USAGE[@]} * 100 ))$'" height="900">
'

for WHO in "${!USAGE[@]}"
do
	echo "${USERS[$WHO]}" "${USAGE[$WHO]}"
done | sort -k 2 -rn | while read NAME USAGE
do
	if test -z "${MAX}"
	then
		X=20
		MAX=${USAGE}
	fi
	HEIGHT=`echo 800\*l\(${USAGE}\)/l\(${MAX}\)|bc -l|cut -d"." -f1`
	Y=$(( 800 - $HEIGHT ))
	echo "<svg:g>"
	echo "<svg:rect height=\"${HEIGHT}\" width=\"20\" x=\"${X}\" y=\"${Y}\" style=\"fill:#"`printf %02x%02x $(( $HEIGHT / 8)) $(( $Y / 4)) `"00;fill-opacity:1\"/>"
	echo "<svg:text x=\"${X}\" y=\"820\">${NAME}</svg:text>"
	echo "<svg:text x=\"${X}\" y=\"850\" style=\"font-size: 0.4em;\">${USAGE}</svg:text>"
	echo "</svg:g>"
	X=$((X + 100))
done
echo "</svg:svg></body></html>"