type disk = {uname : string,
kbs : int}
+ structure StringKey = struct
+ type ord_key = string
+ val compare = String.compare
+ end
+
+ structure SM = BinaryMapFn(StringKey)
+
fun getDiskUsage () =
let
- val proc = Unix.execute ("/bin/sh", ["-c", "/usr/bin/sudo /usr/local/sbin/portal_quotas"])
+ val proc = Unix.execute ("/bin/sh", ["-c", "/usr/bin/vos listvol deleuze"])
val inf = Unix.textInstreamOf proc
- fun ignoreThis s =
- String.isPrefix "Kerberos " s
-
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
+ [vol, _, _, kbs, _, _] =>
+ let
+ val kbsOld = case SM.find (acc, vol) of
+ NONE => 0
+ | SOME n => n
+
+ val uname = case String.tokens (fn ch => ch = #".") vol of
+ [_, uname] =>
+ ((Posix.SysDB.getpwnam uname;
+ SOME uname)
+ handle OS.SysErr _ => NONE)
+ | _ => NONE
+
+ val acc = case uname of
+ NONE => acc
+ | SOME uname => SM.insert (acc, uname, valOf (Int.fromString kbs) + kbsOld)
+ in
loop acc
- else
- raise Fail ("Bad quotas output: " ^ line)
+ end
+ | _ => acc
+
+ val _ = TextIO.inputLine inf
+ val users = map (fn (uname, kbs) => {uname = uname, kbs = kbs}) (SM.listItemsi (loop SM.empty))
in
- loop []
- before ignore (Unix.reap proc)
+ ignore (Unix.reap proc);
+ ListMergeSort.sort (fn ({kbs = kbs1, ...}, {kbs = kbs2, ...}) => kbs1 < kbs2) users
end
end