home *** CD-ROM | disk | FTP | other *** search
- #! /usr/local/bin/perl
- ##---------------------------------------------------------------------------##
- ## File:
- ## man.cgi
- ## Author:
- ## Earl Hood ehood@convex.com
- ## Description:
- ## man.cgi is a CGI program for viewing Unix manpages. The
- ## program man2html,
- ## <URL:http://www.oac.uci.edu/indiv/ehood/man2html.html>,
- ## is used to convert the output from man(1) to html.
- ##
- ## If man.cgi is invoked with no input data, it will output a
- ## form for the user to select a manpage to view.
- ## man.cgi can handle POST and GET methods.
- ##
- ## The code section "Configureable Globals" is designed to
- ## allow you to modify man.cgi to work with your particular
- ## system configuration.
- ##---------------------------------------------------------------------------##
- ## Copyright (C) 1995 Earl Hood, ehood@convex.com
- ##
- ## This program is free software; you can redistribute it and/or modify
- ## it under the terms of the GNU General Public License as published by
- ## the Free Software Foundation; either version 2 of the License, or
- ## (at your option) any later version.
- ##
- ## This program is distributed in the hope that it will be useful,
- ## but WITHOUT ANY WARRANTY; without even the implied warranty of
- ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ## GNU General Public License for more details.
- ##
- ## You should have received a copy of the GNU General Public License
- ## along with this program; if not, write to the Free Software
- ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ##---------------------------------------------------------------------------##
-
- ########################################################################
- ## Configureable Globals
- ##
- ## Change the value of these variables to reflect your
- ## system configuration.
- ##
- ## English name for program
- $ProgName = "Manpage Viewer";
-
- ## man program
- $ManPrg = '/usr/bin/man';
-
- ## man2html program
- $Man2html = '/usr/local/doctools/bin/man2html';
-
- ## Flag if the -cgiurl option should be used
- $DoCgiurl = 1;
-
- ## System specific arguments to man2html:
- ## HP => "-leftm 1 -topm 8"
- ## Sun => "-sun"
- ## See man2html documentation for more information.
- $ConvArgs = "-leftm 1 -topm 8";
-
- ## Keyword search processing arguments for man2html. Normally,
- ## '-k' is adequate. However, if on a Solaris system, the
- ## '-solaris' option should be specified with '-k'. See
- ## man2html documentation on information about the '-solaris' option.
- $KeyWArgs = "-k"; # Normal
- # $KeyWArgs = "-k -solaris"; # For Solaris
-
- ## Possible manual sections. This array is used to determine the
- ## the choices available in an option menu.
- @Sections = (
- '1', '1M', '2', '3', '3C', '3F', '3X', '4', '5', '6', '7', '8', '9',
- );
-
- ## Form method. The value is either 'GET' or 'POST'. 'GET' is
- ## recommended since the URL sent by the client also contains
- ## the argument information. This allows a client's "Reload" function
- ## to reprocess a currently viewed manpage.
- $FormMethod = 'GET';
-
- ## Argument separator for CGI URL links. As clients become more
- ## SGML conformant, the simple use of '&' conflicts with
- ## SGML syntax. You can set this variable to control what is
- ## used as the separator. Possibilities:
- ## &
- ## &
- ##
- $ArgSep = '&';
-
- ## MANPATH for man
- $ENV{'MANPATH'} = "/usr/man:/usr/contrib/man:/usr/local/man";
-
- ## End Configureable Globals section
- ########################################################################
-
- ########################################################################
- ## Globals
- ########################################################################
- ($PROG = $0) =~ s/.*\///; # Name of program
- %FORM = (); # Array to hold form contents
- $Error = ''; # Error string
-
- ########################################################################
- ## Main block
- {
- # Set unbuffered I/O. Prevents buffering problems with
- # "system()" calls.
- select((select(STDOUT), $| = 1)[0]);
-
- # Print content-type header
- &printouttype("text/html");
-
- # Print man form if called w/no arguments
- &printform() if &noarg();
-
- # If reached here, there is input to process
- &error("CGI input error") unless &parseinput();
- &doit();
- exit 0;
- }
- ########################################################################
- ## Subroutines
- ########################################################################
- #-----------------------------------------------------------------------
- # printform outputs the man selection form to the client.
- #
- sub printform {
- &printhead($ProgName);
- print STDOUT <<EndOfForm;
- <p>The following form allows you to view a manpage on this system.
- Please fill out the following fields and select 'Submit' to view
- a manpage.
- </p>
- <form method="$FormMethod" action="/cgi-bin/man.cgi">
- <p>Section:
- <select name=section>
- <option value="all">All Sections</option>
- <option value="keyword">Keyword Search</option>
- EndOfForm
-
- # Print out possible section choices
- local($section);
- foreach $section (@Sections) {
- print STDOUT qq|<option value="$section">Section $section</option>|;
- }
-
- print STDOUT <<EndOfForm;
- </select>
- </p>
- <p>Topic: <input type="TEXT" name="topic">
- </p>
- <p><input type="SUBMIT" value="Submit">
- </p>
- </form>
- EndOfForm
- &printend();
- exit 0;
- }
- #-----------------------------------------------------------------------
- # doit does the conversion
- #
- sub doit {
- local($section, $topic, $manexec, $htmlexec, $manout);
- $manout = '';
-
- # Get section and topic from input
- $section = $FORM{'section'};
- $topic = $FORM{'topic'};
- &error("Questionable characters in topic") if &isquestionable($topic);
-
- # Determine command arguments for man and man2html
- $manexec = "$ManPrg";
- $htmlexec = "$Man2html";
- if ($section =~ /keyword/) {
- $manexec .= " -k $topic";
- $htmlexec .= qq| $KeyWArgs -title "Keyword search: \\"$topic\\""|;
- } else {
- &error("No topic entered") unless $topic;
- $manexec .= " $section" if $section !~ /all/;
- $manexec .= " $topic";
- $htmlexec .= qq| $ConvArgs -title "$topic($section)"|;
- }
- # Check if doing man xref detection
- if ($DoCgiurl) {
- $htmlexec .= q| -cgiurl '/cgi-bin/man.cgi?| .
- q|section=${section}${subsection}| .
- $ArgSep .
- q|topic=${title}'|;
- }
-
- # Execute man
- if (open(MANPRG, "$manexec 2>/dev/null |")) {
- $/ = 0777;
- $manout = <MANPRG>;
- close(MANPRG);
- } else {
- &error("Unable to execute '$manexec'");
- }
-
- # Convert output from man to html
- if ($manout =~ /^\s*$/) {
- &error("Nothing found for $topic");
- } else {
- if (open(MAN2HTML, "| $htmlexec 2>/dev/null")) {
- print MAN2HTML $manout;
- close(MAN2HTML);
- } else {
- &error("Unable to execute '$htmlexec'");
- }
- }
- }
- ########################################################################
- ## Generic subroutines for CGI use
- ########################################################################
- #-----------------------------------------------------------------------
- # noarg returns true if no arguments were passed to script.
- #
- sub noarg {
- $ENV{"REQUEST_METHOD"} eq "GET" && $ENV{"QUERY_STRING"} =~ /^\s*$/;
- }
- #-----------------------------------------------------------------------
- # parseinput converts the input data into the %FORM array
- #
- sub parseinput {
- local($method) = ($ENV{"REQUEST_METHOD"});
- local($data);
- if ($method eq "GET") {
- $data = $ENV{"QUERY_STRING"};
- } elsif ($method eq "POST") {
- read(STDIN, $data, $ENV{"CONTENT_LENGTH"});
- } else {
- $Error = "Unrecgonized request method : $method";
- return 0;
- }
- local(@pairs, $name, $value);
- if ($data ne '') {
- @pairs = split(/&/, $data);
- foreach (@pairs) {
- ($name, $value) = split(/=/);
- $name = &expandstr($name);
- $value = &expandstr($value);
- $FORM{$name} = $value;
- }
- }
- 1;
- }
- #-----------------------------------------------------------------------
- # printouttype prints out specified content-type header back
- # to client
- #
- sub printouttype {
- local($type) = shift;
- print STDOUT "Content-type: $type\r\n\r\n";
- }
-
- #-----------------------------------------------------------------------
- # printhead outputs html prematter
- #
- sub printhead {
- local($title, $h1) = @_;
- $h1 = $title unless $h1;
-
- print STDOUT <<ENDOFHEAD;
- <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
- <HTML>
- <HEAD>
- <TITLE>$title</TITLE>
- </HEAD>
- <BODY>
- <H1>$h1</H1>
- ENDOFHEAD
- }
-
- #-----------------------------------------------------------------------
- # printend outputs html postmatter
- #
- sub printend {
- print STDOUT <<ENDOFEND;
- </BODY>
- </HTML>
- ENDOFEND
- }
-
- #-----------------------------------------------------------------------
- # error prints an error out to the client.
- #
- sub error {
- local($str) = &htmlize(shift);
- &printhead("$ProgName Error");
- $str .= ":" if $Error && $str;
- $str .= " $Error";
- print STDOUT "<p>$str</p>";
- &printend();
- exit 0;
- }
-
- #-----------------------------------------------------------------------
- # htmlize translates special characters to enitity refs.
- #
- sub htmlize {
- local($str) = shift;
- $str =~ s/&/\&/g;
- $str =~ s/</\</g;
- $str =~ s/>/\>/g;
- $str;
- }
- #-----------------------------------------------------------------------
- # expandstr translates hex codes to characters
- #
- sub expandstr {
- local($str) = shift;
- $str =~ tr/+/ /;
- $str =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/ge;
- $str;
- }
- #-----------------------------------------------------------------------
- # isquestionable determines if $str contains questionable
- # characters if $str is used in a subshell invocation.
- #
- sub isquestionable {
- local($str) = shift;
- $str !~ /^[a-zA-Z0-9_\-+ \t\/@%]+$/;
- }
- ########################################################################
-