- NONE => raise Fail "No dividing line found in repquota output"
- | SOME s =>
- if String.sub (s, 0) = #"-" then
- ()
- else
- skipUntilLine ()
-
- 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
+ NONE => acc
+ | SOME line =>
+ case String.tokens Char.isSpace line of
+ [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
+ end
+ | _ => acc
+
+ val _ = TextIO.inputLine inf
+ val users = map (fn (uname, kbs) => {uname = uname, kbs = kbs}) (SM.listItemsi (loop SM.empty))