xref: /freebsd/contrib/mandoc/man.cgi.3 (revision b356ddf07671c7e0c960231344da7bddf5df42c4)
1.\"	$Id: man.cgi.3,v 1.4 2017/03/15 13:18:53 schwarze Exp $
2.\"
3.\" Copyright (c) 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
4.\"
5.\" Permission to use, copy, modify, and distribute this software for any
6.\" purpose with or without fee is hereby granted, provided that the above
7.\" copyright notice and this permission notice appear in all copies.
8.\"
9.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16.\"
17.Dd $Mdocdate: March 15 2017 $
18.Dt MAN.CGI 3
19.Os
20.Sh NAME
21.Nm man.cgi
22.Nd internals of the CGI program to search and display manual pages
23.Sh DESCRIPTION
24The source code of
25.Xr man.cgi 8
26is organized in four levels:
27.Pp
28.Bl -enum -compact
29.It
30.Sx Top level
31.It
32.Sx Page generators
33.It
34.Sx Result generators
35.It
36.Sx Utility routines
37.El
38.Ss Top level
39The top level of
40.Xr man.cgi 8
41consists of the
42.Fn main
43program and a few parser routines.
44.Bl -tag -width 1n
45.It Ft int Fn main void
46The main program
47.Bl -dash -compact
48.It
49limits execution time;
50.It
51changes to
52.Dv MAN_DIR ,
53the data directory containing all the manual trees;
54.It
55calls
56.Fn parse_manpath_conf ;
57.It
58if
59.Ev PATH_INFO
60is empty, calls
61.Fn parse_query_string ;
62otherwise,
63calls
64.Fn parse_path_info ;
65.It
66validates the manpath and the architecture;
67.It
68calls the appropriate one among the
69.Sx Page generators .
70.El
71.It Ft void Fn parse_manpath_conf "struct req *req"
72Parses and validates
73.Pa manpath.conf
74and fills
75.Va req->p
76and
77.Va req->psz .
78.It Ft void Fn parse_path_info "struct req *req" "const char *path"
79Parses and validates
80.Ev PATH_INFO ,
81clears
82.Va req->isquery ,
83and fills
84.Va req->q .
85.It Ft void Fn parse_query_string "struct req *req" "const char *qs"
86Parses and validates
87.Ev QUERY_STRING ,
88sets
89.Va req->isquery ,
90and fills
91.Va req->q .
92This function is the only user of the utility functions
93.Fn http_decode
94and
95.Fn set_query_attr .
96.El
97.Ss Page generators
98The purpose of each page generator is to print a complete HTML page,
99starting with the HTTP headers and continuing to the page footer.
100Before starting HTML output with
101.Fn resp_begin_html ,
102some page generators do some preparatory work, for example to decide
103which page to show.
104Each page generator ends with a call to
105.Fn resp_end_html .
106.Bl -tag -width 1n
107.It Ft void Fn pg_show "struct req *req" "const char *fullpath"
108This page generator is used when
109.Ev PATH_INFO
110contains the complete path to a manual page including manpath,
111section directory, optional architecture subdirectory, manual name
112and section number suffix.
113It validates the manpath, changes into it, validate the filename,
114and then calls
115.Fn resp_begin_html ,
116.Fn resp_searchform ,
117.Fn resp_show ,
118and
119.Fn resp_end_html
120in that order.
121.It Ft void Fn pg_search "const struct req *req"
122This page generator is used when
123.Ev PATH_INFO
124contains a search query in short format or when
125.Ev PATH_INFO
126is empty and a
127.Ev QUERY_STRING
128is provided.
129If possible, requests using
130.Ev QUERY_STRING
131are redirected to URIs using
132.Ev PATH_INFO
133by calling
134.Fn pg_redirect .
135Otherwise, it changes into the manpath and calls
136.Xr mansearch 3 .
137Depending on the result, it calls either
138.Fn pg_noresult
139or
140.Fn pg_searchres .
141.It Ft void Fn pg_redirect "const struct req *req" "const char *name"
142This function is special in so far as it does not print an HTML page,
143but only an HTTP 303 response with a Location: of the form:
144.Sm off
145.No http://
146.Ar host Ns /
147.Op Ar scriptname Ns /
148.Op Ar manpath Ns /
149.Op Ar arch Ns /
150.Fa name
151.Op Pf . Ar sec
152.Sm on
153.It Ft void Fn pg_noresult "const struct req *req" "const char *msg"
154This function calls
155.Fn resp_begin_html ,
156.Fn resp_searchform ,
157prints the
158.Fa msg
159passed to it, and calls
160.Fn resp_end_html .
161.It Ft void Fn pg_searchres "const struct req *req" "struct manpage *r"\
162 "size_t sz"
163This function first validates the filenames found.
164If
165.Ev QUERY_STRING
166was used and there is exactly one result,
167it writes an HTTP redirect to that result.
168Otherwise, it writes an HTML result page beginning with
169.Fn resp_begin_html
170and
171.Fn resp_searchform .
172If there is more than one result, it writes a list of links
173to all the results.
174If it was a
175.Xr man 1
176rather than an
177.Xr apropos 1
178query or if there is only one single result, it calls
179.Fn resp_show .
180Finally, it calls
181.Fn resp_end_html .
182.It Ft void Fn pg_index "const struct req *req"
183This page generator is used when
184.Ev PATH_INFO
185and
186.Ev QUERY_STRING
187are both empty.
188It calls
189.Fn resp_begin_html
190and
191.Fn resp_searchform ,
192writes links to help pages, and calls
193.Fn resp_end_html .
194.It Ft void Fn pg_error_badrequest "const char *msg"
195This page generator is used when
196.Fn main
197or
198.Fn pg_show
199detect an invalid URI.
200It calls
201.Fn resp_begin_html ,
202prints the
203.Fa msg
204provided, and calls
205.Fn resp_end_html .
206.It Ft void Fn pg_error_internal void
207This page generator is used by various functions when errors are
208detected in the
209.Pa manpath.conf
210configuration file, in
211.Xr mandoc.db 5
212databases, in the
213.Xr mandoc 3
214parser, in file system permissions, or when setting up timeouts.
215It calls
216.Fn resp_begin_html ,
217prints
218.Qq "Internal Server Error" ,
219and calls
220.Fn resp_end_html .
221Before calling
222.Fn pg_error_internal ,
223call
224.Xr warn 3
225or
226.Xr warnx 3
227to log the reason of the error to the
228.Xr httpd 8
229server log file.
230.El
231.Ss Result generators
232The purpose of result generators is to print a chunk of HTML code.
233When they print untrusted strings or characters,
234.Fn html_print
235and
236.Fn html_putchar
237are used.
238The highest level result generators are:
239.Bl -tag -width 1n
240.It Ft void Fn resp_begin_html "int code" "const char *msg" "const char *file"
241This generator calls
242.Fn resp_begin_http
243to print the HTTP headers, then prints the HTML header up to the
244opening tag of the <body> element, then copies the file
245.Pa header.html
246to the output, if it exists and is readable.
247If
248.Fa file
249is not
250.Dv NULL ,
251it is used for the <title> element.
252.It Ft void Fn resp_searchform "const struct req *req" "enum focus focus"
253This generator prints a search form, filling it with data
254from the provided request object.
255If the
256.Fa focus
257argument is
258.Dv FOCUS_QUERY ,
259it sets the document's autofocus to the query input box.
260.It Ft void Fn resp_show "const struct req *req" "const char *file"
261This wrapper dispatches to either
262.Fn resp_catman
263or
264.Fn resp_format ,
265depending on whether
266.Ar file
267starts with
268.Pa cat
269or
270.Pa man ,
271respectively.
272.It Ft void Fn resp_catman "const struct req *req" "const char *file"
273This generator translates a preformatted, backspace-encoded manual
274page to HTML and prints it to the output.
275.It Ft void Fn resp_format "const struct req *req" "const char *file"
276This generator formats a manual page on the standard output,
277using the functions documented in
278.Xr mchars_alloc 3
279and
280.Xr mandoc 3 .
281.It Ft void Fn resp_end_html void
282This generator copies the file
283.Pa footer.html
284to the output, if it exists and is readable,
285and closes the <body> and <html> elements.
286.El
287.Ss Utility routines
288These functions take a string and return 1 if it is valid, or 0 otherwise.
289.Bl -tag -width 1n
290.It Ft int Fn validate_urifrag "const char *frag"
291Checks that the string only contains alphanumeric ASCII characters,
292dashes, dots, slashes, and underscores.
293.It Ft int Fn validate_manpath "const struct req *req" "const char* manpath"
294Checks that the string is either
295.Qq mandoc
296or one of the manpaths configured in
297.Pa manpath.conf .
298.It Ft int Fn validate_filename "const char *file"
299Checks that the string starts with
300.Qq man
301or
302.Qq cat
303and does not ascend to parent directories.
304.El
305.Sh SEE ALSO
306.Xr mandoc 3 ,
307.Xr mansearch 3 ,
308.Xr mchars_alloc 3 ,
309.Xr mandoc.db 5 ,
310.Xr man.cgi 8
311