#!/usr/bin/perl # # Linux Source Code CGI Browser # Copyright (C) 1995 by Ben Walter # # 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 # 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. # ############################################################################# # C O N F I G U R A T I O N # ############################################################################# @INC = (@INC, '.'); require 'importenv.pl'; require 'navigator.conf'; #$source_root = '/users/b/ben/html/linux/linux/'; # Base directory of Linux ############################################################################# # C G I P A R S I N G # ############################################################################# $QUERY_STRING =~ s/\.\.//g; %prefs = $PATH_INFO =~ /\/(\w+)=([^\/]+)/g; &check_prefs; $QUERY_STRING =~ s/^include\/asm\//include\/asm-$arch\// if $QUERY_STRING =~ /^include\/asm\//; ($this_path) = $QUERY_STRING =~ /(.+)\/\S+$/; ($this_file) = $QUERY_STRING =~ /\/?(\S+)$/; $source = "$source_root/$QUERY_STRING"; $source =~ s/\/$//; $NAVIGATOR_CGI_URL .= $PATH_INFO; sub check_prefs { $arch = $prefs{'arch'}; $arch = $DEFAULT_ARCH if $arch eq ""; $version = $prefs{'ver'}; $version = $DEFAULT_VERSION if $version eq ""; if (! defined($releases{"$version-$arch"} )) { print <<_EOF_; Content-type: text/html Sorry, nothing available

LINUX SOURCE NAVIGATOR

Sorry, there is currently no support for $version-$arch. Please select another combination from the supported list:

_EOF_ foreach(keys %releases) { ($v, $a) = split('-'); print <<_EOF_;

_EOF_ } print <<_EOF_;
Kernel VersionArchitecture
$v$a
_EOF_ exit; } else { ($source_root, $tags) = split(':', $releases{"$version-$arch"}); } } ############################################################################# # A N S I C K E Y W O R D S # ############################################################################# %ansi = ('auto',1, 'break',1, 'case',1, 'char',1, 'const',1, 'continue',1, 'default',1, 'do',1, 'double',1, 'else',1, 'enum',1, 'extern',1, 'float',1, 'for',1, 'goto',1, 'if',1, 'int',1, 'long',1, 'register',1, 'return',1, 'short',1, 'signed',1, 'sizeof',1, 'static',1, 'struct',1, 'switch',1, 'typedef',1, 'union',1, 'unsigned',1, 'void',1, 'volatile',1, 'while',1); sub ansi_token { local($token) = @_; return defined $ansi{$token}; } ############################################################################# # T A G O P E R A T I O N S # ############################################################################# sub load_tags { local($tags_db) = @_; dbmopen(%TAGS, $tags_db, 0444); } sub lookup_token { return $TAGS{$token}; } sub index_tags { local($file) = @_; local(%tags, $what, $where); $what = "/public/html/linux-source/support/ctags -xto /tmp/nav.$$ $file |"; open(CTAGS,$what) || warn "Problem with ctags"; while() { ($what, $where) = /^(\S+)\s+(\d+)/; $tags{$where} = ""; } close(CTAGS); unlink("/tmp/nav.$$"); return(%tags); } ############################################################################# # M I S C # ############################################################################# sub cat { local($file) = @_; open(FILE, $file); print "
\n";
    while() {
	print;
    }
    print "
\n"; } ############################################################################# # D I R E C T O R Y B U I L D I N G # ############################################################################# sub ls { local($dir) = @_; local(@contents, $url, @formatted); opendir(DIR, $source); @contents = sort grep(!/^\./, readdir(DIR)); closedir(DIR); ($url) = $dir =~ /^$source_root\/(\S+)$/; if ($url ne "") { if ($url =~ /\//) { ($up = $url) =~ s/\/[^\/]+$//; } else { $up = ""; } push(@contents, " .."); $url .= "/"; } $url = "$NAVIGATOR_CGI_URL?$url"; print <
TABLE $col = -1; foreach $file (@contents) { if ($col == 0 || $col == 1) { print "\n"; } if ($col++ == 2) { print "\n\n"; $col = 0; } if ($file =~ /..<\/B>/) { print < $file TD next; } $path = "$dir/$file"; if (-d $path) { print < $file TD } else { print < $file TD } } print "
   
\n"; } ############################################################################# # L E X E R # ############################################################################# sub print_header { print < $this_file


EOH
}

sub do_include {
    if (/</) {
	($include) = /<\;(.+)>\;/;
	$url = "$NAVIGATOR_CGI_URL?include/$include";
	$include = "<$include>";
	s/<\;(.+)>\;/$include/;
    } else {
	($include) = /"(.+)"/;
	$url = "$NAVIGATOR_CGI_URL?$this_path/$include";
	$include = "\"$include\"";
	s/"(.+)"/$include/;
    }
}

sub do_directory {
    local($title);
    ($upper_this_file = $this_file) =~ tr/a-z/A-Z/;
    if ($this_file eq "") {
    print <
Linux Source Navigator

LINUX SOURCE NAVIGATOR

HEAD
    } else {
    print <
Directory of $this_file

$upper_this_file

HEAD
    }

    &ls($source);
    if (-e "$source/README") {
#	print "\n

\n\n"; &cat("$source/README"); } } sub count { local ($s, $c) = @_; local ($count); while ($s =~ /$c/g) { $count++; }; return $count; } $comment_count = 0; sub in_comment { local($string, $pos) = @_; local($s); $s = substr($string, 0, $pos); $this_comment_count = (&count($s, '\/\*') - &count($s, '\*\/')); return 1 if ($comment_count + $this_comment_count) gt 0; return 0; } $string_count = 0; sub in_string { local($string, $pos) = @_; local($s); $s = substr($string, 0, $pos); $this_string_count = (&count($s, '\"') - &count($s, '\\\"')); return ($string_count + $this_string_count) % 2; } sub is_literal { local($token) = @_; return 1 if $token =~ /^\d+$/; return 1 if $token =~ /^0x\d+$/; } sub do_c { &load_tags($tags); %tags = &index_tags($source); $line = 0; open(SOURCE, $source); while() { $line++; s//\311/g; s/&/\312/g; if (/^#/) { s/\310/</g; s/\311/>/g; s/\312/&/g; &do_include if /^#include/; chop; print "$_\n"; next; } $pos = $len = 0; foreach $token (/([A-Za-z0-9_]+)/g) { $pos = index($_, $token, $pos); $len = length($token); if (! &in_comment($_, $pos) && ! &in_string($_, $pos)) { if (&ansi_token($token)) { $token = "$token"; } elsif (($where = &lookup_token($token)) ne "") { if ($where eq "__static__") { $token = "$token"; } else { $token = "$token"; } } elsif (&is_literal($token)) { $token = "$token"; } else { # This is yucky $token = "$token" if ($token ne "lt" && $token ne "gt"); } substr($_, $pos, $len) = "$token"; $len = length($token); $pos += $len; } } print $tags{$line} if $tags{$line} ne ""; $comment_count += (&count($_,'\/\*') - &count($_,'\*\/')); $string_count += (&count($_, '\"') - &count($_, '\\\"')); s/\/\*/\/\*/g; s/\*\//\*\/<\/I>/g; s/\310/</g; s/\311/>/g; s/\312/&/g; print; } dbmclose(%TAGS); close(SOURCE); print <<_EOF_;

_EOF_ } ########################################################################### &print_header; if (-d $source) { &do_directory; exit; } elsif ($source =~ /\.[ch]$/) { &do_c; exit; } else { &cat($source); exit; } .