info2www-1.2.2.9.orig/ 40755 0 0 0 6222020535 12362 5ustar rootrootinfo2www-1.2.2.9.orig/ChangeLog100644 0 0 1321 6222020471 14225 0ustar rootrootdescription: GNU Info Node to HTML gateway ---------------------------- revision 1.2 date: 1994/07/28 15:39:38; author: lmdrsm; state: Rel; lines: +456 -140 Updated for general release. ---------------------------- revision 1.1 date: 1994/03/24 19:15:32; author: lmdrsm; state: Rel; lines: +23 -5 branches: 1.1.1; Included automatic reference to the info2www documentation. ---------------------------- revision 1.0 date: 1994/03/24 17:49:15; author: lmdrsm; state: Exp; Initial revision ---------------------------- revision 1.1.1.11 locked by: lmdrsm; date: 1994/07/28 13:00:56; author: lmdrsm; state: Exp; lines: +36 -17 Fixed layout for *note with embedded newline somewhere. ---------------------------- info2www-1.2.2.9.orig/README100644 0 0 1115 6222020471 13334 0ustar rootrootThis is the "info2www" CGI gateway between GNU Info Nodes and the WWW . Everything you need to know should be in the document: info2www.html. Version 1.2, 1994-07-28 ###### Roar Smith, M.Sc.E.E. *** Organization: # Coordination, UNIX Network *** L.M. Ericsson A/S UNIX # Phone: +45 3388 3577 *** Sluseholmen 8 # # FAX: +45 3388 3134 *** DK-1790 Kbenhavn V # # MEMO: ERI.LMD.LMDRSM *** Denmark # Email: lmdrsm@lmd.ericsson.se info2www-1.2.2.9.orig/info2www100755 0 0 101163 6222020450 14225 0ustar rootroot#!/usr/local/bin/perl # # info2www - Gateway between GNU Info nodes and WWW $id = '$Id: info2www,v 1.2.2.9 1996/07/02 08:44:12 lmdrsm Exp $ '; # # This is a script conforming to the CGI - Common Gateway Interface # # Author: Roar Smith (lmdrsm@lmd.ericsson.se) # # Copyright: This program is in the Public Domain. # # The original code (most of &info2html) was written by # Eelco van Asperen (evas@cs.few.eur.nl). # # TODO: # ----- # * Present a list of choices when there is no exact match for the requested # Info file but multiple non-exact matches exist. # # * Use Tag Table to find possible file and offset. # # #----------------- CONFIGURATION ----------------------------------------------- # # # DEBUG should be set if you want to debug what's happening. # $DEBUG = 0; # # DEBUG_PREFIX is prepended to each debug string. # DEBUG_POSTFIX is appended to each debug string. # DEBUG_HTMLIFY should be set if you want to HTML'ify the debug output, # this shouldn't be necessary within comments, but your mileage may vary. # $DEBUG_PREFIX = ""; # Alternative suggestion: "\n" $DEBUG_HTMLIFY = 0; # Alternative suggestion: 1 # # INFOPATH is the path of direcories in which to search for Info node files. # @INFOPATH = ( "/usr/local/gnu/info", "/usr/local/lemacs-19.9/info", "/usr/local/apstools111/external/cygnus/devo/info", # "/sugd/share/gnu/info", "/info/WWW/info2www", "/Web/info2www/sample_info1", "/Web/info2www/sample_info2" ); # # ALLOWPATH specifies whether info files may be specified with path-names # outside of those directories included in INFOPATH . # It is a possible security hole to set this variable to a true value, # because *any* file on the system could then be accessed through this gateway. $ALLOWPATH = 0; # # ALTERNATIVE is a map of alternatives - look for the alternative if the node # itself isn't found. # The key (first entry) is the node filename, the value (second entry) is the # alternative. Both are basenames (i.e. no path!) with no capital letters. # Note that the keys *must* be unique! # %ALTERNATIVE = ( 'emacs', 'lemacs', 'g++', 'gcc', 'c++', 'gcc', 'gunzip', 'gzip', 'zcat' , 'gzip', 'elisp', 'lispref', 'features', 'bash' # Really easy to guess this huh! ); # # Set the PATH so that the ZCAT and GZCAT programs can be found # $ENV{'PATH'} .= ":/usr/local/bin:/usr/local/gnu/bin"; # # ZCAT is the program to use for reading compressed files (*.Z) # GZCAT is the program to use for reading gzip'ped files (*.gz) # Both are arrays to be used in an exec() call, with the first element # being the program (absolute path, or something to be found in PATH) # and any additional elements being options. # # Set either of these to () if you don't want it used. # @ZCAT = ("zcat"); @GZCAT = ("gunzip", "-c"); # # URL of the icons used for indicating references and stuff: # $INFO_ICON - Icon at the top left of each document # $UP_ICON - Icon used in an "Up:" hyperlink at the top # $NEXT_ICON - Icon used in a "Next:" hyperlink at the top # $PREV_ICON - Icon used in a "Prev:" hyperlink at the top # $MENU_ICON - Icon used in front of each menu label # $ALIGN - How to aling the icons # # Set these to "" if you don't want them used. # $INFO_ICON = "/info2www/infodoc.gif"; $UP_ICON = "/info2www/up.gif"; $NEXT_ICON = "/info2www/next.gif"; $PREV_ICON = "/info2www/prev.gif"; $MENU_ICON = "/info2www/menu.gif"; $ALIGN = "BOTTOM"; # # URL for documentation on info2www # # Set this to "" if you don't want it used. # $DOCREF = "/info2www/info2www.html"; # # $INPUTFORM specifies whether to have an input form for going to an Info node. # # Set this to 0 if you don't want it used. # $INPUTFORM = 1; # # CACHE is the dbm(3) or ndbm(3) file for caching lookup information. # Set this to "" if you don't want it used. # The effective user of this script should have write permissions to # the directory in which the dbm files reside, or at least to the files # $CACHE.dir , $CACHE.pag and $CACHE.lock. # $CACHE = "/var/tmp/info2www_cache"; # # Set this to true if you want to lock the lookup-cache dbm(3) files # while updating lookup information. If flock(2) doesn't work on your # system, then set this to false. # You can get a tiny performance increase by unsetting this variable, # but at the cost of risking damage to the dbm files, which could happen # if you get simultaneous update attempts since there is no builtin locking # in dbm - at least not in SunOS 4.x ! # $CACHE_LOCKING = 0; # # These are the defines for file-locking with flock(2) # $LOCK_SH = 1; $LOCK_EX = 2; $LOCK_NB = 4; $LOCK_UN = 8; # #----------------- CONFIGURATION END ------------------------------------------- #----------------- MAIN -------------------------------------------------------- # print "Content-type: text/html\n\n"; # Mime header for NCSA httpd $DEBUG = 1 if (defined $ENV{'DEBUG'}); $DEBUG && &Debug($id); $pg = $0; $pg =~ s,^.*/([^/]*)$,$1,; ($version, $date) = ($id =~ m@,v\s+([0-9.]+)\s+([0-9/]+)@); %CACHE = (); %INPUT = (); $CACHE_OPENED = 0; $NFILES = 0; @INFOPATH = grep(-d, @INFOPATH); # Only search existing directories $SCRIPT_NAME = $ENV{'SCRIPT_NAME'}; $SERVER_NAME = $ENV{'SERVER_NAME'}; $QUERY_STRING = $ENV{'QUERY_STRING'}; $REQUEST_METHOD = $ENV{'REQUEST_METHOD'}; $PREFIX = $SCRIPT_NAME . "?"; # prefix for HREF= entries $DEBUG && &Debug("QUERY_STRING: $QUERY_STRING") if (defined $QUERY_STRING); $DEBUG && &Debug('ARGV: "', join('", "', @ARGV), '"') if @ARGV; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $request, $ENV{'CONTENT_LENGTH'}); $DEBUG && &Debug("POST: $request"); } elsif ($ENV{'REQUEST_METHOD'} eq "GET" ) { if ($QUERY_STRING) { $request = $QUERY_STRING; } } if ($request) { # The argument string is encoded in %XX format and must be decoded, but not # until split up into key=value pairs: file=gcc&node=Invoking%20GCC if ($request =~ /=/) { # Form created key=value pairs %request = &UrlDecode(split(/[&=]/, $request)); if (!defined $request{'debug'}) { # Do nothing } elsif ($request{'debug'} =~ /^Y(es)?$|^On$|^True$/i) { $DEBUG = 1; &Debug("debug=$request{'debug'}\nDEBUG enabled!"); &Debug($id); &Debug("QUERY_STRING: $QUERY_STRING") if (defined $QUERY_STRING); &Debug('ARGV: "', join('", "', @ARGV), '"') if @ARGV; } elsif ($request{'debug'} =~ /N(o)?$|^Off$|^False$|^$/i) { $DEBUG && &Debug("debug=$request{'debug'}\nIgnored!"); } else { $DEBUG = 1; &Debug("debug=$request{'debug'}\nSay what???\nDEBUG enabled!"); &Debug($id); &Debug("QUERY_STRING: $QUERY_STRING") if (defined $QUERY_STRING); &Debug('ARGV: "', join('", "', @ARGV), '"') if @ARGV; } if ($nodename = ($request{'query'} || $request{'isindex'})) { if ($nodename !~ /^\(/ && $request{'file'}) { $nodename = "(".$request{'file'}.")".$nodename; } } elsif ($request{'file'}) { $nodename = "(".$request{'file'}.")".$request{'node'}; } else { $nodename = "(dir)"; } } else { # Simple request for a node $nodename = &UrlDecode($request); } } elsif (@ARGV) { # The argument string is already decoded, bet special characters are # backslash escaped: \(gcc\)Invoking\ GCC ($nodename = join('+', @ARGV)) =~ s/\\(\W)/$1/g;; } else { $nodename = "(dir)"; } $nodename = "(dir)" unless $nodename; $nodename = "(".$nodename unless ($nodename =~ /^\(/); $nodename = $nodename.")" unless ($nodename =~ /\)/); $DEBUG && &Debug("Nodename: $nodename\n"); &info2html($nodename); if ($DOCREF) { print "
\n", "automatically generated by ", "$pg", " version $version\n"; } else { print "
\n", "automatically generated by ", "$pg", " version $version\n"; } exit(0); #----------------- SUBROUTINES ------------------------------------------------- # # Handle request for one info-node sub info2html { local($node) = @_; local($file, $node_file, $node_name, $fullnode, $link, $linkh, $h_file); local($directory, $basefile, $handle, $pos, $entrypos); local($cachedfile, $cachedpos); local($info_img, $cache, $orglen, $regexp, $menu, $end, $listing, $active); local($matches, $blank, $lastblank, $seenMenu, $indirect, $inentry); $info_img = "\"\" " if $INFO_ICON; # Nodename looks like one of these: # (file)label - Both file and label of the Info node given # (file) - Label defaults to "Top" # - File defaults to "dir", Label defaults to "Top" if ($node =~ /^\(([^\)]*)\)(.+)$/) { ($node_file, $node_name) = ($1, $2); } elsif ($node =~ /^\(([^\)]*)\)$/) { ($node_file, $node_name) = ($1, "Top"); } elsif (!$node) { ($node_file, $node_name) = ("dir", "Top"); } else { &Error("Malformed node: $node"); return(&info2html("(dir)Top")); } $fullnode = "($node_file)$node_name"; ($target = $node_name) =~ tr/A-Z/a-z/; ($regexp = $target) =~ s/(\W)/\\$1/g; # Escape special characters $DEBUG && &Debug("Nodename: $node\nfile: $node_file\ntarget: $target"); ($file, $pos) = &TryCache("($node_file)$target", $regexp) if $CACHE; if ($file) { $cachedfile = $file; $cachedpos = $pos; ($directory, $basefile) = ($cachedfile =~ m|(.*)/([^/]*)$|); } else { ($directory, $basefile) = &FindFile($node_file); unless ($basefile) { &Error("Couldn't find Info file \"$node_file\"."); &UpdateCache(); return(($fullnode =~ /^\(dir\)(Top)?$/i) || &info2html("(dir)Top")); } $file = "$directory/$basefile"; $pos = 0; unless ($file = &OpenFile($file)) { &Error("Couldn't open Info file \"$node_file\"."); &UpdateCache(); return(($fullnode =~ /^\(dir\)(Top)?$/i) || &info2html("(dir)Top")); } } # Figure out what file to specify in links to other targets within same file $link = $node_file; # This seems to be the safest choice $linkh = &HTMLify($link); # HTML'ified $link FileLoop: while ($NFILES > 0) { $handle = $file; $DEBUG && &Debug("Now reading from $handle"); while ($_ = (shift @INPUT || scalar(<$handle>))) { $orglen = length($_); chop; #study; # study actually seems to hurt! /^[\037\f]/ && do { if ($active) { print "\n" if $menu; $menu = 0; # End menu print "\n" if $listing; $listing = 0; # End text close($handle); $DEBUG && &Debug("Closed file $handle"); last FileLoop; } $active = 0; $seenMenu = 0; $indirect = 0; $inentry = 1; $entrypos = $pos; next; }; next unless $inentry; ($inentry == 1) && do { local($h_node, $h_next, $h_prev, $h_up); local($n) = 0; /^tag table:/i && do { # we don't use the tag table $inentry = 0; next; }; /^indirect:/i && do { # this entry is a list of filenames to include: # # gcc.info-1: 1131 # gcc.info-2: 49880 # gcc.info-3: 99426 $inentry++; $indirect++; next; }; # top line: # File: info, Node: Add, Up: Top, Prev: Expert, Next: Menus # # Parse the header line. If one of the fields # Node: Up: Next: Previous: File: # is found, then a variable 'h_node' is set for # the field 'node:', 'h_next' for 'next:', etc. # /\bNode: *([^,\t]*)/i && ($h_node = $1) =~ s/\s+$//; /\bUp: *([^,\t]*)/i && ($h_up = $1) =~ s/\s+$//; /\bPrev: *([^,\t]*)/i && ($h_prev = $1) =~ s/\s+$//; /\bPrevious: *([^,\t]*)/i && ($h_prev = $1) =~ s/\s+$//; /\bNext: *([^,\t]*)/i && ($h_next = $1) =~ s/\s+$//; if ($h_node =~ m/^$regexp$/i) { $active = 1; $matches++; /\bFile: *([^ ,\t]*)/i && ($h_file = $1); $h_file = $node_file unless $h_file; # Update cache if necessary if ($CACHE && (($cachedfile ne $file) || ($cachedpos ne $entrypos))) { $CACHE{"($node_file)$target"} = "$entrypos\0$file"; } print "Info Node: ", &HTMLify("($h_file)$h_node"), "\n", "

