--- /dev/null
+:- module(cgi, [run_cgi/3]).
+
+:- use_module(library(dcgs)).
+:- use_module(library(process)).
+:- use_module(library(pio)).
+:- use_module(dcgs/response).
+:- use_module(config).
+
+run_cgi(Script, Query, Output) :-
+ once(run_cgi_(Script, Query, Output)).
+
+run_cgi_(Script, Query, Output) :-
+ base_env(Script, Env0),
+ query_env(Query, Env1),
+ tls_env(Client, Env2),
+ append([Env0, Env1, Env2], Env),
+ process_create(Script, [], [stdout(pipe(P)), environment(Env), process(H)]),
+ process_wait(H, N),
+ ( N #\= 0, throw(gemini_error(cgi_error, "CGI exited with non-zero exit code!"))
+ ; phrase_from_stream(seq(Output), P)
+ ).
+
+base_env(Script, Env) :-
+ hostname(Hostname), port(Port),
+ Env = [ "GATEWAY_INTERFACE"="CGI/1.1",
+ "REMOTE_ADDR"="TODO",
+ "REMOTE_HOST"="TODO",
+ "REMOTE_PORT"="TODO",
+ "PATH_INFO"="TODO",
+ "SCRIPT_NAME"=Script,
+ "SERVER_SOFTWARE"="SULA",
+ "SERVER_PROTOCOL"="GEMINI",
+ "SERVER_NAME"=Hostname,
+ "SERVER_PORT"=Port,
+ "GEMINI_URL"="TODO",
+ "GEMINI_URL_PATH"="TODO"
+ ].
+
+query_env(none, [ "QUERY_STRING"="" ]) :- !.
+query_env(Query, Env) :-
+ Env = [ "QUERY_STRING"=Query,
+ "GEMINI_QUERY_STRING"=Query
+ ].
+
+tls_env(none, Env) :-
+ Env = [ "AUTH_TYPE"="",
+ "REMOTE_USER"="",
+ "REMOTE_IDENT"=""
+ ],
+ !.
+tls_env(Cert, Env) :-
+ Env = [ "AUTH_TYPE"="Certificate",
+ "REMOTE_USER"="TODO",
+ "TLS_CLIENT_HASH"="TODO",
+ "TLS_CLIENT_SUBJECT"="TODO",
+ "TLS_CLIENT_ISSUER"="TODO",
+ "REMOTE_IDENT"="TODO"
+ ].