structure PassGen :> PASSGEN = struct open Config Sql structure C = PgClient val db = ref (NONE : C.conn option) fun getDb () = valOf (!db) fun begin () = let val c = C.conn passgenDbstring in db := SOME c; ignore (C.dml c "BEGIN") end fun commit () = let val db = getDb () in C.dml db "COMMIT"; C.close db end fun gen () = let val db = getDb () val id = case C.oneRow db "SELECT nextval('PassSeq')" of [id] => C.intFromSql id | _ => raise Fail "Bad nextval() return" val proc = Unix.execute ("/usr/bin/apg", ["/usr/bin/apg", "-d", "-n", "1"]) val inf = Unix.textInstreamOf proc val pass = case TextIO.inputLine inf of NONE => raise Fail "No apg output" | SOME line => String.substring (line, 0, size line - 1) in ignore (Unix.reap proc); ignore (C.dml db ($`INSERT INTO Pass (id, pass) VALUES (^(C.intToSql id), ^(C.stringToSql pass))`)); (id, pass) end end