", "$info_img", &HTMLify("($h_file)$h_node"), "

\n"; print "
\n" if $INPUTFORM; print "
\n"; if (defined $h_next) { $h_next = &HTMLify($h_next); print "Next: ", &Anchor($linkh, $h_next, $h_next, $NEXT_ICON, 1), " "; $n++; } if (defined $h_prev) { $h_prev = &HTMLify($h_prev); print "Prev: ", &Anchor($linkh, $h_prev, $h_prev, $PREV_ICON, 1), " "; $n++; } if (defined $h_up) { $h_up = &HTMLify($h_up); print "Up: ", &Anchor($linkh, $h_up, $h_up, $UP_ICON, 1), " "; $n++; } print "
\n"; print("", "", " ", "Enter node , (file) ", "or (file)node\n") if $INPUTFORM; print "
\n" if $INPUTFORM; print "
\n" unless $listing; $listing = 1; # Start text
		} elsif ($CACHE) {
		    $CACHE{"($node_file)\L$h_node"} = "$entrypos\0$file";
		}
		$inentry++;
		next;
	    };

	    ($inentry == 2 && $indirect) && do  {
		# each line of this entry consists of two fields,
		# a filename and an offset, separated by a colon.
		# For example:
		#	texinfo-1: 1077
		local($includefile, $offset) = split(/:/);
		unless ($includefile =~ /^\//) {
			$includefile = "$directory/$includefile";
		}
		$DEBUG && &Debug("#include $includefile");
		# should save: $inentry $indirect $pos
		push(@inentry, $inentry);
		push(@indirect, $indirect);
		push(@pos, $pos);
		push(@file, $file);
		$inentry = 0;
		$indirect = 0;
		$pos = 0;
		($file = &OpenFile($includefile)) || return(0);
		next FileLoop;
	    };

	    next unless $active;
	    $_ = &HTMLify($_) if /[<>&]/; # Test added for performance reasons
	    #study;			# study actually seems to hurt!
	    
	    $lastblank = $blank; $blank = 0;
	    /^$/ && do {
		print "\n";
		$blank = 1;
		next;
	    };

	    if (($end) = /^\*\s+Menu:(.*)$/) {
		# start of a menu:
		$seenMenu = 1;
		print "
\n" if $listing; $listing = 0; # End text print "$end"; print "\n
" unless $menu; $menu = 1; # Start menu next; }; /^\*/ && do { #---- SAMPLE LINES: ----------------------------------------- # * Sample::. Sample info. # # * Info: (info). Documentation browsing system. # # * Bison: (bison/bison) # A Parser generator in the same style as yacc. # * Random: (Random) Random Random Number Generator #------------------------------------------------------------ if ($menu == 0 && $seenMenu) { print "\n" if $listing; $listing = 0; # End text print "\n
" unless $menu; $menu = 1; # Start menu } # * foo:: /^\*\s+([^:]+)::/ && do { $rest_of_line = $'; print "
", &Anchor($linkh, $1, $1, $MENU_ICON), "
"; $rest_of_line =~ s/^[\s\.]+//; print $rest_of_line, "\n"; next; }; # * foo: (bar)beer OR (bar) /^\*\s+([^:]+):\s*\(([^\) \t\n]+)\)([^\t\n\.,]*)/ && do { $rest_of_line = $'; print "
", &Anchor($linkh, "($2)$3",$1, $MENU_ICON), "
"; $rest_of_line =~ s/^[\s\.]+//; print $rest_of_line, "\n"; next; }; # * foo: beer. /^\*\s+([^:]+):\s*([^\t,\n\.]+)/ && do { $rest_of_line = $'; print "
", &Anchor($linkh, $2, $1, $MENU_ICON), "
", $2, ". "; $rest_of_line =~ s/^[\s\.]+//; print $rest_of_line, "\n"; next; }; # no match: ignore silently }; $menu && $lastblank && do { print "
\n" if $menu; $menu = 0; # End menu print "
\n" unless $listing; $listing = 1; # Start text
	    };

	    $menu && do {
		s/^\s+//;
	    };

	    /\*note/i && do {
		# cross reference entry:
		# "*note nodename::."
		# "*note Cross-reference-name: nodename."
		local($n) = 0;
		# There can be multiple notes in a line, so find them all...
		while (1) {
		    # *note \nfoo... (reference split over newline)
		    # *note foo\nbar... (reference split over newline)
		    # *note foo: bar\nbleh... (reference split over newline)
		    if (/\*note\s*$/i ||
			/\*note\s+[^:\.]+$/i ||
			/\*note\s+[^:\.]+:\s+[^:\.\t]+$/i) {
			# Merge with next line
			local($line) = scalar(<$handle>);
			$pos += length($line);
			chop($line);
			$_ .= "\n" . &HTMLify($line);
		    }
		    # *note foo:
		    if (/\*note(\s+)([^:\.]+)::/i) {
			s//:=:NOTE:=:/;	# insert unique (I hope) marker
			local($spc, $ref, $lbl) = ($1, $2, $2);
			local($note) = "Note:$spc";
			$note .= &Anchor($linkh, $ref, $lbl);
			s/:=:NOTE:=:/$note/;
			$n++;
			next;
		    }

		    # * foo: (bar)beer OR (bar)
		    if (/\*note(\s+)([^:]+):\s+\(([^\)\s]+)\)([^\t.,]*)(.?)/i) {
			s//:=:NOTE:=:/;	# insert unique (I hope) marker
			local($spc, $ref, $lbl) = ($1, "($3)$4", "$2$5");
			local($nl) = ($ref =~ /\n/) ? "\n" : "";
			local($note) = "Note:$spc";
			$note .= &Anchor($linkh, $ref, $lbl);
			s/:=:NOTE:=:/$note$nl/;
			$n++;
			next;
		    }

		    # * foo: beer.
		    if (/\*note(\s+)([^:]+):\s+([^\t,\.]+)(.?)/i) {
			s//:=:NOTE:=:/;	# insert unique (I hope) marker
			local($spc, $ref, $lbl) = ($1, $3, "$2$4");
			local($nl) = ($ref =~ /\n/) ? "\n" : "";
			local($note) = "Note:$spc";
			$note .= &Anchor($linkh, $ref, $lbl);
			s/:=:NOTE:=:/$note$nl/;
			$n++;
			next;
		    }

		    last;
		}
	    };

	    print "$_\n";
	} continue {
	    $pos += $orglen unless $active;
	}
	print "
