# $Id: install,v 1.23 2005/08/13 22:41:38 kiesling Exp $ ### ### TO DO ### 1. Add check for server run from inetd (ServerType directive). ### 2. Test for valid non-numeric user and group id's. ### 3. Make sure that the script can find htpasswd, etc. ### 4. Make sure that group ownership is set correctly if $group_ok. ### use IO::Handle; use warnings; my ($l, $ans, $label, $s); my $handle = new IO::Handle; if (! $handle -> fdopen (fileno(STDIN), "r")) { print "install: couldn't read standard input: $!\n"; exit 1; } print <)) { if ($l =~ /^\s*ServerName/) { ($label, $ServerName) = split /\s/, $l; $ServerName =~ s/\"//g; } if ($l =~ /^DocumentRoot/) { ($label, $DocumentRoot) = split /\s/, $l; $DocumentRoot =~ s/\"//g; } if ($l =~ /^ServerRoot/) { ($label, $ServerRoot) = split /\s/, $l; $ServerRoot =~ s/\"//g; } if ($l =~ /^\s*User\s+/) { ($label, $User) = split /\s/, $l; } if ($l =~ /^Group/) { ($label, $Group) = split /\s/, $l; $group_ok = 1 if $Group =~ /^\d+$/; } if ($l =~ /^Port\s/) { ($Port) = ($l =~ /\w+\s+(\d+)/); } $cgi_ok = 1 if $l =~ m/^\s*AddHandler\s?cgi-script/ && check_module ('mod_cgi', 'cgi_module'); if ($httpd_version =~ /^1\.3/) { $serverparsed_ok = 1 if ($l =~ /^\s*AddHandler\s?server-parsed/ && check_module ('mod_include', 'includes_module')); } elsif ($httpd_version =~ /^2\./) { $serverparsed_ok = 1 if ($l =~ /^\s*AddOutputFilter INCLUDES \.shtml/ && check_module ('mod_include', 'includes_module')); } $mod_auth_ok = 1 if check_module ('mod_auth', 'auth_module'); } close HTTPD_CONF; note_missing_confs (); ## ## Values from onsearch.cfg. ## my @conf; my $WebLogDir = ''; my $DataDir = ''; open CONF, "onsearch.cfg" or die "onsearch.cfg: $!\n"; while (defined ($l = )) { push @conf, ($l); } close CONF; ($s) = grep /^WebLogDir/, @conf; ($label, $WebLogDir) = split /\s+/, $s; ($s) = grep /^DataDir/, @conf; ($label, $DataDir) = split /\s+/, $s; print </dev/null 2>&1`; `cp images/* "$onsearchdir/images" >/dev/null 2>&1`; `cp -R cgi/* $onsearchdir >/dev/null 2>&1`; `cp doc/* "$onsearchdir/doc" >/dev/null 2>&1`; `cp plugins/* "$onsearchdir/plugins" >/dev/null 2>&1`; ### ### Install Perl libraries. ### print "Installing Perl libraries.\n"; `cd lib && (perl Makefile.PL LIB="$onsearchdir/lib" && make install && make clean)`; `chown -R $User "$onsearchdir/lib"`; `chgrp $Group "$onsearchdir/lib"` if $group_ok; ### ### Install OnSearchIO under PerlIO ### `cd lib/OnSearch/OnSearchIO && (perl Makefile.PL && make install && make clean)`; ### ### Set permissions. ### print "Setting permissions.\n"; `chown -R $User $onsearchdir`; `chgrp -R $Group $onsearchdir` if $group_ok; `chown $User $WebLogDir`; `chgrp $Group $WebLogDir` if $group_ok; `chmod 0775 $WebLogDir`; `chmod 0755 $onsearchdir`; `chown $User $DataDir`; `chgrp $Group $DataDir` if $group_ok; `chmod 0700 $DataDir`; foreach (qw/ alert.cgi error.cgi main.cgi search.cgi archive.cgi results.cgi filters.cgi index.cgi/) { `chmod 0755 "$onsearchdir/$_"`; } foreach (qw/adminform.cgi/) { `chmod 0755 "$onsearchdir/admin/$_"`; } foreach (qw/jpeg null ongzip pdf postscript text html/) { `chmod +x "$onsearchdir/plugins/$_"`; } ### ### Find top-level document directories. ### my @tldirs; push @tldirs, ($DocumentRoot); print < on a blank line. TDS2 while (1) { $ans = getkey (); last if (! length ($ans)); push @tldirs, ($ans); } print <$onsearchdir/onsearch.cfg" or die "onsearch.cfg: $!\n"; foreach my $o (@conf) { if ($o =~ /^BinDir/) { ($label, $onsearchbindir) = split /\s+/, $o; chomp $onsearchbindir; } if ($o =~ /^DataDir/) { ($label, $onsearchdatadir) = split /\s+/, $o; chomp $onsearchdatadir; } if ($o =~ /^ServerName/) { chomp $ServerName; print NEWCONFIG "ServerName $ServerName\n"; next; } if ($o =~ /^SearchRoot/) { foreach my $t (@tldirs) { chomp $t; print NEWCONFIG "SearchRoot $t\n" if length ($t); } next; } if ($o =~ /^ExcludeDir/) { print NEWCONFIG "ExcludeDir $onsearchdir/cache\n"; print NEWCONFIG "ExcludeDir $onsearchdir/lib\n"; next; } if ($o =~ /^User/) { chomp $User; print NEWCONFIG "User $User\n"; next; } print NEWCONFIG $o; } close NEWCONFIG; `chown $User "$onsearchdir/onsearch.cfg"`; `chgrp $Group "$onsearchdir/onsearch.cfg"` if $group_ok; ### ### Find perl, modules, and version. ### my ($perl_bin); chomp ($perl_bin = `which perl`); if (!length ($perl_bin)) { print <src/Makefile" or die "src/Makefile: $!\n"; while (defined ($l = )) { if ($l =~ /\@bindir\@/) { $l =~ s"\@bindir\@"$onsearchbindir"; } if ($l =~ /\@datadir\@/) { $l =~ s"\@datadir\@"$onsearchdatadir"; } if ($l =~ /\@onsearchdir\@/) { $l =~ s"\@onsearchdir\@"$onsearchdir"; } print MAKE $l; } close MAKE; close MAKETMPL; `rm -f /tmp/.onsearch.sock*`; print "Building the indexing daemon.\n"; `cd src && make install >/tmp/onsearch.bld 2>&1`; if (! -f 'src/onindex') { print <; close ERR; unlink '/tmp/onsearch.bld'; print "\nCleaning up....\n"; `sh -c "rm -rf $onsearchdir /usr/local/etc/init.d/onindex"`; exit 1; } else { unlink '/tmp/onsearch.bld'; `cd src && make clean`; } print "Installing man pages.\n"; open MAKETMPL, "doc/Makefile.tmpl" or die "src/Makefile.tmpl: $!\n"; open MAKE, ">doc/Makefile" or die "src/Makefile: $!\n"; while (defined ($l = )) { if ($l =~ /\@bindir\@/) { $l =~ s"\@bindir\@"$onsearchbindir"; } if ($l =~ /\@datadir\@/) { $l =~ s"\@datadir\@"$onsearchdatadir"; } if ($l =~ /\@onsearchdir\@/) { $l =~ s"\@onsearchdir\@"$onsearchdir"; } if ($l =~ /\@weblogdir\@/) { $l =~ s"\@weblogdir\@"$WebLogDir"; } print MAKE $l; } close MAKE; close MAKETMPL; # Don't need to cd back because these run in a subshell. `cd doc && (make all >/dev/null 2>&1)`; `cd doc && make clean >/dev/null 2>&1`; ### ### OnSearch Directory Wrapper ### print <>"$httpd_conf"`; ### ### Authentication ### auth: print <>"$httpd_conf"`; print </usr/local/etc/ongroup`; print </usr/local/etc/onpasswd`; print < close; exit 0; ## ## Create directories ## sub mkdir_wrap { my $d =$_[0]; my $a; if (($a = `mkdir -p $d 2>&1`) =~ /cannot create directory/i) { print STDERR "$a\n"; return -1; } return 0; } ## ## Keyboard input. ## sub getkey { my $key; $key = $handle -> getline; chomp $key; return $key; } ### ### Make subdirs ### sub mkdirtree { my ($dir, $mask) = @_; my ($parent) = ($dir =~ /(.*)\/.*$/); if (! -d $parent) { mkdirtree ($parent, $mask); } if (! -d $dir) { print "$dir.\n"; mkdir ($dir, $mask) or die "Could not make directory $dir: $!\n"; } } ## ## Missing Conf Variable ## sub missing_conf { my $c = $_[0]; print < Options ExecCGI Includes AddHandler cgi-script .cgi AddType text/html .shtml AddHandler server-parsed .shtml |; return $f } sub auth_template { my ($progdir) = @_; my $f = qq| # Added by OnSearch installation. AuthType Basic AuthName OnSearch AuthUserFile /usr/local/etc/onpasswd AuthGroupFile /usr/local/etc/ongroup require group onsearch |; return $f } sub group_template { my $f = qq|onsearch: onsearch|; return $f; } ### ### First check the httpd settings. ### Then check normal locations. ### Then search. ### Then warn user. ### sub find_httpd_conf { my @HTTP_CONF_PATHS = qw(/etc/apache/httpd.conf /usr/local/apache/conf/httpd.conf /usr/local/apache2/conf/httpd.conf); my @conffiles = (); my @httpdroots = (); my ($httpdroot, $conffile, $ans, $i, $altconf); ### ### First check the server's configuration. ### my @conflines = grep /httpd.conf/, split /\n/, `$httpd -V`; ($conffile) = ($conflines[0] =~ /SERVER_CONFIG_FILE=\"(.*?)\"/); @httpdroots = grep /HTTPD_ROOT/, split /\n/, `$httpd -V`; ($httpdroot) = ($httpdroots[0] =~ /HTTPD_ROOT=\"(.*?)\"/); if (-f $conffile) { print < 0) { print <= 0) { print <&1|" or die "ps: $!."; @httpd_procs = grep /httpd|apache/, ; close PS; PROC: foreach my $h (@httpd_procs) { chomp $h; @psfields = split /\s+/, $h; foreach my $p (@psfields) { if (-x $p) { next PROC if scalar grep /$p/, @dups; $ps_prog = $p; push @dups, ($ps_prog); } } if ($ps_prog) { print "The Web server is $ps_prog. Is this correct (y/n)?\n"; $ans = getkey (); if ($ans =~ /y/i) { $httpd_prog = $ps_prog; last PROC; } else { next PROC; } } } return $httpd_prog if $httpd_prog; ### ### Next, search bin directories. ### foreach my $bindir (@bindirs) { next if scalar grep m"$bindir\/(apache|httpd)", @dups; if (-x "$bindir/apache") { $httpd_prog = "$bindir/apache"; } elsif (-x "$bindir/httpd") { $httpd_prog = "$bindir/httpd" if -x "$bindir/httpd"; } else { undef $httpd_prog; } if ($httpd_prog) { print "The Web server is $httpd_prog. Is this correct (y/n)?\n"; $ans = getkey (); if ($ans =~ /y/i) { return $httpd_prog; } else { next; } } } print <)) { if ($l =~ m"^\s*LoadModule\s?$module_label") { $mod_ok = 1; last; } } close CONF; return $mod_ok; } sub get_port { my ($l, @lines, $pline, $label, $ipaddr, $port); open CONF, $httpd_conf || die "Can't open $httpd_conf: $!."; while (defined ($l = )) { chomp $l; push @lines, ($l); } close CONF; ### ### Check for a Port directive. ### if (scalar grep /^\s*Port/, @lines) { ($pline) = grep /^\s*Port/, @lines; if (length ($pline)) { ($label, $port) = split /\s+/, $pline; return $port; } } ### ### Check for a Listen directive, which could also have an ### IP address. ### if (scalar grep /^\s*Listen/, @lines) { ($pline) = grep /^\s*Listen/, @lines; if (length ($pline)) { if ($pline =~ m/\:/) { ($label, $ipaddr, $port) = ($pline =~ /^\s*(\w+)\s+(\S+):(\d+)/); } else { ($label, $port) = split /\s+/, $pline; } return $port; } } ### ### If not there, check the ServerName directive for a ### Port number. ### if (scalar grep /^\s*ServerName/, @lines) { ($pline) = grep /^\s*ServerName/, @lines; if (length ($pline)) { if ($pline =~ m/\:/) { ($label, $ipaddr, $port) = ($pline =~ /^\s*(\w+)\s+(\S+):(\d+)/); } else { ($label, $port) = split /\s+/, $pline; } return $port; } } print <