* vhosts to kilobytes, and a mapping from usernames to their vhosts and bandwidth
* totals. *)
- type disk = {uname : string, (* UNIX username *)
- blocks : int, (* Number of disk blocks used *)
- files : int} (* Number of files used *)
+ type disk = {uname : string, (* UNIX username *)
+ kbs : int} (* Number of kilobytes space used *)
val getDiskUsage : unit -> disk list
(* Get /home disk usage statistics, in descending blocks order. *)
end
type disk = {uname : string,
- blocks : int,
- files : int}
+ kbs : int}
fun getDiskUsage () =
let
- val proc = Unix.execute ("/usr/bin/sudo", ["/usr/sbin/repquota", "-g", "/home"])
+ val proc = Unix.execute ("/bin/sh", ["-c", "/usr/bin/sudo /usr/local/sbin/portal_quotas"])
val inf = Unix.textInstreamOf proc
- fun skipUntilLine () =
- case TextIO.inputLine inf of
- NONE => raise Fail "No dividing line found in repquota output"
- | SOME s =>
- if String.sub (s, 0) = #"-" then
- ()
- else
- skipUntilLine ()
+ fun ignoreThis s =
+ String.isPrefix "Kerberos " s
- fun readData acc =
- let
- fun done () =
- ListMergeSort.sort (fn (d1, d2) =>
- #blocks d1 < #blocks d2) acc
- in
- case TextIO.inputLine inf of
- NONE => done ()
- | SOME s =>
- case String.tokens Char.isSpace s of
- [uname, "--", blocks, bsoft, bhard, files, fsoft, fhard] =>
- readData ({uname = uname,
- blocks = valOf (Int.fromString blocks),
- files = valOf (Int.fromString files)} :: acc)
- | [uname, "+-", blocks, bsoft, bhard, _, files, fsoft, fhard] =>
- readData ({uname = uname,
- blocks = valOf (Int.fromString blocks),
- files = valOf (Int.fromString files)} :: acc)
- | [uname, "-+", blocks, bsoft, bhard, files, fsoft, fhard, _] =>
- readData ({uname = uname,
- blocks = valOf (Int.fromString blocks),
- files = valOf (Int.fromString files)} :: acc)
- | [uname, "++", blocks, bsoft, bhard, _, files, fsoft, fhard, _] =>
- readData ({uname = uname,
- blocks = valOf (Int.fromString blocks),
- files = valOf (Int.fromString files)} :: acc)
- | [] => done ()
- | _ => raise Fail ("Bad repquota line: " ^ s)
- end
+ fun loop acc =
+ case TextIO.inputLine inf of
+ NONE => acc
+ | SOME line =>
+ case String.tokens Char.isSpace line of
+ [uname, kbs] => loop ({uname = uname, kbs = valOf (Int.fromString kbs)} :: acc)
+ | _ =>
+ if ignoreThis line then
+ loop acc
+ else
+ raise Fail ("Bad quotas output: " ^ line)
in
- skipUntilLine ();
- readData []
+ loop []
before ignore (Unix.reap proc)
end