\n" if $menu; $menu = 0; # End menu # clear status variables; $active = 0; $seenMenu = 0; $indirect = 0; $inentry = 0; $lastblank = 0; $DEBUG && &Debug("End of file $handle"); close($handle); $NFILES--; $DEBUG && &Debug("Closed file $handle"); $inentry = pop(@inentry); $indirect = pop(@indirect); $pos = pop(@pos); $file = pop(@file); last if $matches; } while ($file = pop(@file)) { $handle = $file; close($handle); $NFILES--; $DEBUG && &Debug("Closed file $handle"); $inentry = pop(@inentry); # Not really necessary $indirect = pop(@indirect); # Not really ncessary $pos = pop(@pos); # Not really necessary } unless ($matches) { &Error("Couldn't find target: \"$node_name\" in file \"$node_file\"."); if ($CACHE && $cachedfile) { $CACHE{"($node_file)$target"} = undef; if ($cachedpos eq "0") { $CACHE{"($node_file)"} = undef; } } &UpdateCache(); return(($fullnode =~ /\)Top$/i) || &info2html("($node_file)Top")); } &UpdateCache(); return($matches); } #--------------------------------------------------------------------------- sub UrlDecode { # Decode a URL encoded string or array of strings # 1. Change "+" to space, since FORMS change space to "+" # 2. Change "%XX" to character with hex value "XX" foreach (@_) { tr/+/ /; s/%(..)/pack("c",hex($1))/ge; } wantarray ? @_ : $_[$[]; } sub Anchor { local($link, $ref, $label, $icon, $iconlink) = @_; local($file, $name, $img, $href); $DEBUG && &Debug("Anchor($link, $ref, $label)"); # (foo)bar if ($ref =~ m/^\(([^\)]+)\)\s*([^\t,\.]*)/) { $file = $1; $name = $2; } elsif ($link =~ /^dir$|\/dir$/i) { $DEBUG && &Debug("(dir) node - Menu \"$ref\" means \"($ref)\""); $file = $ref; $name = ""; } else { $file = $link; $name = $ref; } $name =~ s/\s+$//; # Strip trailing blanks $href = "($file)$name"; # Escape special characters in URL to %XX form. # Since encoding is done to %XX form we must first encode "%" itself. # The HTML special characters "<", ">" and "&" are already HTML'ified to # "<", ">" and "&" so we must *not* further encode "&" here, # but for good measure we can encode any "<" and ">" that slip through... $href =~ s/%/%25/g; # % $href =~ s/([<>\#\+\?\=\"\\])/sprintf("%%%X",ord($1))/ge; $href =~ s/\s+/+/g; # Encode multiple blanks as a "+" encoded space $href = "$PREFIX$href"; if ($icon) { $img = "\"\*\" "; } if ($iconlink) { return "$img$label"; } else { return "$img$label"; } } sub HTMLify { local($_) = @_; s/&/&\;/g; s//>\;/g; $_; } sub FindFile { local($orgname) = @_; local($name) = $orgname; local($dir, $fil); $DEBUG && &Debug("FindFile: \"$name\""); ($dir, $fil) = &FindFileNoAlt($name); if ($dir) { $CACHE{"($orgname)"} = "0\0$dir/$fil" unless ($orgname =~ /\//); return($dir, $fil); } # Try a possible alternative... $fil = $name; $fil =~ s/[-\.]info$//; $fil =~ tr/A-Z/a-z/; $name = $ALTERNATIVE{$fil}; $DEBUG && &Debug("\$ALTERNATIVE{$fil} = $name"); return(undef) unless $name; $DEBUG && &Debug("Trying with the alternative \"$name\"..."); ($dir, $fil) = &FindFileNoAlt($name); if ($dir) { $CACHE{"($orgname)"} = "0\0$dir/$fil" unless ($orgname =~ /\//); $CACHE{"($name)"} = "0\0$dir/$fil" unless ($name =~ /\//); return($dir, $fil); } else { return(undef); } } sub FindFileNoAlt { local($name) = @_; local($aname) = $name; local(@list); local($dir, $fil); local($regexp, $aregexp); $aname =~ s/\.gz$|\.Z$//; if ($aname =~ /\.info$/) { $aname =~ s/\.info$//; } elsif ($aname =~ /-info$/) { $aname =~ s/-info$/.info/; } else { $aname =~ s/$/.info/; } $DEBUG && &Debug("FindFileNoAlt: \"$name\", Alt=\"$aname\""); ($regexp = $name) =~ s/(\W)/\\$1/g; # Escape special characters if ($name =~ /\.gz$|\.Z$/) { # Don't add gzip'ped and compress file to the regular expression } elsif (@GZCAT && @ZCAT) { $regexp .= "(\\.gz|\\.Z)?"; } elsif (@GZCAT) { $regexp .= "(\\.gz)?"; } elsif (@ZCAT) { $regexp .= "(\\.Z)?"; } ($aregexp = $aname) =~ s/(\W)/\\$1/g; # Escape special characters if (@GZCAT && @ZCAT) { $aregexp .= "(\\.gz|\\.Z)?"; } elsif (@GZCAT) { $aregexp .= "(\\.gz)?"; } elsif (@ZCAT) { $aregexp .= "(\\.Z)?"; } $DEBUG && &Debug("\$regexp=/$regexp/ \$aregexp=/$aregexp/"); # Try absolute match for $name... if ($name =~ /\//) { ($dir, $fil) = ($name =~ m|(.*)/([^/]*)$|); if ($ALLOWPATH || grep($_ eq $dir, @INFOPATH)) { @list = ($name); push(@list, "$name.gz") if (@GZCAT && !$name =~ /\.gz$|\.Z$/); push(@list, "$name.Z") if (@ZCAT && !$name =~ /\.gz$|\.Z$/); push(@list, $aname); push(@list, "$aname.gz") if (@GZCAT && !$aname =~ /\.gz$|\.Z$/); push(@list, "$aname.Z") if (@ZCAT && !$aname =~ /\.gz$|\.Z$/); foreach (@list) { $DEBUG && &Debug("Trying absolute match for \"$_\"..."); if (-e $_) { ($dir, $fil) = ($_ =~ m|(.*)/([^/]*)$|); return($dir, $fil); } } # Remove path component $name =~ s,^.*/([^/]*)$,$1,; $aname =~ s,^.*/([^/]*)$,$1,; $DEBUG && &Debug("Stripped path from filename: $name"); } elsif (!$ALLOWPATH) { $DEBUG && &Debug("Warning: Absolute path-names not allowed!"); $name =~ s,^.*/([^/]*)$,$1,; $aname =~ s,^.*/([^/]*)$,$1,; $DEBUG && &Debug("Stripped path from filename: $name"); } } # Try exact match for $name in all directories... $DEBUG && &Debug("Trying exact match for \"$name\"..."); foreach $dir (@INFOPATH) { @list = ("$dir/$name"); push(@list, "$dir/$name.gz") if (@GZCAT && !$name =~ /\.gz$|\.Z$/); push(@list, "$dir/$name.Z") if (@ZCAT && !$name =~ /\.gz$|\.Z$/); foreach (@list) { $DEBUG && &Debug("Trying exact match for \"$_\"..."); if (-e $_) { ($dir, $fil) = ($_ =~ m|(.*)/([^/]*)$|); return($dir, $fil); } } } # Try exact match for $aname in all directories... $DEBUG && &Debug("Trying exact match for \"$aname\"..."); foreach $dir (@INFOPATH) { @list = ("$dir/$aname"); push(@list, "$dir/$aname.gz") if (@GZCAT && !$aname =~ /\.gz$|\.Z$/); push(@list, "$dir/$aname.Z") if (@ZCAT && !$aname =~ /\.gz$|\.Z$/); foreach (@list) { $DEBUG && &Debug("Trying exact match for \"$_\"..."); if (-e $_) { ($dir, $fil) = ($_ =~ m|(.*)/([^/]*)$|); return($dir, $fil); } } } # Try caseless match for $name in all directories... $DEBUG && &Debug("Trying caseless match for \"$name\"..."); @list = (); foreach $dir (@INFOPATH) { opendir(DIR, $dir); push (@list, grep(s/^/$dir\//, sort grep(/^$regexp$/i, readdir(DIR)))); closedir(DIR); } if ($#list > 0) { # One or more matches, return first match ($dir, $fil) = ($list[0] =~ m|(.*)/([^/]*)$|); return($dir, $fil); } elsif ($#list == 0) { # No matches ($dir, $fil) = ($list[0] =~ m|(.*)/([^/]*)$|); return($dir, $fil); } # Try caseless match for $aname in all directories... $DEBUG && &Debug("Trying caseless match for \"$aname\"..."); @list = (); foreach $dir (@INFOPATH) { opendir(DIR, $dir); push (@list, grep(s/^/$dir\//, sort grep(/^$aregexp$/i, readdir(DIR)))); closedir(DIR); } if ($#list > 0) { # One or more matches, return first match ($dir, $fil) = ($list[0] =~ m|(.*)/([^/]*)$|); return($dir, $fil); } elsif ($#list == 0) { # No matches ($dir, $fil) = ($list[0] =~ m|(.*)/([^/]*)$|); return($dir, $fil); } # Bummer - no matches at all return(undef); } sub OpenFile { local($filename) = @_; local($handle, $pid, $file, $directory); if ($filename =~ /\//) { ($directory, $filename) = ($filename =~ m|(.*)/([^/]*)$|); } $file = "$directory/$filename"; unless (-f $file) { if (@GZCAT && -f "$file.gz") { $filename .= ".gz"; $file .= ".gz"; } elsif (@ZCAT && -f "$file.Z") { $filename .= ".Z"; $file .= ".Z"; } else { $DEBUG && &Debug("No such file: $file"); return(undef); } } $DEBUG && &Debug("Trying to open file \"$file\"..."); $handle = $file; if ($filename =~ /\.gz$/) { if (@GZCAT) { select((select(STDOUT), $| = 1)[0]); # Non-buffered STDOUT select((select(STDERR), $| = 1)[0]); # Non-buffered STDERR $pid = open($handle, "-|"); if ($pid) { # This is the parent! $NFILES++; $DEBUG && &Debug("Opened pipe: @GZCAT $file |"); return($file); } elsif (defined $pid) { # This is the child! exec(@GZCAT, $file) || die "Could not exec: $!\n"; } else { # Pipe failed! $DEBUG && &Debug("Could not open pipe: $!"); return(undef); } } else { $DEBUG && &Debug("Cannot use gzip'ped file: $file"); return(undef); } } elsif ($filename =~ /\.Z$/) { if (@ZCAT) { select((select(STDOUT), $| = 1)[0]); # Non-buffered STDOUT select((select(STDERR), $| = 1)[0]); # Non-buffered STDERR $pid = open($handle, "-|"); if ($pid) { # This is the parent! $NFILES++; $DEBUG && &Debug("Opened pipe: @ZCAT $file |"); return($file); } elsif (defined $pid) { # This is the child! exec(@ZCAT, $file) || die "Could not exec: $!\n"; } else { # Pipe failed! $DEBUG && &Debug("Could not open pipe: $!"); return(undef); } } else { $DEBUG && &Debug("Cannot use compressed file: $file"); return(undef); } } else { # Not a compressed or gzip'ped file if (open($handle, $file)) { $NFILES++; $DEBUG && &Debug("Opened file \"$file\""); return($file); } else { $DEBUG && &Debug("Could not open file: $!"); return(undef); } } } # Try to lookup the file and position of the node in the cache sub TryCache { local($cachekey, $regexp) = @_; local($handle, $line, $h_node, $pos, $dummy); local($cachevalue, $cachedpos, $cachedfile, $cachedir, $newkey, $file); undef @INPUT; $DEBUG && &Debug("Trying cached entry for \"$cachekey\"..."); if ($CACHE) { unless ($CACHE_OPENED) { if (eval 'dbmopen(%cache, $CACHE, 0644) || die "$!\n"') { $CACHE_OPENED = 1; } else { $DEBUG && &Debug("Couldn't open cache: $@"); undef $CACHE; } } if ($CACHE_OPENED) { $cachevalue = $cache{$cachekey}; } else { undef $CACHE; return(undef); } } else { undef $CACHE; return(undef); } if (!$cachevalue) { if ($cachekey =~ m,\(.*/.*\).*,) { # Remove path and try again ($newkey = $cachekey) =~ s,^\([^\)]*/([^/\)]*)\),($1),; $DEBUG && &Debug("New key: $newkey"); return(&TryCache($newkey, $regexp)); } elsif ($regexp && ($cachekey =~ /^\([^\)]*\).+/)) { # Remove target and try again ($newkey = $cachekey) =~ s,^\(([^\)]*)\).*,($1),; $DEBUG && &Debug("New key: $newkey"); return(&TryCache($newkey, undef)); } else { $DEBUG && &Debug("Cached entry not found!"); return(undef); } } ($cachedpos, $cachedfile) = split("\0", $cachevalue); $DEBUG && &Debug("Cached entry found: pos=$cachedpos in \"$cachedfile\""); if ($cachedfile =~ /\//) { ($cachedir = $cachedfile) =~ s,(.*)/[^/]*$,$1,; if (!$ALLOWPATH && !grep($_ eq $cachedir, @INFOPATH)) { $DEBUG && &Debug("Warning: Absolute path-names not allowed!"); $CACHE{$cachekey} = undef; return(undef); } } if ($cachedpos < 0) { $DEBUG && &Debug("Warning: Negative cached position ignored!"); $cachedpos = 0; $CACHE{$cachekey} = undef; } unless ($file = &OpenFile($cachedfile)) { $CACHE{$cachekey} = undef; return(undef); } if ($file ne $cachedfile) { $CACHE{$cachekey} = "$cachedpos\0$file"; } $handle = $file; $DEBUG && &Debug("Now reading from $handle"); # Seek forward to the cached position by using seek() or read() # Note that seek() will not work with a pipe! unless (seek($handle, $cachedpos, 0) || (read($handle, $dummy, $cachedpos) == $cachedpos)) { close($handle); $NFILES--; $CACHE{$cachekey} = undef; return(undef); } undef $dummy; $DEBUG && &Debug("Position: $cachedpos"); unless ($regexp) { return($file, $pos); } if ($line = <$handle>) { push(@INPUT, $line); # Save line for later chop($line); $DEBUG && &Debug("line: [$line]"); if ($line =~ /^[\037\f]/) { $DEBUG && &Debug("Found node start"); if ($line = <$handle>) { push(@INPUT, $line); # Save line for later chop($line); $DEBUG && &Debug("line: [$line]"); if ($line =~ /\bnode: *([^,\t]*)/i) { $h_node = $1; $h_node =~ s/\s+$//; # delete trailing spaces if ($h_node =~ m/^$regexp$/i) { $DEBUG && &Debug("Found the node!"); $pos = $cachedpos; return($file, $pos); } } } } } undef @INPUT; undef $pos; $CACHE{$cachekey} = undef; close($handle); return(undef); } # Update the cache lookup DBM database with any saved entries in %CACHE sub UpdateCache { local($key, $value, $pos, $file); if ($CACHE && %CACHE && &LockCache()) { unless ($CACHE_OPENED) { if (eval 'dbmopen(%cache, $CACHE, 0644) || die "$!\n"') { $CACHE_OPENED = 1; } else { $DEBUG && &Debug("Couldn't open cache: $@"); undef $CACHE; } } if ($CACHE_OPENED) { while (($key, $value) = each %CACHE) { if (defined $value) { $cache{$key} = $value; if ($DEBUG) { ($pos, $file) = split("\0", $value); &Debug("cache{$key} set to: pos=$pos in \"$file\""); } } else { delete $cache{$key}; $DEBUG && &Debug("cache{$key} deleted"); } } undef %CACHE; eval 'dbmclose(%cache) || die "$!\n'; $CACHE_OPENED = 0; &UnLockCache(); return(1); } else { $DEBUG && &Debug("Couldn't open DBM file: $!"); undef $CACHE; &UnLockCache(); return(0); } } else { undef $CACHE; return(0); } } # Lock the lookup cache DBM database # # See the dbm(3) manual page. Here is an excerpt from dbm(3) on SunOS 4.1.3: # # BUGS # ... # There are no interlocks and no reliable cache flushing; thus # concurrent updating and reading is risky. # sub LockCache { return(1) unless $CACHE_LOCKING; # Just fake it unless cache locking is used local($file) = $CACHE . ".lock"; unless (open(LOCKFILE, ">$file")) { $DEBUG && &Debug("Couldn't open CACHE lockfile \"$file\": $!"); return(0); } unless (eval 'flock(LOCKFILE, $LOCK_EX) || die "$!\n"') { $DEBUG && &Debug("Couldn't lock CACHE lockfile \"$file\": $@"); close(LOCKFILE); return(0); } $DEBUG && &Debug("Locked CACHE lockfile \"$file\""); return(1); } # Unlock the cache lookup DBM database sub UnLockCache { return(1) unless $CACHE_LOCKING; # Just fake it unless cache locking is used local($file) = $CACHE . ".lock"; unless (eval 'flock(LOCKFILE, $LOCK_UN) || die "$!\n"') { $DEBUG && &Debug("Couldn't unlock CACHE lockfile \"$file\": $@"); close(LOCKFILE); return(0); } close(LOCKFILE); $DEBUG && &Debug("Unlocked CACHE lockfile \"$file\""); return(1); } # Print an HTML error message sub Error { local($reason) = @_; print "Sorry! - $reason\n

