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