#!/usr/bin/perl use strict; use warnings; use File::Find; use File::Spec; use Getopt::Long qw(:config pass_through); #map{ print STDERR "$_ => $ENV{$_}\n" }keys(%ENV); #----------------------------------------------------------------------# # configuartions # main config file of lighttpd # needed to determin "username" "groupname" and "document_root" my @conf=qw(); # temp dir my $tmp=File::Spec->tmpdir(); # seach only here for perl scrips my $bin_path= 'fcgi-bin'; # file suffix my @suffix = qw(); # max processes of the script allowed my $max_process=1; # additional options my $add=''; my @defult_confs=qw(/etc/lighttpd.conf /etc/lighttpd/lighttpd.conf /usr/lib/lighttpd/lighttpd.conf /usr/local/lib/lighttpd/lighttpd.conf); #----------------------------------------------------------------------# # script GetOptions ( "config_file=s" => \@conf, "suffix=s" => \@suffix, "bin_path=s" => \$bin_path, "max_process=i" => \$max_process, "add=s" =>\$add, "tmp=s" =>\$tmp, ) || exit; #find a config file if no defined. # ( CWD is set to conf path ) if(!@conf) { my $first=''; for(@defult_confs) { $first=$_ and last if(-f $_) }; find(sub{ if($File::Find::name=~/\.conf$/) { my $fname=(File::Spec->splitpath())[2]; if($fname=~/lighttpd\.conf/) { if($first) { unshift(@conf,$File::Find::name); } else { $first=$File::Find::name; } } elsif($fname=~/lighttpd\.conf/) { unshift(@conf,$File::Find::name); } elsif($File::Find::name=~/lighttpd/) { push(@conf,$File::Find::name); } } },File::Spec->rel2abs('.')); unshift(@conf,$first) if($first); } # read config to find doc-root user and group my $usr=''; my $grp=''; my $base=''; { OUTER:for(@conf) { open(my $fh, '<', $_) or exit; while(my $l=<$fh>) { $base=$1 if($l=~m!^\s*server.document-root\s*=\s*"([^"]+)"!s); $usr=$1 if($l=~m!^\s*server.username\s*=\s*"([^"]+)"!s); $grp=$1 if($l=~m!^\s*server.groupname\s*=\s*"([^"]+)"!s); last OUTER if($base && $usr && $grp); } close($fh); } } exit unless($base && -d $base && $usr && $grp); # get ids for user and group my $uid = getpwnam($usr); my $gid = getgrnam($grp); exit unless(defined($uid) && defined($gid)); # find files # files have to be executable by process my %files=(); find(sub{ if(!@suffix || grep{$File::Find::name=~/\Q$_\E$/}@suffix) { my $fname=$File::Find::name; my $rname=File::Spec->abs2rel($fname,$base); $rname=~s!\\!/!gs; $rname="/$rname"; my ($fperm,$fuid,$fgid)=(stat($fname))[2,4,5]; $fperm &= 07777; if(-f $fname && (($fuid == $uid && $fperm & 00100) || ($fgid == $gid && $fperm & 00010) || $fperm & 00001) ) { $files{$fname}=$rname; } } },File::Spec->rel2abs($base,$bin_path)); exit unless(%files); # load mod_fastcgi print qq#server.modules += ( "mod_fastcgi" )\n#; # for each found script create a configuration. my $cnt=0; while(my($f,$n)=each(%files)) { my $tmp_file=File::Spec->join($tmp,"fastpl.$cnt.socket"); print <<"EOC"; fastcgi.server += ( "$n" => (( "bin-path" => "$f", "socket" => "$tmp_file", "max_process" => $max_process, "bin-copy-environment" => ( "PATH", "SHELL", "USER" ), "broken-scriptfilename" => "enable" $add )) ) EOC $cnt++; }