\n"; return(0); } # Print debug information if debugging is enabled sub Debug { # Print out text if debugging enabled if ($DEBUG) { print $DEBUG_PREFIX; if ($DEBUG_HTMLIFY) { foreach (@_) { print &HTMLify($_); } } else { print @_; } print $DEBUG_POSTFIX; } } __END__ info2www-1.2.2.9.orig/info2www.html100644 0 0 6100 6222020471 15123 0ustar rootroot info2www - The GNU Info Node to HTML Gateway

info2www - The GNU Info Node to HTML Gateway

Copyright: This program is in the Public Domain.

Latest version is 1.2 - see the ChangeLog for more information.

The info2www script makes your CGI compliant HTTP/1.0 or later server a gateway to all that information you have "stacked away" in the GNU Info Nodes (you know - the Info Nodes accessible from Emacs).

The Info Nodes are parsed and formatted on the fly by info2www and presents hyperlinks to other Info Nodes that your WWW browser can use (hopefully).

Configuration and installation

The following steps are necessary for getting info2www up and running:

  1. Make sure that Perl is installed on your system
  2. Choose a directory under your DocumentRoot directory, e.g. DocumentRoot/info2www for keeping the info2www files in.
  3. Create this directory and "cd" into it.
  4. Extract the tar-file info2www-1.2.tar.Z in this directory
  5. Edit the info2www script and make the following changes:
  6. Copy or make a link of info2www to your CGI script directory - e.g. DocumentRoot/cgi-bin .
  7. Include hyperlinks to the info2www CGI interface wherever you want in your other hypertext documents.

