1*c9bcef03Schristos.\" Id: man.cgi.3,v 1.4 2017/03/15 13:18:53 schwarze Exp 29ff1f2acSchristos.\" 3*c9bcef03Schristos.\" Copyright (c) 2016, 2017 Ingo Schwarze <schwarze@openbsd.org> 49ff1f2acSchristos.\" 59ff1f2acSchristos.\" Permission to use, copy, modify, and distribute this software for any 69ff1f2acSchristos.\" purpose with or without fee is hereby granted, provided that the above 79ff1f2acSchristos.\" copyright notice and this permission notice appear in all copies. 89ff1f2acSchristos.\" 99ff1f2acSchristos.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 109ff1f2acSchristos.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 119ff1f2acSchristos.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 129ff1f2acSchristos.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 139ff1f2acSchristos.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 149ff1f2acSchristos.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 159ff1f2acSchristos.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 169ff1f2acSchristos.\" 17*c9bcef03Schristos.Dd March 15, 2017 189ff1f2acSchristos.Dt MAN.CGI 3 199ff1f2acSchristos.Os 209ff1f2acSchristos.Sh NAME 219ff1f2acSchristos.Nm man.cgi 229ff1f2acSchristos.Nd internals of the CGI program to search and display manual pages 239ff1f2acSchristos.Sh DESCRIPTION 249ff1f2acSchristosThe source code of 259ff1f2acSchristos.Xr man.cgi 8 269ff1f2acSchristosis organized in four levels: 279ff1f2acSchristos.Pp 289ff1f2acSchristos.Bl -enum -compact 299ff1f2acSchristos.It 309ff1f2acSchristos.Sx Top level 319ff1f2acSchristos.It 329ff1f2acSchristos.Sx Page generators 339ff1f2acSchristos.It 349ff1f2acSchristos.Sx Result generators 359ff1f2acSchristos.It 369ff1f2acSchristos.Sx Utility routines 379ff1f2acSchristos.El 389ff1f2acSchristos.Ss Top level 399ff1f2acSchristosThe top level of 409ff1f2acSchristos.Xr man.cgi 8 419ff1f2acSchristosconsists of the 429ff1f2acSchristos.Fn main 439ff1f2acSchristosprogram and a few parser routines. 449ff1f2acSchristos.Bl -tag -width 1n 459ff1f2acSchristos.It Ft int Fn main void 469ff1f2acSchristosThe main program 479ff1f2acSchristos.Bl -dash -compact 489ff1f2acSchristos.It 499ff1f2acSchristoslimits execution time; 509ff1f2acSchristos.It 519ff1f2acSchristoschanges to 529ff1f2acSchristos.Dv MAN_DIR , 539ff1f2acSchristosthe data directory containing all the manual trees; 549ff1f2acSchristos.It 559ff1f2acSchristoscalls 569ff1f2acSchristos.Fn parse_manpath_conf ; 579ff1f2acSchristos.It 589ff1f2acSchristosif 599ff1f2acSchristos.Ev PATH_INFO 609ff1f2acSchristosis empty, calls 619ff1f2acSchristos.Fn parse_query_string ; 629ff1f2acSchristosotherwise, 639ff1f2acSchristoscalls 649ff1f2acSchristos.Fn parse_path_info ; 659ff1f2acSchristos.It 669ff1f2acSchristosvalidates the manpath and the architecture; 679ff1f2acSchristos.It 689ff1f2acSchristoscalls the appropriate one among the 699ff1f2acSchristos.Sx Page generators . 709ff1f2acSchristos.El 719ff1f2acSchristos.It Ft void Fn parse_manpath_conf "struct req *req" 729ff1f2acSchristosParses and validates 739ff1f2acSchristos.Pa manpath.conf 749ff1f2acSchristosand fills 759ff1f2acSchristos.Va req->p 769ff1f2acSchristosand 779ff1f2acSchristos.Va req->psz . 789ff1f2acSchristos.It Ft void Fn parse_path_info "struct req *req" "const char *path" 799ff1f2acSchristosParses and validates 809ff1f2acSchristos.Ev PATH_INFO , 819ff1f2acSchristosclears 829ff1f2acSchristos.Va req->isquery , 839ff1f2acSchristosand fills 849ff1f2acSchristos.Va req->q . 859ff1f2acSchristos.It Ft void Fn parse_query_string "struct req *req" "const char *qs" 869ff1f2acSchristosParses and validates 879ff1f2acSchristos.Ev QUERY_STRING , 889ff1f2acSchristossets 899ff1f2acSchristos.Va req->isquery , 909ff1f2acSchristosand fills 919ff1f2acSchristos.Va req->q . 929ff1f2acSchristosThis function is the only user of the utility functions 939ff1f2acSchristos.Fn http_decode 949ff1f2acSchristosand 959ff1f2acSchristos.Fn set_query_attr . 969ff1f2acSchristos.El 979ff1f2acSchristos.Ss Page generators 989ff1f2acSchristosThe purpose of each page generator is to print a complete HTML page, 999ff1f2acSchristosstarting with the HTTP headers and continuing to the page footer. 1009ff1f2acSchristosBefore starting HTML output with 1019ff1f2acSchristos.Fn resp_begin_html , 1029ff1f2acSchristossome page generators do some preparatory work, for example to decide 1039ff1f2acSchristoswhich page to show. 1049ff1f2acSchristosEach page generator ends with a call to 1059ff1f2acSchristos.Fn resp_end_html . 1069ff1f2acSchristos.Bl -tag -width 1n 1079ff1f2acSchristos.It Ft void Fn pg_show "struct req *req" "const char *fullpath" 1089ff1f2acSchristosThis page generator is used when 1099ff1f2acSchristos.Ev PATH_INFO 1109ff1f2acSchristoscontains the complete path to a manual page including manpath, 1119ff1f2acSchristossection directory, optional architecture subdirectory, manual name 1129ff1f2acSchristosand section number suffix. 1139ff1f2acSchristosIt validates the manpath, changes into it, validate the filename, 1149ff1f2acSchristosand then calls 1159ff1f2acSchristos.Fn resp_begin_html , 1169ff1f2acSchristos.Fn resp_searchform , 1179ff1f2acSchristos.Fn resp_show , 1189ff1f2acSchristosand 1199ff1f2acSchristos.Fn resp_end_html 1209ff1f2acSchristosin that order. 1219ff1f2acSchristos.It Ft void Fn pg_search "const struct req *req" 1229ff1f2acSchristosThis page generator is used when 1239ff1f2acSchristos.Ev PATH_INFO 1249ff1f2acSchristoscontains a search query in short format or when 1259ff1f2acSchristos.Ev PATH_INFO 1269ff1f2acSchristosis empty and a 1279ff1f2acSchristos.Ev QUERY_STRING 1289ff1f2acSchristosis provided. 129*c9bcef03SchristosIf possible, requests using 130*c9bcef03Schristos.Ev QUERY_STRING 131*c9bcef03Schristosare redirected to URIs using 132*c9bcef03Schristos.Ev PATH_INFO 133*c9bcef03Schristosby calling 134*c9bcef03Schristos.Fn pg_redirect . 135*c9bcef03SchristosOtherwise, it changes into the manpath and calls 1369ff1f2acSchristos.Xr mansearch 3 . 1379ff1f2acSchristosDepending on the result, it calls either 1389ff1f2acSchristos.Fn pg_noresult 1399ff1f2acSchristosor 1409ff1f2acSchristos.Fn pg_searchres . 141*c9bcef03Schristos.It Ft void Fn pg_redirect "const struct req *req" "const char *name" 142*c9bcef03SchristosThis function is special in so far as it does not print an HTML page, 143*c9bcef03Schristosbut only an HTTP 303 response with a Location: of the form: 144*c9bcef03Schristos.Sm off 145*c9bcef03Schristos.No http:// 146*c9bcef03Schristos.Ar host Ns / 147*c9bcef03Schristos.Op Ar scriptname Ns / 148*c9bcef03Schristos.Op Ar manpath Ns / 149*c9bcef03Schristos.Op Ar arch Ns / 150*c9bcef03Schristos.Fa name 151*c9bcef03Schristos.Op Pf . Ar sec 152*c9bcef03Schristos.Sm on 1539ff1f2acSchristos.It Ft void Fn pg_noresult "const struct req *req" "const char *msg" 1549ff1f2acSchristosThis function calls 1559ff1f2acSchristos.Fn resp_begin_html , 1569ff1f2acSchristos.Fn resp_searchform , 1579ff1f2acSchristosprints the 1589ff1f2acSchristos.Fa msg 1599ff1f2acSchristospassed to it, and calls 1609ff1f2acSchristos.Fn resp_end_html . 1619ff1f2acSchristos.It Ft void Fn pg_searchres "const struct req *req" "struct manpage *r"\ 1629ff1f2acSchristos "size_t sz" 1639ff1f2acSchristosThis function first validates the filenames found. 1649ff1f2acSchristosIf 1659ff1f2acSchristos.Ev QUERY_STRING 1669ff1f2acSchristoswas used and there is exactly one result, 1679ff1f2acSchristosit writes an HTTP redirect to that result. 1689ff1f2acSchristosOtherwise, it writes an HTML result page beginning with 1699ff1f2acSchristos.Fn resp_begin_html 1709ff1f2acSchristosand 1719ff1f2acSchristos.Fn resp_searchform . 1729ff1f2acSchristosIf there is more than one result, it writes a list of links 1739ff1f2acSchristosto all the results. 1749ff1f2acSchristosIf it was a 1759ff1f2acSchristos.Xr man 1 1769ff1f2acSchristosrather than an 1779ff1f2acSchristos.Xr apropos 1 1789ff1f2acSchristosquery or if there is only one single result, it calls 1799ff1f2acSchristos.Fn resp_show . 1809ff1f2acSchristosFinally, it calls 1819ff1f2acSchristos.Fn resp_end_html . 1829ff1f2acSchristos.It Ft void Fn pg_index "const struct req *req" 1839ff1f2acSchristosThis page generator is used when 1849ff1f2acSchristos.Ev PATH_INFO 1859ff1f2acSchristosand 1869ff1f2acSchristos.Ev QUERY_STRING 1879ff1f2acSchristosare both empty. 1889ff1f2acSchristosIt calls 1899ff1f2acSchristos.Fn resp_begin_html 1909ff1f2acSchristosand 1919ff1f2acSchristos.Fn resp_searchform , 1929ff1f2acSchristoswrites links to help pages, and calls 1939ff1f2acSchristos.Fn resp_end_html . 1949ff1f2acSchristos.It Ft void Fn pg_error_badrequest "const char *msg" 1959ff1f2acSchristosThis page generator is used when 1969ff1f2acSchristos.Fn main 1979ff1f2acSchristosor 1989ff1f2acSchristos.Fn pg_show 1999ff1f2acSchristosdetect an invalid URI. 2009ff1f2acSchristosIt calls 2019ff1f2acSchristos.Fn resp_begin_html , 2029ff1f2acSchristosprints the 2039ff1f2acSchristos.Fa msg 2049ff1f2acSchristosprovided, and calls 2059ff1f2acSchristos.Fn resp_end_html . 2069ff1f2acSchristos.It Ft void Fn pg_error_internal void 2079ff1f2acSchristosThis page generator is used by various functions when errors are 2089ff1f2acSchristosdetected in the 2099ff1f2acSchristos.Pa manpath.conf 2109ff1f2acSchristosconfiguration file, in 2119ff1f2acSchristos.Xr mandoc.db 5 2129ff1f2acSchristosdatabases, in the 2139ff1f2acSchristos.Xr mandoc 3 2149ff1f2acSchristosparser, in file system permissions, or when setting up timeouts. 2159ff1f2acSchristosIt calls 2169ff1f2acSchristos.Fn resp_begin_html , 2179ff1f2acSchristosprints 2189ff1f2acSchristos.Qq "Internal Server Error" , 2199ff1f2acSchristosand calls 2209ff1f2acSchristos.Fn resp_end_html . 2219ff1f2acSchristosBefore calling 2229ff1f2acSchristos.Fn pg_error_internal , 2239ff1f2acSchristoscall 2249ff1f2acSchristos.Xr warn 3 2259ff1f2acSchristosor 2269ff1f2acSchristos.Xr warnx 3 2279ff1f2acSchristosto log the reason of the error to the 2289ff1f2acSchristos.Xr httpd 8 2299ff1f2acSchristosserver log file. 2309ff1f2acSchristos.El 2319ff1f2acSchristos.Ss Result generators 2329ff1f2acSchristosThe purpose of result generators is to print a chunk of HTML code. 2339ff1f2acSchristosWhen they print untrusted strings or characters, 2349ff1f2acSchristos.Fn html_print 2359ff1f2acSchristosand 2369ff1f2acSchristos.Fn html_putchar 2379ff1f2acSchristosare used. 2389ff1f2acSchristosThe highest level result generators are: 2399ff1f2acSchristos.Bl -tag -width 1n 240*c9bcef03Schristos.It Ft void Fn resp_begin_html "int code" "const char *msg" "const char *file" 2419ff1f2acSchristosThis generator calls 2429ff1f2acSchristos.Fn resp_begin_http 2439ff1f2acSchristosto print the HTTP headers, then prints the HTML header up to the 2449ff1f2acSchristosopening tag of the <body> element, then copies the file 2459ff1f2acSchristos.Pa header.html 2469ff1f2acSchristosto the output, if it exists and is readable. 247*c9bcef03SchristosIf 248*c9bcef03Schristos.Fa file 249*c9bcef03Schristosis not 250*c9bcef03Schristos.Dv NULL , 251*c9bcef03Schristosit is used for the <title> element. 2529ff1f2acSchristos.It Ft void Fn resp_searchform "const struct req *req" "enum focus focus" 2539ff1f2acSchristosThis generator prints a search form, filling it with data 2549ff1f2acSchristosfrom the provided request object. 2559ff1f2acSchristosIf the 2569ff1f2acSchristos.Fa focus 2579ff1f2acSchristosargument is 2589ff1f2acSchristos.Dv FOCUS_QUERY , 2599ff1f2acSchristosit sets the document's autofocus to the query input box. 2609ff1f2acSchristos.It Ft void Fn resp_show "const struct req *req" "const char *file" 2619ff1f2acSchristosThis wrapper dispatches to either 2629ff1f2acSchristos.Fn resp_catman 2639ff1f2acSchristosor 2649ff1f2acSchristos.Fn resp_format , 2659ff1f2acSchristosdepending on whether 2669ff1f2acSchristos.Ar file 2679ff1f2acSchristosstarts with 2689ff1f2acSchristos.Pa cat 2699ff1f2acSchristosor 2709ff1f2acSchristos.Pa man , 2719ff1f2acSchristosrespectively. 2729ff1f2acSchristos.It Ft void Fn resp_catman "const struct req *req" "const char *file" 2739ff1f2acSchristosThis generator translates a preformatted, backspace-encoded manual 2749ff1f2acSchristospage to HTML and prints it to the output. 2759ff1f2acSchristos.It Ft void Fn resp_format "const struct req *req" "const char *file" 2769ff1f2acSchristosThis generator formats a manual page on the standard output, 2779ff1f2acSchristosusing the functions documented in 2789ff1f2acSchristos.Xr mchars_alloc 3 2799ff1f2acSchristosand 2809ff1f2acSchristos.Xr mandoc 3 . 2819ff1f2acSchristos.It Ft void Fn resp_end_html void 2829ff1f2acSchristosThis generator copies the file 2839ff1f2acSchristos.Pa footer.html 2849ff1f2acSchristosto the output, if it exists and is readable, 2859ff1f2acSchristosand closes the <body> and <html> elements. 2869ff1f2acSchristos.El 2879ff1f2acSchristos.Ss Utility routines 2889ff1f2acSchristosThese functions take a string and return 1 if it is valid, or 0 otherwise. 2899ff1f2acSchristos.Bl -tag -width 1n 2909ff1f2acSchristos.It Ft int Fn validate_urifrag "const char *frag" 2919ff1f2acSchristosChecks that the string only contains alphanumeric ASCII characters, 2929ff1f2acSchristosdashes, dots, slashes, and underscores. 2939ff1f2acSchristos.It Ft int Fn validate_manpath "const struct req *req" "const char* manpath" 2949ff1f2acSchristosChecks that the string is either 2959ff1f2acSchristos.Qq mandoc 2969ff1f2acSchristosor one of the manpaths configured in 2979ff1f2acSchristos.Pa manpath.conf . 2989ff1f2acSchristos.It Ft int Fn validate_filename "const char *file" 2999ff1f2acSchristosChecks that the string starts with 3009ff1f2acSchristos.Qq man 3019ff1f2acSchristosor 3029ff1f2acSchristos.Qq cat 3039ff1f2acSchristosand does not ascend to parent directories. 3049ff1f2acSchristos.El 3059ff1f2acSchristos.Sh SEE ALSO 3069ff1f2acSchristos.Xr mandoc 3 , 3079ff1f2acSchristos.Xr mansearch 3 , 3089ff1f2acSchristos.Xr mchars_alloc 3 , 3099ff1f2acSchristos.Xr mandoc.db 5 , 3109ff1f2acSchristos.Xr man.cgi 8 311