Annotation of mandoc/man.cgi.3, Revision 1.3
1.3 ! schwarze 1: .\" $Id: man.cgi.3,v 1.2 2016/07/07 19:19:01 schwarze Exp $
1.1 schwarze 2: .\"
3: .\" Copyright (c) 2016 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: .\"
1.3 ! schwarze 17: .Dd $Mdocdate: July 7 2016 $
1.1 schwarze 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
24: The source code of
25: .Xr man.cgi 8
26: is 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
39: The top level of
40: .Xr man.cgi 8
41: consists of the
42: .Fn main
43: program and a few parser routines.
44: .Bl -tag -width 1n
45: .It Ft int Fn main void
46: The main program
47: .Bl -dash -compact
48: .It
49: limits execution time;
50: .It
51: changes to
52: .Dv MAN_DIR ,
53: the data directory containing all the manual trees;
54: .It
55: calls
56: .Fn parse_manpath_conf ;
57: .It
1.2 schwarze 58: if
59: .Ev PATH_INFO
60: is empty, calls
61: .Fn parse_query_string ;
62: otherwise,
1.1 schwarze 63: calls
64: .Fn parse_path_info ;
65: .It
66: validates the manpath and the architecture;
67: .It
68: calls the appropriate one among the
69: .Sx Page generators .
70: .El
71: .It Ft void Fn parse_manpath_conf "struct req *req"
72: Parses and validates
73: .Pa manpath.conf
74: and fills
75: .Va req->p
76: and
77: .Va req->psz .
78: .It Ft void Fn parse_path_info "struct req *req" "const char *path"
79: Parses and validates
80: .Ev PATH_INFO ,
81: clears
82: .Va req->isquery ,
83: and fills
84: .Va req->q .
85: .It Ft void Fn parse_query_string "struct req *req" "const char *qs"
86: Parses and validates
87: .Ev QUERY_STRING ,
88: sets
89: .Va req->isquery ,
90: and fills
91: .Va req->q .
92: This function is the only user of the utility functions
93: .Fn http_decode
94: and
95: .Fn set_query_attr .
96: .El
97: .Ss Page generators
98: The purpose of each page generator is to print a complete HTML page,
99: starting with the HTTP headers and continuing to the page footer.
100: Before starting HTML output with
101: .Fn resp_begin_html ,
102: some page generators do some preparatory work, for example to decide
103: which page to show.
104: Each 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"
108: This page generator is used when
109: .Ev PATH_INFO
110: contains the complete path to a manual page including manpath,
111: section directory, optional architecture subdirectory, manual name
112: and section number suffix.
113: It validates the manpath, changes into it, validate the filename,
114: and then calls
115: .Fn resp_begin_html ,
116: .Fn resp_searchform ,
117: .Fn resp_show ,
118: and
119: .Fn resp_end_html
120: in that order.
121: .It Ft void Fn pg_search "const struct req *req"
122: This page generator is used when
123: .Ev PATH_INFO
124: contains a search query in short format or when
125: .Ev PATH_INFO
126: is empty and a
127: .Ev QUERY_STRING
128: is provided.
1.3 ! schwarze 129: If possible, requests using
! 130: .Ev QUERY_STRING
! 131: are redirected to URIs using
! 132: .Ev PATH_INFO
! 133: by calling
! 134: .Fn pg_redirect .
! 135: Otherwise, it changes into the manpath and calls
1.1 schwarze 136: .Xr mansearch 3 .
137: Depending on the result, it calls either
138: .Fn pg_noresult
139: or
140: .Fn pg_searchres .
1.3 ! schwarze 141: .It Ft void Fn pg_redirect "const struct req *req" "const char *name"
! 142: This function is special in so far as it does not print an HTML page,
! 143: but 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
1.1 schwarze 153: .It Ft void Fn pg_noresult "const struct req *req" "const char *msg"
154: This function calls
155: .Fn resp_begin_html ,
156: .Fn resp_searchform ,
157: prints the
158: .Fa msg
159: passed 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"
163: This function first validates the filenames found.
164: If
165: .Ev QUERY_STRING
166: was used and there is exactly one result,
167: it writes an HTTP redirect to that result.
168: Otherwise, it writes an HTML result page beginning with
169: .Fn resp_begin_html
170: and
171: .Fn resp_searchform .
172: If there is more than one result, it writes a list of links
173: to all the results.
174: If it was a
175: .Xr man 1
176: rather than an
177: .Xr apropos 1
178: query or if there is only one single result, it calls
179: .Fn resp_show .
180: Finally, it calls
181: .Fn resp_end_html .
182: .It Ft void Fn pg_index "const struct req *req"
183: This page generator is used when
184: .Ev PATH_INFO
185: and
186: .Ev QUERY_STRING
187: are both empty.
188: It calls
189: .Fn resp_begin_html
190: and
191: .Fn resp_searchform ,
192: writes links to help pages, and calls
193: .Fn resp_end_html .
194: .It Ft void Fn pg_error_badrequest "const char *msg"
195: This page generator is used when
196: .Fn main
197: or
198: .Fn pg_show
199: detect an invalid URI.
200: It calls
201: .Fn resp_begin_html ,
202: prints the
203: .Fa msg
204: provided, and calls
205: .Fn resp_end_html .
206: .It Ft void Fn pg_error_internal void
207: This page generator is used by various functions when errors are
208: detected in the
209: .Pa manpath.conf
210: configuration file, in
211: .Xr mandoc.db 5
212: databases, in the
213: .Xr mandoc 3
214: parser, in file system permissions, or when setting up timeouts.
215: It calls
216: .Fn resp_begin_html ,
217: prints
218: .Qq "Internal Server Error" ,
219: and calls
220: .Fn resp_end_html .
221: Before calling
222: .Fn pg_error_internal ,
223: call
224: .Xr warn 3
225: or
226: .Xr warnx 3
227: to log the reason of the error to the
228: .Xr httpd 8
229: server log file.
230: .El
231: .Ss Result generators
232: The purpose of result generators is to print a chunk of HTML code.
233: When they print untrusted strings or characters,
234: .Fn html_print
235: and
236: .Fn html_putchar
237: are used.
238: The highest level result generators are:
239: .Bl -tag -width 1n
240: .It Ft void Fn resp_begin_html "int code" "const char *msg"
241: This generator calls
242: .Fn resp_begin_http
243: to print the HTTP headers, then prints the HTML header up to the
244: opening tag of the <body> element, then copies the file
245: .Pa header.html
246: to the output, if it exists and is readable.
1.2 schwarze 247: .It Ft void Fn resp_searchform "const struct req *req" "enum focus focus"
1.1 schwarze 248: This generator prints a search form, filling it with data
249: from the provided request object.
1.2 schwarze 250: If the
251: .Fa focus
252: argument is
253: .Dv FOCUS_QUERY ,
254: it sets the document's autofocus to the query input box.
1.1 schwarze 255: .It Ft void Fn resp_show "const struct req *req" "const char *file"
256: This wrapper dispatches to either
257: .Fn resp_catman
258: or
259: .Fn resp_format ,
260: depending on whether
261: .Ar file
262: starts with
263: .Pa cat
264: or
265: .Pa man ,
266: respectively.
267: .It Ft void Fn resp_catman "const struct req *req" "const char *file"
268: This generator translates a preformatted, backspace-encoded manual
269: page to HTML and prints it to the output.
270: .It Ft void Fn resp_format "const struct req *req" "const char *file"
271: This generator formats a manual page on the standard output,
272: using the functions documented in
273: .Xr mchars_alloc 3
274: and
275: .Xr mandoc 3 .
276: .It Ft void Fn resp_end_html void
277: This generator copies the file
278: .Pa footer.html
279: to the output, if it exists and is readable,
280: and closes the <body> and <html> elements.
281: .El
282: .Ss Utility routines
283: These functions take a string and return 1 if it is valid, or 0 otherwise.
284: .Bl -tag -width 1n
285: .It Ft int Fn validate_urifrag "const char *frag"
286: Checks that the string only contains alphanumeric ASCII characters,
287: dashes, dots, slashes, and underscores.
288: .It Ft int Fn validate_manpath "const struct req *req" "const char* manpath"
289: Checks that the string is either
290: .Qq mandoc
291: or one of the manpaths configured in
292: .Pa manpath.conf .
293: .It Ft int Fn validate_filename "const char *file"
294: Checks that the string starts with
295: .Qq man
296: or
297: .Qq cat
298: and does not ascend to parent directories.
299: .El
300: .Sh SEE ALSO
301: .Xr mandoc 3 ,
302: .Xr mansearch 3 ,
1.2 schwarze 303: .Xr mchars_alloc 3 ,
1.1 schwarze 304: .Xr mandoc.db 5 ,
305: .Xr man.cgi 8
CVSweb