1#! /usr/bin/perl -w
2# -*- mode: Perl -*-
3##################################################################
4# MRTG 2.17.4  --- Index Generator
5##################################################################
6#
7# This reads a mrtg.cfg file form std input or cmdline argument
8# and it takes a regexp on the cmdline to specify which
9# targets to look at.
10#
11# from this info it produces a router index on stdout or
12# on the filename specified by the --output option
13#
14##################################################################
15# Distributed under the GNU General Public License
16# Copyright 2000 by Tobias Oetiker <tobi@oetiker.ch>
17##################################################################
18
19$main::GRAPHFMT="png";
20
21require 5.005;
22use strict;
23
24# DEBUG TARGETS
25# base - basic program flow
26#@main::DEBUG=qw(base);
27
28BEGIN {
29    # Automatic OS detection ... do NOT touch
30    if ( $^O =~ /^(?:(ms)?(dos|win(32|nt)?))/i ) {
31        $main::OS = 'NT';
32        $main::SL = '\\';
33        $main::PS = ';';
34    } elsif ( $^O =~ /^NetWare$/i ) {
35        $main::OS = 'NW';
36        $main::SL = '/';
37        $main::PS = ';';
38    } elsif ( $^O =~ /^VMS$/i ) {
39        $main::OS = 'VMS';
40        $main::SL = '.';
41        $main::PS = ':';
42    } else {
43        $main::OS = 'UNIX';
44        $main::SL = '/';
45        $main::PS = ':';
46    }
47}
48
49use FindBin;
50use lib "${FindBin::Bin}";
51use lib "${FindBin::Bin}${main::SL}..${main::SL}lib${main::SL}mrtg2";
52
53use MRTG_lib "2.100016";
54use Getopt::Long;
55use Pod::Usage;
56
57#----------------------------------------------------------------------
58sub decimal_sort($$) {
59 my $a = $_[0];
60 my $b = $_[1];
61
62 $a =~ s/([0-9]+)/sprintf("%09u",${1})/ge;
63 $b =~ s/([0-9]+)/sprintf("%09u",${1})/ge;
64 return $a cmp $b;
65 }
66#----------------------------------------------------------------------
67
68my @argv = @ARGV;
69my $argz = "$0";
70foreach my $ar (@argv) {
71   if ($ar =~ /[ |()]/ ) {
72      $ar = sprintf qq{"%s"}, $ar;
73   }
74   $argz .= " $ar";
75}
76
77
78main();
79exit 0;
80
81sub main {
82    # default options
83    my %opt = (
84	       sort => 'original',
85	       show => 'day',
86	       section => 'h1',
87	       columns => 2,
88	       addhead => '',
89	       bodyopt => 'bgcolor="#ffffff" text="#000000" '.
90	                  'link="#000000" vlink="#000000" alink="#000000"',
91	       title => 'MRTG Index Page',
92	       headlevel => 1,
93	       pagetopend => '',
94	       pagetop => '',
95	       pageend => '',
96	       prefix => '',
97	       rrdviewer => '/cgi-bin/14all.cgi',
98	       optlog => 1,
99	       bold => 1,
100	       boldon => '<B>',
101	       boldoff => '</B>',
102	       div => 'DIV',
103	       imgborder => 1,
104	       cellspacing => 10,
105	       nolegend => 0,
106	      );
107    $opt{headon} = "<H$opt{headlevel}>";
108    $opt{headoff} = "</H$opt{headlevel}>";
109    # load real options
110    options(\%opt);
111
112    #adapt some defaults to the current options
113    die "ERROR: --autoprefix requires --output"
114      if ($opt{autoprefix} and !defined $opt{output});
115    $opt{pageend} = $opt{pagetopend} if (defined $opt{pagetopend} and not $opt{pageend});
116    $opt{pagetop} = $opt{pagetopend} if (defined $opt{pagetopend} and not $opt{pagetop});
117    $opt{boldon} = $opt{boldoff} = "" if (!$opt{bold});
118    $opt{picfirst} = (defined $opt{picfirst}?1:0);
119    if ($opt{compact}) {
120        $opt{imgborder} = 0;
121        $opt{cellspacing} = 0;
122        $opt{headon} = $opt{boldon};
123        $opt{headoff} = $opt{boldoff};
124    }
125	if ($opt{sidebyside}) {
126		$opt{div} = 'td';
127	}
128
129    # slurp config files
130    my %rcfg;
131    my %cfg;
132    my @target;
133    my @routers;
134    my $cfgfile;
135    my %files;
136    while (@ARGV) {
137           $cfgfile = shift @ARGV;
138	    readcfg($cfgfile,\@routers,\%cfg,\%rcfg);
139	    if (($opt{sectionhost}) or ($opt{perhost})) {
140	    	#We need to cache the "hostname" as appeared in cfgfile,
141	    	#since it does change in cfgcheck (for ex. if multiple
142	    	#overlapping cfgfiles are specified)
143	    	for my $targ (@routers) {
144	    		if ( !defined $rcfg{host}{$targ} and
145	    			 !($rcfg{target}{$targ} =~ m/(?<!\\)[ \`]/) ) {
146	    			$rcfg{target}{$targ} =~ m/.*[^\\]@([^:]*)/;
147	    			$rcfg{host}{$targ} = ucfirst $1 if (defined $1);
148	    		}
149	    	}
150	    }
151	    cfgcheck(\@routers, \%cfg, \%rcfg, \@target);
152           for my $targ (@routers) {
153               if (! defined $files{$targ}) {
154                    $files{$targ}=substr($cfgfile,rindex($cfgfile,'/')+1);
155               }
156           }
157	    if ($opt{autoprefix}) {
158		    $rcfg{prefixes} = {} if (!defined $rcfg{prefixes});
159	        my $pref = subpath($cfg{htmldir},$opt{output});
160		    for my $targ (@routers) {
161		        $rcfg{prefixes}->{$targ} = $pref
162		          if (! defined $rcfg{prefixes}->{$targ});
163		    }
164		}
165    }
166    # generate index page
167    genindex(\@routers, \%cfg, \%rcfg, \%opt, \%files);
168}
169
170sub cleanurl ($) {
171    my $url = shift;
172    $url =~ s|([^/.][^/.]*/)\.\./\1|$1|g;
173    return $url;
174}
175
176#Take a path the mrtg (usually the mrtg output directory) and the overview
177#file, find the relative path from the overview to the directory
178sub subpath ($$) {
179	my $sub = shift;
180	my $out = shift;
181	my @s=split /$main::SL/,$sub;
182	my @o=split /$main::SL/,$out;
183	pop @o;	#Last is a filename;
184	for my $i (0..$#s) {		#cut common dirs
185		if (defined $s[0] and
186		    defined $o[0] and
187		    $s[0] eq $o[0] ) {
188		    	shift @s;
189		    	shift @o;
190		}
191	}
192	my $ret = join $main::SL,@s;
193	for my $i (0..$#o) {
194		$ret = "..$main::SL$ret";	# ".." == "Directory below this one" for
195									# dos, windows, unix. What about VMS ?
196									# Is this correct ? HEH
197	}
198	$ret .= $main::SL;			#Possibly this should be "/" in order not
199								#to break on platforms !unix, since it will be
200								#used for generating urls ?
201	#Don't degenerate in "/" when really no prefix is needed.
202	$ret = "" if ($ret eq $main::SL);
203	return $ret;
204}
205
206sub genindex ($$$$) {
207    my $routers = shift;
208    my $cfg = shift;
209    my $rcfg = shift;
210    my $opt = shift;
211    my $cfgfile = shift;
212    my $index;
213    my $metaCmdLine;
214    # -----------------------------------------------------------
215    # keep only the items our users want (--filter)
216    # -----------------------------------------------------------
217    my @filtered;
218    ITEM: foreach my $item (@{$routers}) {
219	foreach my $filter (@{$$opt{filter}}) {
220	    if ($filter =~ /(.+)([=!]~)(.+)/) {
221		my ($area,$comp,$regex) = ($1,$2,$3);
222		my $value;
223	        for ($area) {
224		    /^title|pagetop$/ &&
225		      do { $value = $$rcfg{$area}{$item}; last };
226
227		    /^name$/ &&
228		      do { $value = $item; last };
229
230		    die "ERROR: unknown filter area $_\n";
231		};
232		for ($comp) {
233		    /^=~$/ &&
234		      do { next ITEM unless $value =~ /$regex/; last };
235		    /^!~$/ &&
236		      do { next ITEM unless $value !~ /$regex/; last };
237		    die "ERROR: unknown comparison operator $_\n";
238		};
239	    } else {
240		die "ERROR: invalid filter expression $filter\n";
241	    }
242	}
243	push @filtered, $item;
244    };
245
246    # -----------------------------------------------------------
247    # get items into proper order (--sort)
248    # -----------------------------------------------------------
249    my @order;
250    for ($$opt{sort}) {
251	/^original$/ && do {@order = @filtered; last};
252       /^name$/ &&  do { @order = sort { decimal_sort($a,$b); } @filtered; last};
253	/^title$/ && do { @order =
254                           sort { decimal_sort($$rcfg{title}{$a}, $$rcfg{title}{$b}) || $a cmp $b }
255			      @filtered;
256			  last;
257		      };
258	/^descr(iption)?$/ &&
259	    do {
260	      @order =
261	        sort {
262		  $$rcfg{pagetop}{$a} =~
263	           m[<td>Description:</td>\s*<td>(?:\S+\s+)?(.+?)</td>]i;
264		  my $aval = lc $1;
265		  $$rcfg{pagetop}{$b} =~
266	           m[<td>Description:</td>\s*<td>(?:\S+\s+)?(.+?)</td>]i;
267		  my $bval = lc $1;
268		  $aval cmp $bval;
269	        } @filtered;
270			  last;
271		      };
272	die "ERROR: unknown sort order '$$opt{sort}'\n";
273    }
274
275    die "ERROR: did not find any matching data in cfg file\n" unless @order;
276
277    # -----------------------------------------------------------
278    # issue page top
279    # -----------------------------------------------------------
280    my $interval =$$cfg{'interval'} ? $$cfg{'interval'} : 5;
281    my $expiration = &expistr($interval);
282    my $refresh =  $$cfg{'refresh'} ? $$cfg{'refresh'} : 300;
283    for ($$opt{show}) {
284       $refresh = /^week$/     && 1800
285               || /^month$/    && 7200
286               || /^year$/     && 86400
287               || $refresh ;
288    }
289
290    my $gifPath = '';
291
292    if ($$cfg{icondir} || $$opt{icondir}) {
293       $gifPath = $$opt{icondir} || $$cfg{icondir};
294       #lets make sure there is a trailing path separator
295     $gifPath =~ s|/*$|/|;
296   } else {
297       $gifPath = "$$cfg{imagehtml}";
298   }
299
300
301if ($$opt{optlog}) {
302    $metaCmdLine = $argz;
303} else {
304    $metaCmdLine = "<suppressed>";
305}
306
307$metaCmdLine =~ s/&/&amp;/g;   # Must be first, otherwise it will affect the following changes
308$metaCmdLine =~ s/"/&quot;/g;
309$metaCmdLine =~ s/</&lt;/g;
310$metaCmdLine =~ s/>/&gt;/g;
311    my $headeradd = $$opt{headeradd} || "";
312    $index = <<ECHO;
313<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
314<HTML>
315<HEAD>
316    <TITLE>$$opt{title}</TITLE>
317    <!-- Command line is easier to read using "View Page Properties" of your browser -->
318    <!-- But not all browsers show that information. :-(                             -->
319    <meta http-equiv="content-type" content="text/html; charset=iso-8859-15" >
320    <META NAME="Command-Line" CONTENT="$metaCmdLine" >
321    <META HTTP-EQUIV="Refresh" CONTENT="$refresh" >
322    <META HTTP-EQUIV="Cache-Control" content="no-cache" >
323    <META HTTP-EQUIV="Pragma" CONTENT="no-cache" >
324    <META HTTP-EQUIV="Expires" CONTENT="$expiration" >
325    <LINK HREF="${gifPath}favicon.ico" rel="shortcut icon" >
326    $headeradd
327ECHO
328
329    $index .= <<ECHO if ($$opt{optlog});
330<style type="text/css">
331/* commandline was: $argz */
332/* sorry, no style, just abusing this to place the commandline and pass validation */
333</style>
334ECHO
335
336    $index .= <<ECHO if ($$opt{addhead});
337    $$opt{addhead}
338ECHO
339
340    $index .= <<ECHO;
341</HEAD>
342
343<BODY $$opt{bodyopt}>
344ECHO
345    $index .= <<ECHO;
346
347$$opt{pagetop}
348$$opt{headon}$$opt{title}$$opt{headoff}
349ECHO
350
351    $index .= <<ECHO if $$opt{subtitle};
352<p>$$opt{subtitle}</p>
353ECHO
354
355    $index .= <<ECHO;
356
357<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=$$opt{cellspacing}>
358<tr>
359ECHO
360
361    # -----------------------------------------------------------
362    # print the graph items
363    # -----------------------------------------------------------
364    my $itemnr = 0;
365    my $first = $order[0];
366    my $host = $$rcfg{host}{$first};
367    if ($host){
368       $index .= "<a NAME=\"$host\"></a><tr><td>$$opt{headon}Interfaces of $host $$opt{headoff}</td></tr>" if $$opt{perhost};
369    } else {
370       $index .= "<a NAME=\"$host\"></a><tr><td>$$opt{headon}Special Items$$opt{headoff}</td></tr>" if $$opt{perhost};
371    }
372    foreach my $item (@order) {
373
374	if ($$opt{perhost}) {
375		my $newhost = $$rcfg{host}{$item} || 'unspecified host';
376		if (!($host eq $newhost)) {
377			$host = $newhost;
378			if ($host){
379   		          $index .= "<tr><td>$$opt{headon}Interfaces of $host $$opt{headoff}</td></tr>\n";
380                        } else {
381   		          $index .= "<tr><td>$$opt{headon}Special Items$$opt{headoff}</td></tr>\n";
382			}
383 		        $index .= "<tr>\n";
384			$itemnr=0;
385		}
386	}
387    $$opt{prefix} = $$rcfg{prefixes}->{$item} if ($$opt{autoprefix});
388	$itemnr++;
389	$index .= "<td>";
390        my $dirrel = "../" x ($$rcfg{'directory_web'}{$item} =~ tr|/|/|);
391
392	# --- produce graph section title ---
393	my $section;
394	for ($$opt{section}) {
395	    /^h1$/ &&
396	      do{
397		  if ($$rcfg{pagetop}{$item} =~ m[<h1[^>+]*>(.+?)</h1]i) {
398		      $section = $1;
399		      last;
400		  } else {
401		      die "ERROR: no H1 line pagetop property in $item section\n";
402		  }
403	      };
404	    /^title$/ &&
405	      do{
406		  $section = $$rcfg{title}{$item}; last
407	      };
408	    /^name$/ &&
409	      do{
410		  $section = $item; last
411	      };
412            /^descr(iption)?$/ &&
413              do{
414                  $section = "No Description for $item";
415		  $$rcfg{setenv}{$item} =~ /MRTG_INT_DESCR="(.+?)"/  #"
416                        and $section = $1;
417                  $$rcfg{pagetop}{$item} =~
418   		          m,<td>Description:</td>\s*<td>\Q$section\E\s*([^< ][^<]+?)</td>,i
419                        and $section = $1;
420                  last;
421              };
422             /^portname$/ &&
423               do{
424                 $section = "No Portname for $item";
425                 $$rcfg{pagetop}{$item} =~ m,<td>Port Name:</td>\s*<td>(.*?)</td>,i
426                      and  $section = $1;
427                 last;
428               };
429            die "ERROR: unknown sectioning type $_\n";
430	};
431	if (defined $$rcfg{host}{$item} and
432		!($section =~ m/\b\Q$$rcfg{host}{$item}\E\b/i)) {
433		$section = ucfirst $$rcfg{host}{$item} . ": $section";
434	}
435
436	# --- write the actual graph ----
437	die "ERROR: Unknown show type $$opt{show}\n"
438	  unless $$opt{show} =~ /^day|week|month|year|none$/;
439
440	my $image = "$item-$$opt{show}.${main::GRAPHFMT}"
441	 if $$opt{show} ne 'none';
442
443	$index .= "<$$opt{div}>" if (!$$opt{sidebyside});
444
445    if (not $image) {
446           if ($$cfg{logformat} eq 'rrdtool') {
447                my $sep = $$opt{rrdviewer} =~ /\?/ ? '&amp;' : '?';
448                $index .=
449               "<A HREF=\"$$opt{rrdviewer}".$sep."log=$item&amp;cfg=$$cfgfile{$item}\">".
450                       "$$opt{boldon}".
451                     "$section$$opt{boldoff}</A>";
452            } else {
453    	          $index .= "$$opt{boldon}".
454	             "<A HREF=\"".cleanurl($$opt{prefix}.
455		        $$rcfg{directory_web}{$item}).$item.
456		        ".$$rcfg{extension}{$item}\">".
457		        "$section$$opt{boldoff}</A></$$opt{div}>\n<$$opt{div}>";
458	    }
459	} else {
460		#loop used for reversing (text,images) to (images,text) if req.
461		for my $picfirstloop (1,0) {
462			if ( $picfirstloop^$$opt{picfirst} ) {
463				$index .= "$$opt{boldon}$itemnr. $$opt{boldoff}"
464	  			  if $$opt{enumerate};
465			    if ($$opt{clicktext}) {
466			        $index .= "$$opt{boldon}<A HREF=\"".cleanurl($$opt{prefix}.
467					  $$rcfg{directory_web}{$item}).$item.
468					  ".$$rcfg{extension}{$item}\">";
469				$index .= $section;
470				$index .= "</A>$$opt{boldoff}";
471			    } else {
472			    	$index .= "$$opt{boldon}$section$$opt{boldoff}";
473			    }
474	 	        $index .= "</$$opt{div}>\n<$$opt{div}>" if $picfirstloop;
475		    }
476
477		    if ( !($picfirstloop^$$opt{picfirst}) ) {
478		    	# figure show name for rrd viewer
479			    if ($$cfg{logformat} eq 'rrdtool') {
480               my $sep = $$opt{rrdviewer} =~ /\?/ ? '&amp;' : '?';
481               $index .= "<A HREF=\"$$opt{rrdviewer}".$sep."log=$item&amp;cfg=$$cfgfile{$item}\">".
482		                          "<IMG BORDER=$$opt{imgborder} ALT=\"$item Traffic Graph\" ".
483 "SRC=\"$$opt{rrdviewer}".$sep."log=$item&amp;cfg=$$cfgfile{$item}&amp;png=$$opt{show}.".
484					  "s&amp;small=1\"></A>"
485			    } else {
486				$index .= "<A HREF=\"".cleanurl($$opt{prefix}.
487					  $$rcfg{directory_web}{$item}).$item.
488					  ".$$rcfg{extension}{$item}\">";
489		        	$index .= "<IMG BORDER=$$opt{imgborder} ALT=\"$item Traffic Graph\" ".
490					  "SRC=\"".cleanurl($$opt{prefix}.
491					  $$rcfg{directory_web}{$item}.$dirrel.
492					  $$cfg{imagehtml}.$$rcfg{directory_web}{$item}).
493					  "$image\"";
494				$index .= ' WIDTH="'.$$opt{width}.'"'
495		                      if defined $$opt{width};
496				$index .= ' HEIGHT="'.$$opt{height}.'"'
497				      if defined $$opt{height};
498				$index .= "></A>";
499				$index .= "<BR>"
500				      if ( ! defined $$opt{compact} );
501				$index .= "\n<SMALL><!--#flastmod file=\"".
502					  cleanurl($$opt{prefix}.$$rcfg{directory_web}{$item}).$item.
503					  ".$$rcfg{extension}{$item}\" --></SMALL>";
504			    }
505			    $index .= "</$$opt{div}>\n<$$opt{div}>" if $picfirstloop;
506			}
507		}
508	}
509
510	$index .= "</$$opt{div}>" if (!$$opt{sidebyside});
511	$index .= "\n</td>";
512
513	# --- new table column if necessary ----
514	if (($itemnr) % $$opt{columns} == 0) {
515	    $index .= "</tr>\n<tr>\n";
516	}
517    }
518    # -----------------------------------------------------------
519    # print page end
520    # -----------------------------------------------------------
521
522
523    my $VERSION = "2.17.4";
524    $index .= <<ECHO;
525<td></td>
526</tr>
527</TABLE>
528ECHO
529
530   $index .= <<ECHO if (defined $$opt{pageend});
531$$opt{pageend}
532ECHO
533
534   $index .= <<ECHO if (!$$opt{nolegend});
535<BR>
536<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>
537  <TR>
538    <TD WIDTH=63><A
539    HREF="http://oss.oetiker.ch/mrtg/"><IMG
540    BORDER=0 SRC="${gifPath}mrtg-l.${main::GRAPHFMT}" WIDTH=63 HEIGHT=25 ALT="MRTG"></A></TD>
541    <TD WIDTH=25><A
542    HREF="http://oss.oetiker.ch/mrtg/"><IMG
543    BORDER=0 SRC="${gifPath}mrtg-m.${main::GRAPHFMT}" WIDTH=25 HEIGHT=25 ALT=""></A></TD>
544    <TD WIDTH=388><A
545    HREF="http://oss.oetiker.ch/mrtg/"><IMG
546    BORDER=0 SRC="${gifPath}mrtg-r.${main::GRAPHFMT}" WIDTH=388 HEIGHT=25
547    ALT="Multi Router Traffic Grapher"></A></TD>
548  </TR>
549</TABLE>
550<TABLE BORDER=0 CELLSPACING=0 CELLPADDING=0>
551  <TR VALIGN=top>
552  <TD WIDTH=88 ALIGN=RIGHT><FONT FACE="Arial,Helvetica" SIZE=2>
553  version $VERSION</FONT></TD>
554  <TD WIDTH=388 ALIGN=RIGHT><FONT FACE="Arial,Helvetica" SIZE=2>
555  <A HREF="http://tobi.oetiker.ch/">Tobias Oetiker</A>
556  <A HREF="mailto:tobi+mrtglink\@oetiker.ch">&lt;tobi\@oetiker.ch&gt;</A>
557  and&nbsp;<A HREF="http://www.bungi.com/">Dave&nbsp;Rand</A>&nbsp;<A HREF="mailto:dlr\@bungi.com">&lt;dlr\@bungi.com&gt;</A></FONT>
558  </TD>
559</TR>
560</TABLE>
561ECHO
562   $index .= <<ECHO;
563</BODY>
564</HTML>
565ECHO
566
567    # -----------------------------------------------------------
568    # write out the index page
569    # -----------------------------------------------------------
570    if ($$opt{output}) {
571	debug ('base', "Writing $$opt{output}");
572	open X, ">$$opt{output}" or die "ERROR: creating $$opt{output}: $!\n";
573	print X $index;
574	close X;
575    } else {
576	print $index;
577    }
578
579}
580
581sub options ($) {
582    my $opt = shift;
583    my @options = (
584	       'help|?',
585	       'man',
586	       'output=s',
587	       'filter=s@',
588           'addhead=s',
589	       'title=s',
590           'subtitle=s',
591	       'bodyopt=s',
592	       'pagetopend=s',
593	       'pagetop=s',
594	       'pageend=s',
595	       'columns=i',
596	       'perhost!',
597	       'sort=s',
598	       'enumerate',
599	       'width=i',
600	       'height=i',
601	       'show=s',
602	       'section=s',
603           'version',
604	       'prefix=s',
605               'headeradd=s',
606	       'clicktext!',
607	       'optlog!',
608	       'compact!',
609	       'headlevel=i',
610	       'bold!',
611	       'picfirst!',
612	       'sidebyside!',
613	       'nolegend',
614	       'autoprefix!',
615	       'sectionhost!',
616           'icondir=s',
617	       'rrdviewer=s');
618
619	#generate --option-file from --option
620	for ( grep /=s$/,@options ) {
621		my $fileopt = $_;
622		$fileopt =~ s/=s$/-file=s/;
623		push @options, $fileopt;
624	}
625
626    GetOptions( $opt, @options ) or pod2usage(-verbose => 1);
627
628    if ($$opt{prefix}){
629	$$opt{prefix} .= '/';
630	$$opt{prefix} =~ s|/+$|/|;
631    }
632    die ("Indexmaker for mrtg-2.17.4\n") if $$opt{version};
633    pod2usage(-exitval => 1, -verbose => 2) if $$opt{man};
634    pod2usage(-verbose => 1) if not @ARGV;
635
636    #take care of --fileoption --> --option
637    for my $fileopt ( grep /-file$/, keys %{$opt} ) {
638    	my $orgopt = $fileopt;
639    	$orgopt =~ s/-file$//;
640    	$$opt{$orgopt} = &readfile($$opt{$fileopt});
641    }
642}
643
644#return the contents of a file
645sub readfile($) {
646	my $file = shift;
647	open F,"<$file" or die "ERROR: can\'t open $file for read, $!";
648	my $sl = $/;
649	$/ = undef;
650	my $string = <F>;
651	$/ = $sl;
652	close F;
653	return $string;
654}
655
656__END__
657
658=pod
659
660=head1 NAME
661
662indexmaker - Creates index files for mrtg web sites (mrtg-2.17.4)
663
664=head1 SYNOPSIS
665
666indexmaker [options] mrtg.cfg [other.cfg ...]
667
668=head1 OPTIONS
669
670 --output=filename   set output filename (default: stdout)
671
672 --filter title=~regexp  select targets by matching regexp against titles
673 --filter pagetop=~regexp  select targets by matching regexp against pagetop
674 --filter name=~regexp  select targets by matchin regexp against name
675
676 --addhead=text      insert this text between </TITLE> and </HEAD>
677 --title=text        set title of generated index file
678 --subtitle=text     add a subtitle to the generated index file
679 --bodyopt=text      set body tag options
680 --headlevel=number  use <Hnumber> at top of page (default: 1)
681 --pagetop=text      insert this text between <BODY> and <H1>...</H1>
682 --pageend=text      insert this text after the main body
683 --pagetopend=text   use this text for pagetop or pageend if undefined
684 --nolegend          do not add the Mrtg legend at the end of the page
685
686 --columns=number    show graphs in a table with x columns (default: 2)
687 --perhost           show graphs of the same host on a row
688 --compact           try to make a vertically more compact page
689 --optlog            log the used command line in the page (default: log)
690
691 --sort=title        sort graphs by title
692 --sort=name         sort graphs by their name
693 --sort=descr        sort graphs by their description
694 --sort=original     leave as is (default)
695
696 --enumerate         add a sequence number to the title of each graph
697
698 --picfirst          place pictures before text (default: text first)
699 --width=number      set width of graphs (default: not set)
700 --height=number
701 --sidebyside        place text / pictures side by side (default: above/below)
702 --bold              use bold text (default: bold)
703 --clicktext         make the text link to the inner page (like the image)
704
705 --show=day          pick which graph to show in the index (default)
706 --show=week
707 --show=month
708 --show=year
709 --show=none
710
711 --section=h1        h1 tag from pagetop as section heading (default)
712 --section=title     title as section headings for graphs
713 --section=name      graph name as section heading
714 --section=descr     graph description as section heading
715 --section=portname  port name entry in pagetop as section heading
716 --sectionhost       Try to prepend the host to the section heading if missing
717
718 --rrdviewer=path    path to rrdviewer (default: /cgi-bin/14all.cgi)
719 --icondir=path      path to icondir
720 --prefix=path       path from the location of the index.html to the graphs
721 --headeradd=string  add string to the html page header
722 --autoprefix        try to set prefix automatically
723
724 --<opt>-file=file   read string argument for option <opt> from file
725
726=head1 DESCRIPTION
727
728B<Indexmaker> can create web pages which display the status of an
729array of mrtg interface status pages.
730
731=over
732
733=item B<--output> I<filename>
734
735set output filename (default: stdout)
736
737=item B<--filter> (B<title>|B<pagetop>|B<name>)(B<=~>|B<!~>)I<regexp>
738
739Several filters may get set.  Each filter can match agains the contents
740of a specific section of the mrtg config file. B<Name> refers to the
741bit in square brackets (option[name]: bla).
742
743Depending on the match operator chosen (B<=~> or B<!~>) the match will be
744positive or negative.
745
746Note that some shells consider B<!> a special character.  It may be
747necessary to type B<\!~> instead.
748
749=item B<--title> I<text>
750
751Set title of generated index file (default: regexp)
752
753=item B<--bodyopt> I<text>
754
755The value of this argument gets appended to
756the E<lt>BODYE<gt> tag. This allows you to set document colors.
757By default this option is set to
758
759 bgcolor="#ffffff" text="#000000" link="#000000" vlink="#000000" alink="#000000"
760
761=item  B<--columns> I<number>
762
763Display graphs in a table with I<number> columns (default: 2)
764
765=item B<--sort> B<title>|B<name>|B<descr>|B<original>
766
767Sort the graphs in the page either by B<title>, by B<name>, by interface
768B<descr>iption, or leave them as is.
769
770=item B<--enumerate>
771
772Add a sequence number to the title of each graph
773
774=item B<--width> I<number>
775
776Set width of graphs
777
778=item B<--height> I<number>
779
780Set the height of the graphs
781
782=item B<--show> B<day>|B<week>|B<month>|B<year>|B<none>
783
784Select which graph to show in the index page. You can supress images
785completely with B<--show=none>.
786
787=item B<--section> B<h1>|B<title>|B<name>|B<description>|B<portname>
788
789Select what to use as the title for each graph in the page.  B<h1> is
790the H1 section from pagetop, B<title> is the graph title, B<name> is
791the bit in square brackets (option[name]: bla), and B<descr> or
792B<description> is the text from the Description field of the PageTop
793(the Cisco description text if it's available, otherwise just the
794interface description). B<portname> is the C<Port Name:> from pagetop.
795
796=item B<--sectionhost>
797
798Extract the hostname from the target line (this does not work if the
799target is a mathematial expression). Prepend the hostname (and a colon)
800to the section if not already present.
801
802=item B<--rrdviewer> I<path>
803
804If you have set the B<LogFormat: rrdtool> property in the mrtg.cfg
805file, the index will take this into account. The only thing you must
806tell it is the path to your grapher cgi. (default: /cgi-bin/14all.cgi)
807
808=item B<--prefix> I<path>
809
810By  default we assume    that  the file generated by indexmaker is stored in
811I<WorkDir>.  If you want to  store it somewhere   else, specify how to reach
812I<WorkDir>  from  the place where the Index is stored. Note that you have to
813use '/' as path separator as this will be used in urls. Speaking of which,
814you can even enter a whole url.
815
816=item B<--autoprefix> I<path>
817
818Requires --output.
819Try to generate the prefix automatically by comparision of the path to the
820output file set with --output and the Htmldir set in the configuration files.
821Particulary useful when multiple configuration files are specified, with
822different Htmldir settings.
823
824=item B<--optlog>
825
826Default is logging in the generated page the command line, suppress with
827--nooptlog . Useful if the commandline contains a complex --pagetop=string
828which could confuse simple browsers.
829
830=item B<--someoption-file> I<filename>
831
832For any someoption which takes a I<string> as parameter you can read the
833string from a file by adding <-file> to the option keyword. The whole
834content of the file will be read and used as the I<string>. The file must
835exist.
836
837=back
838
839=head1 AUTHOR
840
841Tobias Oetiker E<lt>tobi@oetiker.chE<gt>
842
843=head1 LICENSE
844
845GNU General Public License
846
847=head1 COPYRIGHT
848
8492000-2001 Tobias Oetiker E<lt>tobi@oetiker.chE<gt>
850
851=cut
852