#!/bin/bash -efu

LANGUAGE="${LANGUAGE:-C}"
ALTERATOR_QUOTA_CONF="${ALTERATOR_QUOTA_CONF:-/etc/alterator/quota.conf}"

show_help(){
cat <<EOF
Helper script for alterator-quota module.

    Usage:  $0 <action> [<options>]

    Actions:

help   -- print this help
list   -- list users ("<UID> <name>" pairs)
listfs -- fist filesystems ("<device> <mountpoints>" pairs)
read   -- read settings for a given UID
write  -- write settings for a given UID

    Options:

-f <filesystem> -- specify filesystem (mandatory in read and write actions)
-u <UID>        -- specify user id (mandatory in read and write actions)
-a              -- show all users in list action; by default only users with
                   UIDs in the range [UID_MIN..UID_MAX] (see /etc/login.defs)
                   are shown
-q "<block_soft>,<block_hard>,<inode_soft>,<inode_hard>"
                -- specify quota settings for write action;
                   default value is "0,0,0,0"

    Examples:

$0 listfs
$0 list -f
$0 read -f /dev/sda1 -u 500
$0 write -f / -u 500 -q 100,100,20,20

EOF
} #' -- for xgettext, not mc!

. shell-getopt
. shell-error

on_list(){
  local num o1 o2
  getent passwd | tr ':' '\t' |
  while read name o1 num o3; do

    if [ -z "${all:-}" ]; then
      [ "$(($num>=$UID_MIN))" = "1" -a\
        "$(($num<=$UID_MAX))" = "1" ] || continue
    fi
    echo $num $name
  done
}

on_listfs(){
  local dev s d x1 x2 x3
  quota -v 2>/dev/null | sed -n -e '/Filesystem/,${/Filesystem/!p}' | 
  while read dev x1; do
    mount | while read s x2 d x3; do
      [ "$s" = "$dev" ] || continue
      echo "$s  $d"
    done
  done
}


on_read(){
  local fs1 sep b_used b_soft b_hard i_used i_soft i_hard x
  EDITOR=cat edquota $uid -f $fs | tail -n1 | (
    read fs1 b_used b_soft b_hard i_used i_soft i_hard x
    echo "uid:     $uid"
    echo "fs:      $fs"
    echo "b_used:  ${b_used:-0}"
    echo "b_soft:  ${b_soft:-0}"
    echo "b_hard:  ${b_hard:-0}"
    echo "b_grace: ${b_grace:-0}"
    echo "i_used:  ${i_used:-0}"
    echo "i_soft:  ${i_soft:-0}"
    echo "i_hard:  ${i_hard:-0}"
    echo "i_grace: ${i_grace:-0}"
  ) || fatal "Error: can't get quota"
}

on_write(){
  local b_soft b_hard i_soft i_hard
  echo -n "$quota" |
    tr -s ',; \n' ' ' |
    (
      grep '^[0-9]\+ [0-9]\+ [0-9]\+ [0-9]\+$' ||
        fatal "Error: bad quota setting: $quota"
    ) | (
      read b_soft b_hard i_soft i_hard
      setquota "$uid" "$b_soft" "$b_hard" "$i_soft" "$i_hard" "$fs" ||
        fatal "Error: can't set quota"
    )
}


action="${1:-help}"
shift ||:
all=

# get min and max gids from /etc/login.defs
eval "$(sed -n \
            -e 's/^[[:space:]]*UID_MAX[[:space:]]*/UID_MAX=/p'\
            -e 's/^[[:space:]]*UID_MIN[[:space:]]*/UID_MIN=/p'\
      /etc/login.defs)"

# parse options
case "$action" in
  list)
    while getopts "af:s" "$@"; do
      case $OPTOPT in
        f) fs="$OPTARG" ;;
        a) all=1 ;;
      esac
    done
  ;;
  read)
    while getopts "f:u:" "$@"; do
      case $OPTOPT in
        u) uid="$OPTARG" ;;
        f) fs="$OPTARG"  ;;
      esac
    done
  ;;
  write)
    while getopts "f:u:q:" "$@"; do
      case $OPTOPT in
        u) uid="$OPTARG"   ;;
        f) fs="$OPTARG"    ;;
        q) quota="$OPTARG" ;;
      esac
    done
  ;;
  *)
  ;;
esac

if [ "$action" = read -o "$action" = write ]; then
 [ -n "${fs:-}" ] || fatal "Error: filesystem does not set"
fi

if [ "$action" = read -o "$action" = write ]; then
 [ -n "${uid:-}" ] || fatal "Error: uid does not set"
fi

if [ "$action" = write ]; then
 [ -n "${quota:-}" ] || fatal "Error: quota settings are empty"
fi

verbose "executing $action action"
case $action in
  list)       on_list   ;;
  listfs)     on_listfs ;;
  read)       on_read   ;;
  write)      on_write  ;;
  *)          show_help ;;
esac
