#!/usr/bin/perl 

########## Confixx(R) 3.0 Professional ############
####### Copyright SWsoft, Inc. 2004-2005 ##########
#### http://www.sw-soft.com - info@sw-soft.com ####


BEGIN {
  use FindBin;
  use lib "$FindBin::Bin";
  use lib "$FindBin::Bin/../scripts";
}

## Pre-Main
use File::Basename;
use File::Copy;

use lib_module_db;
use lib_module_common;

&initConfig();

$wDir = dirname($0);
unless (-e "$wDir/proFTPD_install.pl"){
  $wDir = "$installDir/admin/subs";
}

safe_do "$wDir/subs_include_questions.pl";
safe_do "$wDir/subs_include_writeConfig.pl";
safe_do "$wDir/subs_include_files.pl";
safe_do "$wDir/subs_include_proFTPD.pl";

&header2( &ltext('install_header_ftp', 'ProFTPD') );

if ( $ftpDaemon ne 'ProFTPD' || 
		 ( -T "$wDir/../.config" && $ftpDaemon eq '' ) || 
		 ! (-T $ftpConfFile) ) {
  $ftpDaemon = 'ProFTPD';
	&configureFtpd();
}
## /Pre-Main

## Main
&ConfigureProFTPD;

&restartFtpd;

&WriteMainConfigFile;

## /Main

## Unterprogramme


sub ConfigureProFTPD{
  $ftpEmail = $ftpConfAdmin unless $ftpEmail;
  unless($ftpEmail){
    $ftpEmail = &Question(&ltext('install_question_ftpemail', 'ProFTPD'), "technik\@$hostname");
    $ftpConfAdmin = $ftpEmail;
  }
  &BackUpFile("$ftpConfFile", "$installDir/backup/Pro-FTPD/proftpd.conf");
  print "\n";
  &CreateProFTPDConfigFile;
}


sub CreateProFTPDConfigFile{
  copy("$ftpConfFile", "$ftpConfFile.confixx-backup");
  my $time = localtime();
  my $group = 'nogroup';
  if(!(getgrnam($group)) && (getgrnam('nobody'))){
    $group = 'nobody';
  }
  my $default_type = &getServerType($ftpConfFile) || $ftpdType;
  my @types = ("inetd", "standalone");
  my $type;
  if($no_questions_mode){
    $type = 'inetd';
  } 
  else{
    $type = ($default_type) ? $default_type : &SelectQuestion( &ltext('install_question_ftpservertype'), @types);
  }
  $ftpdType = $type;
  my $limit;
  if($popGroup eq ""){
    $limit = "";
  }
  else{

  $limit = << "LIMIT";
# Groups that are not allowed to login
<Limit LOGIN>
DenyGroup $popGroup
</Limit>
LIMIT

  }

  my $LsDirective = 'LsDefaultOptions "-a"';
  
  unless (defined $ftpDaemonVersion) {
    $ftpDaemonVersion = &getProFTPDVersion(&getSearchPaths());
    unless (defined $ftpDaemonVersion) {
		&report_error(
"Can not detect version of ProFTPd.
You are to check if your '$ftpConfFile' is generated properly
after installation is complete. If you have ProFTPD server version 1.2.8
or greater, make sure that your configuration file has 'ListOptions'
directive, not 'LsDefaultOptions'"
		);
    }
  }
  
  my ($ver,$min,$maj) = map { /^\d+$/?$_:0 } split(/\./,$ftpDaemonVersion );
  my $ge = 0;
  if($ver>1){  ## ver 1.2.8
    $ge = 1;
  }elsif($ver==1){
    if($min>2){
  	  $ge=1;
	}elsif($min==2){
	  if($maj>=8){
	    $ge=1;
	  }
	}
  }
  if($ge){
    $LsDirective = 'ListOptions "-a"';
  }

  print &ltext('install_do_file_create', $ftpConfFile);
  open(FILE, ">$ftpConfFile");



print FILE << "CONFIG";
#### CONFIXX PRO-FTPD CONFIG FILE ####
    #### created at $time ###

# This is a basic ProFTPD configuration file (rename it to
# 'proftpd.conf' for actual use.  It establishes a single server
# and a single anonymous login.  It assumes that you have a user/group
# "nobody" and "ftp" for normal operation and anon.

ServerName	$hostname
ServerType	$type
DefaultServer	on
ServerAdmin	$ftpEmail
ServerIdent     on "FTP Server ready."
$LsDirective 

# Port 21 is the standard FTP port.
Port                            21

# Umask 022 is a good standard umask to prevent new dirs and files
# from being group and world writable.
Umask                           022

# To prevent DoS attacks, set the maximum number of child processes
# to 30.  If you need to allow more than 30 concurrent connections
# at once, simply increase this value.  Note that this ONLY works
# in standalone mode, in inetd mode you should use an inetd server
# that allows you to limit maximum number of processes per service
# (such as xinetd)
MaxInstances                    30

# Set the user and group that the server normally runs at.
User                            nobody
Group                           $group

TransferLog	$ftpLogFile

# Normally, we want files to be overwriteable.
AllowOverwrite                on

#
# Do a chroot for web-users (i.e. public or www group), but
# do not change root if the user is also in the users group...
#
#DefaultRoot ~/public_html       public,!users
#
DefaultRoot ~

$limit

     ### ENDE ####

CONFIG

  close(FILE);
}


# This subroutine returns current proftp version:
# 1) $ftpDaemonVersion value (if defined in confixx_main.conf)
# 2) tries to find proftpd binary and parse its output
# 3) undef
#
# The function is a temporary solution. Do not forget to change it later

sub getProFTPDVersion(@) {
  my (@path) = @_;        
  my $found = 0;
  foreach my $dir (@path) {
	my $ftpbin = "$dir/proftpd";
    if (-x $ftpbin) {
	  print "'proftpd' is found on '$ftpbin'\n";
  	  my $output = `$ftpbin --version 2>&1`;
  	  chomp $output;
  	  $output =~ /(\d+.\d+.\d+)/;
  	  return $1;
    }
  }
  unless ($found) {
  	&report_error("Can not find proftpd executable ('proftpd') in the following paths: \n"
	.join(":",@path)."\n".
	"Path to proftpd binary must be included in PATH environment variable\n");
  }
  return undef;
}

# This subroutine returns list of pathes in which the binary should be looked for.
sub getSearchPaths() {
	return (split(/:/,$ENV{PATH}),'/bin', '/sbin', '/usr/bin', '/usr/sbin', '/usr/local/bin', '/usr/local/sbin');
}

# Try to get the currently used ServerType option (inetd|standalone)
# from proftpd.conf.
# @return (inetd|standalone|undef)

sub getServerType() {

  my $file = shift;
  if(-T $file && open(FILE, "< $file")){
    while(<FILE>){
      if($_ =~ /^\s*ServerType\s+(\S+)/i){
        $var = $1;
        if($var =~ /(inetd|standalone)/i){
          return $var;
        }
      } 
    }
	close (FILE);
  }
  return undef;
}

sub report_error($) {
	my ($str) = @_;

	warn "PROBLEM FOUND: $str\n";
	my $logfile = "$installDir/INSTALLATION_PROBLEMS.LOG";
	unless (open(FILE, ">>$logfile")) {
		warn "Warning: can not save problem description to $logfile: can not open file $logfile: $!\n";
		return;
	}
	print FILE "$str\n";
	unless (close(FILE)) {
		warn "Warning: can not save problem description to $logfile: can not close file $logfile: $!\n";
		return;
	}
}

## /Unterprogramme
