1 structure Stats
:> STATS
=
3 val webbw
= "/etc/stats/webbw"
4 val webbw_last
= "/etc/stats/webbw.last"
5 val webbw_last2
= "/etc/stats/webbw.last2"
7 type host
= {ssl
: bool,
12 case String.fields (fn ch
=> ch
= #
".") host
of
14 (case String.fields (fn ch
=> ch
= #
"_") first
of
15 [first
, "ssl"] => {ssl
= true, hostname
= String.concatWith
"." (first
::rest
),
17 | _
=> {ssl
= false, hostname
= host
, id
= host
})
18 | _
=> {ssl
= false, hostname
= host
, id
= host
}
27 | _
=> raise Fail
"Asked for too old of a bandwidth file"
29 val inf
= TextIO.openIn fname
31 val sum
= case TextIO.inputLine inf
of
32 NONE
=> raise Fail
"Can't read webbw"
35 case String.tokens
Char.isSpace l
of
36 [_
, n
] => valOf (Int.fromString n
)
37 | _
=> raise Fail
"Bad total in webbw"
40 case TextIO.inputLine inf
of
41 (NONE | SOME
"\n") => List.rev L
43 case String.tokens (fn ch
=> Char.isSpace ch
orelse ch
= #
":") l
of
44 [d
, n
] => readEm ((checkSsl d
, valOf (Int.fromString n
)) :: L
)
45 | _
=> raise Fail
"Bad row in webbw"
47 fun splitLast
[] = raise Fail
"Not enough items for splitLast"
48 | splitLast
[x
] = ([], x
)
51 val (l
, x
) = splitLast t
57 case TextIO.inputLine inf
of
60 case String.tokens (fn ch
=> Char.isSpace ch
orelse ch
= #
":" orelse ch
= #
"[" orelse ch
= #
"]" orelse ch
= #
",") l
of
63 val (l
, x
) = splitLast rest
65 readGroups ((d
, map checkSsl l
, valOf (Int.fromString x
)) :: L
)
67 | _
=> raise Fail
"Bad row in webbw, part 2"
70 (sum
, readEm
[], readGroups
[])
71 before TextIO.closeIn inf
74 type disk
= {uname
: string,
80 val proc
= Unix
.execute ("/usr/bin/sudo", ["/usr/sbin/repquota", "-g", "/home"])
81 val inf
= Unix
.textInstreamOf proc
83 fun skipUntilLine () =
84 case TextIO.inputLine inf
of
85 NONE
=> raise Fail
"No dividing line found in repquota output"
87 if String.sub (s
, 0) = #
"-" then
95 ListMergeSort
.sort (fn (d1
, d2
) =>
96 #blocks d1
< #blocks d2
) acc
98 case TextIO.inputLine inf
of
101 case String.tokens
Char.isSpace s
of
102 [uname
, "--", blocks
, bsoft
, bhard
, files
, fsoft
, fhard
] =>
103 readData ({uname
= uname
,
104 blocks
= valOf (Int.fromString blocks
),
105 files
= valOf (Int.fromString files
)} :: acc
)
106 |
[uname
, "+-", blocks
, bsoft
, bhard
, _
, files
, fsoft
, fhard
] =>
107 readData ({uname
= uname
,
108 blocks
= valOf (Int.fromString blocks
),
109 files
= valOf (Int.fromString files
)} :: acc
)
110 |
[uname
, "-+", blocks
, bsoft
, bhard
, files
, fsoft
, fhard
, _
] =>
111 readData ({uname
= uname
,
112 blocks
= valOf (Int.fromString blocks
),
113 files
= valOf (Int.fromString files
)} :: acc
)
114 |
[uname
, "++", blocks
, bsoft
, bhard
, _
, files
, fsoft
, fhard
, _
] =>
115 readData ({uname
= uname
,
116 blocks
= valOf (Int.fromString blocks
),
117 files
= valOf (Int.fromString files
)} :: acc
)
119 | _
=> raise Fail ("Bad repquota line: " ^ s
)
124 before ignore (Unix
.reap proc
)