1#!/usr/bin/perl
2
3# WebCscope: A web interface to the cscope application
4# Copyright (C) 2001, Ragho Mahalingam <ragho@mahalingam.com>
5#
6# This program is free software; you can redistribute it and/or
7# modify it under the terms of the GNU Lesser General Public
8# License as published by the Free Software Foundation; either
9# version 2.1 of the License, or (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14# General Public License for more details.
15#
16# You should have received a copy of the GNU General Public
17# License along with this program; if not, write to the Free Software
18# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19#
20# Change History:
21#
22# $Log: cscope,v $
23#
24# Revision 1.3.4.1  2001/02/05 15:14:34  rmahalin
25# initial release with some bug fixes
26#
27# Revision 1.3.3.1  2001/01/22 22:21:23  rmahalin
28# added multi-database support
29# fixed cookie support for trivial functions; removed global trivials
30# added syntax highlighting for files displayed on browser
31#
32# Revision 1.3.1.1  2001/01/11 22:17:30  rmahalin
33# added direct download with mime-type 'text/c-source' and made cosmetic changes
34#
35# Revision 1.3  2001/01/11 21:36:39  rmahalin
36# *** empty log message ***
37#
38# Revision 1.2  2001/01/11 21:34:13  rmahalin
39# incorporated draft feedback changes
40#
41# Revision 1.1  2001/01/11 21:19:32  rmahalin
42# Initial revision
43#
44
45require "cgi-lib.pl";
46
47# current code version being used
48$version = "iSOS 2.5/int16";
49# full path to the cscope binary
50$cscopecmd = "/usr/global/bin/cscope";
51# cscope working directory, where all the in/out and db files are stored
52$cscopedir = "/usr/local/cscope";
53# trivial functions not to display, one per line in the trivs file
54$trivs = "/usr/local/htdocs/cscope/trivials";
55# temporary storage directory
56$tmpdir = "/tmp";
57$tmpinfile = $tmpdir . "/cscopein.$$";
58$tmpoutfile = $tmpdir . "/cscopeout.$$";
59$showfile = $tmpdir . "/showfile.$$";
60# C syntax highlighting application or uncomment the line beneath to just cat
61#$hiliter = "/bin/cat";
62$hiliter = "/usr/local/cgi-bin/cscope/hilite";
63($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = gmtime(time+1000000);
64$cookie_exp = sprintf("%s %02d-%s-%s %02d:%02d:%02d GMT", $wday, $mday, $mon, $year, $hour, $min, $sec);
65
66# standard images, from the apache distribution
67$img{openfile} = "/icons/folder.gif";
68$img{downloadfile} = "/icons/folder.open.gif";
69$img{csymbol} = "/icons/c.gif";
70$img{upfunc} = "/icons/up.gif";
71$img{downfunc} = "/icons/down.gif";
72$img{globalfunc} = "/icons/world2.gif";
73$img{trashfunc} = "/icons/bomb.gif";
74$img{untrashfunc} = "/icons/back.gif";
75$img{back} = "/icons/left.gif";
76
77# feedback details
78$comment{name} = "Ragho Mahalingam";
79$comment{email} = "ragho\@mahalingam.com";
80
81# operations allowed
82@oper = ( "Find this C symbol",
83"Find this global symbol",
84"Find functions called by",
85"Find functions calling",
86"Find this text string",
87"---------------------",
88"Find this egrep pattern",
89"Find this file",
90"Find files #including this file" );
91
92# -- removed global trivial function list in favor of customized trivials
93#open(TRIVIAL_FUNC, $trivs);
94#@trivial = <TRIVIAL_FUNC>;
95#close(TRIVIAL_FUNC);
96@trivial = ();
97
98MAIN:
99
100{
101   $starttime = time;
102
103	if (&ReadParse(*input)) {
104		&ProcessCookie;
105		&ProcessForm;
106	} else {
107		&PrintForm;
108	}
109}
110
111sub ProcessCookie {
112
113	if ( defined $ENV{HTTP_COOKIE} ) {
114		($var, $val) = split('=',$ENV{HTTP_COOKIE});
115		$Cookie{$var} = $val;
116      if ( defined $Cookie{'cs-trivf'} ) {
117         # do nothing, else initialize it to null
118      } else {
119         $Cookie{'cs-trivf'} = "defined";
120      }
121      @loc_trivial = split(',', $Cookie{'cs-trivf'});
122      @trivial = ( @loc_trivial );
123
124	}
125}
126
127sub ProcessTrashForm {
128
129		if ( defined $input{'trash'} ) {
130				@trivial = (@trivial, $input{'func'});
131      } else {
132				@tmptriv = ();
133				for ($i=0; $i <= $#trivial; $i++) {
134          		$fhash = unpack('H*', $input{'func'});
135          		$thash = unpack('H*', $trivial[$i]);
136          		if ( $fhash != $thash ) {
137						@tmptriv = ( @tmptriv, $trivial[$i] );
138					}
139				}
140				@trivial = @tmptriv;
141		}
142
143		$Cookie{'cs-trivf'} = join(',',@trivial);
144
145		print "Content-type: text/html\n";
146		print "Set-Cookie: cs-trivf=$Cookie{'cs-trivf'}; path=$ENV{SCRIPT_NAME}; expires $cookie_exp\n\n";
147		print &HtmlTop("Your WebCScope Trivial Functions");
148		print "<ul>";
149		for ($i=0; $i <= $#trivial; $i++) {
150			print "<li><a href=\"$ENV{SCRIPT_NAME}?untrash=&func=$trivial[$i]\"><img src=$img{untrashfunc} border=0></a>&nbsp; $trivial[$i]";
151		}
152		print "</ul><hr>\n";
153		print "Click <a href=\"#\" onClick=\"history.back();\"><img src=$img{back} border=0></a> to go back.\n";
154		print &HtmlBot;
155
156}
157
158sub ProcessForm {
159
160   chdir $cscopedir;
161   opendir(DIRLIST,$cscopedir);
162   @dirlist = readdir(DIRLIST);
163   closedir(DIRLIST);
164
165	if ( $input{'db'} eq "all" ) {
166		@csdirs = ();
167  	 	for ($i=0; $i <= $#dirlist; $i++ ) {
168        if ( ($dirlist[$i] ne ".") && ($dirlist[$i] ne "..") && ( -d $dirlist[$i] ) ) {
169	     @csdirs = ( @csdirs, $dirlist[$i] );
170        }
171      }
172	} else {
173		@csdirs = ( $input{'db'} );
174	}
175
176   $op = $input{'op'};
177   $arg = $input{'arg'};
178   $shtriv = $input{'triv'};
179	$db = $input{'db'};
180
181   if ( defined $input{'fshow'} ) { &ShowFileForm; exit; }
182   if ( defined $input{'load'} ) { &DownloadFileForm; exit; }
183   if ( (defined $input{'trash'}) || (defined $input{'untrash'}) ) {
184			&ProcessTrashForm; exit; }
185
186	print &PrintHeader;
187	print &HtmlTop ("WebCscope");
188   print <<ENDOFHDR;
189<h3>Instructions</h3><p>
190<ul>
191<li><img src=$img{csymbol}> will find a symbol with this name<br>
192<li><img src=$img{upfunc}> will find functions <i>calling</i> this function<br>
193<li><img src=$img{downfunc}> will find functions <i>called</i> by this
194function<br>
195<li><img src=$img{globalfunc}> will locate a global definition of this name<br>
196<li><img src=$img{openfile}> will display this file and highlight
197the fragment line<br>
198<li><img src=$img{downloadfile}> will download this file with mimetype "text/c-source"<br>
199<li><img src=$img{trashfunc}> will add this symbol/function to your trivial list<br>
200</ul>
201<p><hr>
202ENDOFHDR
203
204 foreach $index ( 0 .. $#csdirs ) {
205
206	unlink $tmpinfile, $tmpoutfile;
207	open(CSCOPEIN, ">$tmpinfile");
208	print CSCOPEIN "$op$arg\n";
209	print CSCOPEIN "exit\n";
210	close(CSCOPEIN);
211
212	$dbdir = $cscopedir . "/" . $csdirs[$index];
213	chdir($dbdir);
214
215	$syscmd = "cd $dbdir; $cscopecmd -d -l < $tmpinfile > $tmpoutfile;";
216	system($syscmd);
217
218   $count = 1;
219	open(CSCOPEIN, "$tmpoutfile");
220
221	$line = <CSCOPEIN>;
222	@temp =  split(' ',$line);
223	$numresult = $temp[2];
224
225	print <<ENDOFHDRs;
226<h2>Search Results from <b>$csdirs[$index]</b></h2>
227<font size=+1>$oper[$op]: <b>$arg</b></font><br>
228Matches: $numresult<p>
229<table border=1 cellpadding=2 cellspacing=2>
230<tr><td><b>Num</b></td><td><b>File</b></td><td><b>Function</b></td>
231<td><b>Line</b></td><td><b>Fragment</b></td></tr>
232ENDOFHDRs
233
234	$trivs_rm = 0;
235
236   for ($i=0; $i < $numresult; $i++ ) {
237       $line = <CSCOPEIN>;
238       @fields = split(' ',$line);
239       $file = shift @fields;
240       $fshowfile = $file;
241       $func = shift @fields;
242       $lnum = shift @fields;
243       @filef = split('/',$file);
244       $file = $filef[$#filef];
245       $frag = join(' ',@fields);
246
247	 if ( ! $shtriv ) {
248		for ( $j=0; $j <= $#trivial; $j++ )
249      {
250          $fhash = unpack('H*', $func);
251          $thash = unpack('H*', $trivial[$j]);
252          if ( $fhash == $thash ) { $trivs_rm++; goto done; }
253      }
254    }
255
256    if ( $func ne "<global>" && $func ne "<unknown>" ) {
257	       print <<ENDOFBODY1;
258<tr><td>$count</td>
259<td><a href="$ENV{SCRIPT_NAME}?fshow=1&fshowfile=$fshowfile&line=$lnum&db=$db">
260<img src=$img{openfile} border=0></a> $file
261 <a href="$ENV{SCRIPT_NAME}?load=1&file=$fshowfile&db=$db">
262<img src=$img{downloadfile} border=0></a>
263</td>
264<td><a href="$ENV{SCRIPT_NAME}?op=0&triv=$shtriv&arg=$func&db=$db">
265<img src=$img{csymbol} border=0></a>
266<a href="$ENV{SCRIPT_NAME}?op=3&triv=$shtriv&arg=$func&db=$db">
267<img src=$img{upfunc} border=0></a>
268$func
269<a href="$ENV{SCRIPT_NAME}?op=2&triv=$shtriv&arg=$func&db=$db">
270<img src=$img{downfunc} border=0></a>
271<a href="$ENV{SCRIPT_NAME}?op=1&triv=$shtriv&arg=$func&db=$db">
272<img src=$img{globalfunc} border=0></a>
273<a href="$ENV{SCRIPT_NAME}?trash=&func=$func&db=$db">
274<img src=$img{trashfunc} border=0></a>
275</td>
276<td>$lnum</td>
277<td>$frag</td></tr>
278ENDOFBODY1
279
280} else {
281			 $func =~ tr/<>/[]/;
282	       print <<ENDOFBODY2;
283<tr><td>$count</td>
284<td><a href="$ENV{SCRIPT_NAME}?fshow=1&fshowfile=$fshowfile&line=$lnum&db=$db">
285<img src=$img{openfile} border=0></a> $file
286 <a href="$ENV{SCRIPT_NAME}?load=1&file=$fshowfile&db=$db">
287<img src=$img{downloadfile} border=0></a>
288</td>
289<td>$func</td>
290<td>$lnum</td>
291<td><$frag</td></tr>
292ENDOFBODY2
293
294}
295
296       $count++;
297done:
298
299   }
300
301	close(CSCOPEIN);
302   print "</table>\n";
303   print "<br>Eliminated $trivs_rm line item(s) as trivial functions<p><hr>\n";
304   unlink $tmpinfile, $tmpoutfile;
305
306}
307
308   print &OperationTime;
309   print &Feedback;
310   print &HtmlBot;
311
312}
313
314sub DownloadFileForm {
315    $file = $input{'file'};
316    print "Content-type: text/c-source\n\n";
317    open(SHOWFILE, $file);
318    while (<SHOWFILE>) { print; }
319    close(SHOWFILE);
320}
321
322sub ShowFileForm {
323
324    $file = $input{'fshowfile'};
325    $lnum = $input{'line'};
326
327	print &PrintHeader;
328	print &HtmlTop ("WebCscope");
329   print "<b>Note</b>: Click <a href=#ref><img src=$img{downfunc} border=0></a> to go to the reference line<p><hr>\n";
330   print "<hr>";
331
332	unlink $showfile;
333   system("$hiliter $file > $showfile");
334	open(SHOWFILE, $showfile);
335
336   $curline = 1;
337   while ( <SHOWFILE> ) {
338       $line = $_;
339       if ( $curline == $lnum ) {
340          print "<a name=ref><blink>$line</blink>";
341       } else {
342          print $line;
343       }
344       $curline++;
345   }
346
347   close (SHOWFILE);
348
349
350
351   print &OperationTime;
352   print &Feedback;
353   print &HtmlBot;
354}
355
356sub PrintForm {
357
358   chdir $cscopedir;
359   opendir(DIRLIST,$cscopedir);
360   @dirlist = readdir(DIRLIST);
361   closedir(DIRLIST);
362
363	@csdirs = ();
364   for ($i=0; $i <= $#dirlist; $i++ ) {
365       if ( ($dirlist[$i] ne ".") && ($dirlist[$i] ne "..") && ( -d $dirlist[$i] ) ) {
366	   @csdirs = ( @csdirs, $dirlist[$i] );
367       }
368   }
369
370	print &PrintHeader;
371	print &HtmlTop ("Web-CScope");
372
373	print <<ENDOFTEXTA;
374<p style="color:red">Be aware that this webfrontend is insecure and allows viewing ALL apache readable files, including your configuration!</p>
375Select an operation below and enter a symbol, function or text to search in
376the database.  The active version is $version.  Input is case-sensitive,
377so if your search returns no results, check the case and the symbol name.<hr>
378<form method="get" action="$ENV{SCRIPT_NAME}">
379<table border=0 cellpadding=2 cellspacing=2>
380<tr>
381<td>Operation:</td>
382<td>
383<select name="op">
384ENDOFTEXTA
385
386  	foreach $opi ( 0 .. $#oper ) {
387  	   print "<option value=$opi>$oper[$opi]";
388  	}
389
390	print <<ENDOFTEXTB;
391</select>
392</td>
393</tr>
394<tr>
395<td>CScope Database:</td>
396<td>
397<select name="db">
398	<option selected value="all">All Databases
399ENDOFTEXTB
400
401	for ($i=0; $i <= $#csdirs; $i++) {
402		print "   <option value=\"$csdirs[$i]\">$csdirs[$i]\n";
403	}
404
405	print <<ENDOFTEXT2;
406</select>
407<tr>
408<td>Symbol, function or text:</td>
409<td><input name="arg" size=30></td>
410</tr>
411<tr>
412<td></td>
413<td halign=center>Show trivial functions:
414<input type=radio name="triv" value=1>Yes
415<input type=radio name="triv" value=0 checked>No
416<br><br>
417<input type="submit" value="Scope It!"></td>
418</tr>
419</table>
420<hr>
421</form>
422ENDOFTEXT2
423
424   print &Feedback;
425	print &HtmlBot;
426}
427
428sub Feedback {
429
430  $feedback  = "<font size=-1>";
431  $feedback .= "$comment{name}<i>&lt;";
432  $feedback .= "<a href=\"mailto:$comment{email}\">";
433  $feedback .= "$comment{email}</a>&gt;</i></font>";
434  return $feedback;
435}
436
437sub OperationTime {
438
439   $deltime = time - $starttime;
440   return "Operation took $deltime second(s)<br>";
441
442}
443