Using info2www

The info2www script should be called with 0 or 1 argument as follows:
<A HREF="http://yourserver/your-cgi-dir/info2www"> Directory</A>
Access the default Info Node (DIR)Top

<A HREF="http://yourserver/your-cgi-dir/info2www?(w3)"> W3</A>
Access the Info Node (w3)Top

<A HREF="http://yourserver/your-cgi-dir/info2www?(gzip)Concept%20Index"> GZIP Concept Index</A>
Access the Info Node (gzip)Concept%20Index

Enjoy!
Roar Smith <lmdrsm@lmd.ericsson.se>
info2www-1.2.2.9.orig/infodoc.gif100644 0 0 241 6222020471 14543 0ustar rootrootGIF89a !, ry T`q58僎iRƒrb)F /!+vFE!(NJjT`XbNdZ zҾw1=)Dd7çw(׸X;info2www-1.2.2.9.orig/menu.gif100644 0 0 142 6222020471 14066 0ustar rootrootGIF89a!,9S4u]m/Z$`jNhvyF-t@ ;info2www-1.2.2.9.orig/next.gif100644 0 0 125 6222020471 14101 0ustar rootrootGIF87a,4ڋiwl!Ȕʡ NyJy>L*;info2www-1.2.2.9.orig/prev.gif100644 0 0 123 6222020471 14075 0ustar rootrootGIF87a,2ڋ iwxdx:ۆr3"Ģ;info2www-1.2.2.9.orig/up.gif100644 0 0 115 6222020471 13546 0ustar rootrootGIF87a,,TP}_%SYF(Lqf %;