8 use Digest::MD5 'md5_hex';
 
  10 our (@local_rdomains,@local_rhosts);
 
  12 $ENV{PATH} .= ':/sbin:/usr/sbin';
 
  14 $usage = "usage: $0 [-p port] [IP-address]\n";
 
  15 $xinetd = '/etc/xinetd.d/fex';
 
  20   die "you must be root to install F*EX\n";
 
  23 $fex = 'fex.rus.uni-stuttgart.de';
 
  24 if (system("host $fex >/dev/null") != 0) {
 
  25   die "host $fex is not resolvable - check /etc/resolv.conf\n";
 
  28 # $fexupdate = '/root/bin/fexupdate';
 
  29 # die "found $fexupdate\n" if -x $fexupdate;
 
  33 if (open $xinetd,$xinetd) {
 
  35     if (/^\s*port\s*=\s*(\d+)/) {
 
  36       $opt_p = $fexport = $1;
 
  38     if (/^\s*bind\s*=\s*([\d.]+)$/) {
 
  45 goto INSTALL if $0 =~ /upgrade$/;
 
  47 if (`uname` =~ /^SunOS/) {
 
  48   die "Solaris is currently not supported. "
 
  49      ."Please contact framstag\@rus.uni-stuttgart.de for details.\n";
 
  52 getopts('p:') or die $usage;
 
  55 if ($arg and -f "locale/$arg/lib/fup.pl") {
 
  56   exec 'locale/translate',$arg;
 
  58   $ip = $arg || $fexip || 0;
 
  61 # if (not $ip and open P,"ifconfig 2>/dev/null |") {
 
  62 if (not $ip and open P,'host $(hostname)|') {
 
  65     if (/(\d+\.\d+\.\d+\.\d+)/) { 
 
  72     print "Your IP [$guessed_ip] : ";
 
  79 ($hostname) = gethostbyaddr(gethostbyname($ip),AF_INET);
 
  80 die "cannot find hostname for IP $ip\n" unless $hostname;
 
  82 print "checking prerequisites\n";
 
  84 if (`which xinetd` =~ m{^/}) {
 
  85   print "found xinetd\n";
 
  87   print "xinetd executable NOT found\n";
 
  91 foreach (qw'/usr/lib/sendmail /usr/sbin/sendmail') {
 
  94     print "found $sendmail\n";
 
  99   print "sendmail NOT found\n";
 
 104   print "installation aborted, nothing has been touched yet\n";
 
 105   print "what now? ==> see doc/installation\n";
 
 111   $SH = IO::Socket::INET->new(
 
 118     print "There is already a tcp-service running on $ip:$opt_p !\n";
 
 119     print "Select another port for F*EX by running $0 -p OTHERPORT $ip\n";
 
 120     print "or an alternative IP-address by running $0 OTHERADDRESS\n";
 
 125 print "prerequisites checked, ok\n";
 
 127 unless (getpwnam('fex')) {
 
 128   print "creating user fex\n";
 
 129   system 'groupadd --system fex 2>/dev/null || groupadd fex';
 
 130   my @g = getgrnam('fex') or die "$0: cannot groupadd fex\n";
 
 132   if (getpwuid($gid)) {
 
 133     system "useradd -s /bin/bash -c 'File EXchange' -g $gid -m fex"
 
 135     system "useradd -s /bin/bash -c 'File EXchange' -u $gid -g $gid -m fex"
 
 140 if (open F,'/etc/passwd') {
 
 142     $fexbash = $_ if /^fex:.*\/bash/;
 
 147   die "no bash login shell for user fex\n";
 
 154 @FEX = getpwnam('fex') or die "no user fex\n";
 
 156 $ENV{HOME} = $FEXHOME; # needed for later eval fex.ph
 
 158 die "no HOME directory for user fex\n" unless -d $FEXHOME;
 
 159 if ($FEXHOME !~ /fex/) {
 
 160   print "HOME=$FEXHOME for user fex does not contain \"fex\"\n";
 
 161   print "REALLY continue?! ";
 
 167 if (-d "$FEXHOME/htdocs/locale") {
 
 168   chmod 0755,"$FEXHOME/htdocs/locale";
 
 169   chmod 0755,grep { -d $_ } glob("$FEXHOME/locale/*/htdocs");
 
 172 print "Installing:\n";
 
 174 $pecl = "$FEXHOME/perl/Encode/ConfigLocal.pm";
 
 176   mkdir "$FEXHOME/perl";
 
 177   mkdir "$FEXHOME/perl/Encode";
 
 178   open $pecl,'>',$pecl or die "$0: cannot write $pecl - $!\n";
 
 180     "# hack for broken Perl in SuSe and Solaris, used via \@INC in fexsrv\n",
 
 184   chownr('fex:0',"$FEXHOME/perl");
 
 190   "lib/reactivation.txt",
 
 194   "htdocs/FAQ/local.faq",
 
 201     rename $f,$fs and print "$f --> $fs\n";
 
 205 cpav(qw'bin cgi-bin lib etc htdocs doc',$FEXHOME);
 
 206 unlink "$FEXHOME/doc/License";
 
 207 unlink "$FEXHOME/htdocs/License";
 
 209 $hl = "$FEXHOME/htdocs/locale";
 
 210 unless (-d $hl) { mkdir $hl or die "$0: cannot mkdir $hl - $!\n" }
 
 218     rename $f,$fn and print "$f --> $fn\n";
 
 219     rename $fs,$f and print "$fs --> $f\n";
 
 223 if (-d "$FEXHOME/spool") {
 
 224   warn "checking $FEXHOME/spool ...\n";
 
 227   $newinstall = $FEXHOME;
 
 229   mkdir "$FEXHOME/spool",0700 or die "cannot mkdir $FEXHOME/spool - $!\n";
 
 230   mkdir "$FEXHOME/spool/.error",0700;
 
 232 foreach my $dir (qw'.dkeys .ukeys .akeys .skeys .gkeys .xkeys .locks') {
 
 233   mkdir "$FEXHOME/spool/$dir",0700;
 
 236 chownr('fex',"$FEXHOME/spool/.");
 
 239 if (open my $setup,'/root/bin/setup') {
 
 246 system(qw'perl -p -i -e',
 
 247   's:href="/?FAQ.html":href="/FAQ/FAQ.html":',
 
 248   "$FEXHOME/lib/fup.pl"
 
 251 $fph = "$FEXHOME/lib/fex.ph";
 
 252 open $fph,$fph or die "cannot read $fph - $!\n";
 
 254   s/'MYHOSTNAME.MYDOMAIN'/'$hostname'/;
 
 261 # die "no \$spooldir in $fph\n" unless $spooldir;
 
 262 $spooldir ||= '/home/fex/spool';
 
 263 die "\$spooldir=$spooldir is not a directory, see $fph\n" unless -d $spooldir;
 
 264 symlink $spooldir,"$FEXHOME/spool" unless -e "$FEXHOME/spool";
 
 265 @sds1 = stat "$spooldir/.";
 
 266 @sds2 = stat "$FEXHOME/spool/.";
 
 267 if ("@sds1" ne "@sds2") {
 
 268   die "$FEXHOME/spool is not a symbolic link to \$spooldir=$spooldir\n";
 
 271 $fid = "$FEXHOME/.fex/id";
 
 272 $aa = "$spooldir/$admin/@";
 
 274 if ($newinstall or not -s $aa) {
 
 277     print "Server hostname [$hostname] : ";
 
 280     $hostname = $_ if $_;
 
 281     last if gethostbyname($hostname);
 
 282     print "No DNS for $hostname\n";
 
 285     print "F*EX admin [$admin] : ";
 
 289     last if $admin =~ /.\@./;
 
 290     print "admin must be a valid email address!\n";
 
 292   $aa = "$spooldir/$admin/@";
 
 293   while (not $admin_pw) {
 
 294     print "F*EX admin password: ";
 
 296     $admin_pw =~ s/\s//g;
 
 299   print "(admin password is in $aa)\n";
 
 300   $conf =~ s/^\s*\$hostname\s*=.*/\$hostname = '$hostname';/m;
 
 301   $conf =~ s/^\s*\$admin\s*=.*/\$admin = '$admin';/m;
 
 304     print "\nFound old \$admin_pw in $fph !\n";
 
 305     print "This is no longer supported for security reason.\n";
 
 310       if ($_ ne $admin_pw) {
 
 311         print "\nYou have to delete \$admin_pw in $fph and run\n";
 
 312         print "$FEXHOME/bin/fac -u $admin $admin_pw\n";
 
 313         print "\nThen rerun $0\n";
 
 318     print "\$admin_pw is transfered to auth-ID in $aa\n\n";
 
 319     $conf =~ s/^\s*(\$admin_pw)\s*=.*/# $1 is now auth_ID of user \$admin/m;
 
 323 open $fph,">$fph.new" or die "$0: cannot write $fph.new - $!\n";
 
 326 system "chown fex $fph.new";
 
 327 rename "$fph.new",$fph or die "$0: cannot rename $fph.new to $fph - $!\n"; 
 
 329 do $fph or die "$0: error in new $fph - $!\n";
 
 331 if (@locales = glob "locale/*/lib/fup.pl") {
 
 333     m{locale/(.+?)/} and $locale = $1;
 
 334     if (-f "$FEXHOME/$_") { 
 
 335       system 'locale/translate',$locale;
 
 336       chownr('fex',"$FEXHOME/locale/$locale");
 
 337       $hl = "$FEXHOME/htdocs/locale/$locale";
 
 338       symlink "$FEXHOME/locale/$locale/htdocs",$hl unless -l $hl;
 
 339       chownr('fex',"$FEXHOME/htdocs/locale/$locale");
 
 341       push @nlocales,"./install $1\n";
 
 345     if (glob "$FEXHOME/locale/*/lib/fup.pl") {
 
 346       print "\nTo install another localized version, type:\n";
 
 348       print "\nTo install a localized version, type:\n";
 
 354 $fph = "$FEXHOME/lib/fex.ph";
 
 357 unless (-f $xinetd) {
 
 358   my $xc = '/etc/xinetd.conf';
 
 361       if (/^\s*only_from/) {
 
 362         print "WARNING: found \"only_from\" in $xc : fexsrv is restricted!\n";
 
 367   if (-d '/etc/xinetd.d') {
 
 368     unless (-f $xinetd) {
 
 369       open $xinetd,">$xinetd" or die "cannot write $xinetd - $!\n";
 
 370       open F,'etc/xinetd_fex' or die "cannot read etc/xinetd_fex - $!\n";
 
 379       system qw'/etc/init.d/xinetd restart';
 
 380       print "WARNING: cannot restart xinetd\n" if $?;
 
 383     print "WARNING: No /etc/xinetd.d found.\n";
 
 384     print "WARNING: You have to install etc/xinetd_fex manually.\n";
 
 387   $crontab = `crontab -u fex -l 2>/dev/null`;
 
 388   if ($crontab !~ /fex_cleanup/) {
 
 389     open $crontab,">fex.cron" or die "cannot create fex.cron - $!\n";
 
 390     print {$crontab} $crontab,"\n";
 
 391     print {$crontab} " 3 2 * * * exec $FEXHOME/bin/backup\n";
 
 392     print {$crontab} " 3 3 * * * exec $FEXHOME/bin/fex_cleanup\n";
 
 394     system qw'crontab -u fex fex.cron';
 
 397   chownr('fex:0',$FEXHOME,"$FEXHOME/spool/.","$FEXHOME/htdocs/.");
 
 398   chmodr('go-r',"$FEXHOME/lib","$FEXHOME/cgi-bin","$FEXHOME/spool/.");
 
 401   print "Now check configuration file $FEXHOME/lib/fex.ph and run\n";
 
 402   print "$FEXHOME/bin/fac for further configuration and user management.\n";
 
 403   print "(You can do this as user \"fex\")\n";
 
 406   chmodr('go-r',"$FEXHOME/lib","$FEXHOME/cgi-bin");
 
 409   print "F*EX update installed.\n";
 
 410   print "You can inform your users about the new features with:\n";
 
 411   print "$FEXHOME/bin/fexwall 'new F*EX features on $hostname' ".
 
 412         "< $FEXHOME/doc/newfeatures\n";
 
 415 if (@local_rdomains and not @local_rhosts) {
 
 416   print "\nWARNING:\n";
 
 417   print "In $fph you have \@local_rdomains but not \@local_rhosts!\n";
 
 418   print "Selfregistrating of external users will not work!\n";
 
 419   print "See ${fph}_new/\n";
 
 422 if (`$sendmail -h 2>&1 </dev/null` =~ /exim/ and 
 
 423     `grep trusted_users /etc/exim4/exim4.conf 2>/dev/null` !~ /\bfex\b/) {
 
 424   print "\nWARNING:\n";
 
 425   print "$sendmail is exim\n";
 
 426   print "You MUST set in your exim4.conf:\n";
 
 427   print "trusted_users = mail : uucp : fex\n";
 
 433   my $ad = dirname($aa);
 
 435   open $aa,'>',$aa or die "$0: cannot create $aa - $!\n";
 
 436   print {$aa} "$admin_pw\n";
 
 438   my $fd = dirname($fid);
 
 440   rename $fid,$fid.'_save';
 
 441   open $fid,'>',$fid or die "$0: cannot create $fid - $!\n";
 
 442   print {$fid} "$hostname:$opt_p\n";
 
 443   print {$fid} "$admin\n";
 
 444   print {$fid} "$admin_pw\n";
 
 446   chownr('fex',$ad,$fd);
 
 454     if (m:^/*(lib|usr|home)?/*$:) {
 
 455       die "ERROR: short path in chownr $user @_\n";
 
 458   system qw'chown -R',$user,@_;
 
 465     if (m:^/*(lib|usr|home)?/*$:) {
 
 466       die "ERROR: short path in chmodr $mod @_\n";
 
 469   system qw'chmod -R',$mod,@_;
 
 473   my ($f,$d,$to,$from,$link);
 
 478   our ($spooldir,$skeydir,$gkeydir);
 
 479   $ENV{FEXLIB} = $FEXLIB = "$FEXHOME/lib";
 
 480   require "$FEXLIB/fex.pp" or die "$0: cannot load $FEXLIB/fex.pp - $!\n";
 
 481   die "no \$spooldir in $FEXLIB/fex.pp\n" unless $spooldir;
 
 482   die "\$spooldir=$spooldir/" if $spooldir =~ m:^/*(root)?$:;
 
 484   # User --> user@maildomain
 
 486     foreach $f (glob "$spooldir/.dkeys/*") {
 
 487       if ($link = readlink $f) {
 
 488         (undef,$to,$from,$file) = split('/',$link);
 
 490           $to   .= '@'.$mdomain if $to   !~ /@/;
 
 491           $from .= '@'.$mdomain if $from !~ /@/;
 
 492           if ($link ne "../$to/$from/$file") {
 
 493             symlink "../$to/$from/$file",$f;
 
 500   # fix spool layout: FROM and TO must have domains and must be lower case
 
 501   foreach $d ((glob "$spooldir/*/*"),(glob "$spooldir/*")) {
 
 502     if (not -l $d and -d $d and $d =~ m:(.+)/(.+):) {
 
 505       if ($b !~ /^@/ and $b !~ /^[A-Z_-]+$/) {
 
 506         if ($mdomain and $b !~ /@/) {
 
 507           rename $d,sprintf("%s/%s@%s",$p,lc($b),$mdomain);
 
 508         } elsif ($b ne lc($b)) {
 
 509           rename $d,sprintf("%s/%s",$p,lc($b));
 
 515   # split auth-ID and subuser file: @ --> @ @SUBUSER
 
 516   foreach my $u (glob "$spooldir/*@*") {
 
 517     next if -f "$u/\@SUBUSER";
 
 518     open my $idf,"$u/\@" or next;
 
 520     if (defined ($su = <$idf>) and $su =~ /\w/
 
 521         and open my $suf,">$u/\@SUBUSER") {
 
 523       while (defined ($su = <$idf>)) { print {$suf} $su }
 
 526       if (open my $idf,">$u/\@") {
 
 534   foreach my $sf (glob "$spooldir/*/\@SUBUSER") {
 
 535     $user = (split '/',$sf)[-2];
 
 539         if (/(.+\@.+):(.+)/) {
 
 540           ($subuser,$id) = ($1,$2);
 
 541           next if $subuser =~ /\*/;
 
 542           $skey = md5_hex("$user:$subuser:$id");
 
 543           if (open $skey,'>',"$skeydir/$skey") {
 
 544             print {$skey} "from=$subuser\n",
 
 549           mkdirp("$spooldir/$subuser/\@MAINUSER");
 
 550           symlink $skey,"$spooldir/$subuser/\@MAINUSER/$user";
 
 558   foreach my $gf (glob "$spooldir/*/\@GROUP/*") {
 
 560     # normalize group name
 
 561     if ($gf =~ m:(.+)/(.+):) {
 
 565       $g2 =~ s/[^\w\*%^+=:,.!-]/_/g;
 
 567         rename "$gd/$g1","$gd/$g2" and $gf = "$gd/$g2";
 
 570     $group = (split '/',$gf)[-1];
 
 571     $user  = (split '/',$gf)[-3];
 
 575         if (/(.+\@.+):(.+)/) {
 
 577           $gkey = md5_hex("$user:$group:$gm:$id");
 
 578           if (open $gkey,'>',"$gkeydir/$gkey") {
 
 579             print {$gkey} "from=$gm\n",
 
 585           mkdirp("$spooldir/$gm/\@GROUP");
 
 586           symlink "../../$user/\@GROUP/$group","$spooldir/$gm/\@GROUP/$group";
 
 598   die "cpav: $dd is not a directory" unless -d $dd;
 
 599   open P,"tar cf - @_ | su -c 'cd $dd; umask 022; tar xvf - 2>&1' fex |" 
 
 600     or die "cpav: cannot tar - $!\n";
 
 603     print "$_ --> $dd/$_\n" unless /\/$/;