#!/usr/local/bin/perl5 -w ############################################################################### # FILE: OpalCodeUpdate # PURPOSE: Update all OPAL code # # AUTHOR: Roger W L Jones # DATE: October 1995 # # RETURNS: 0 - OK # 1 - errors from ftp or named file wasn't ftp-ed # 2 - procedural errors # # CHANGES: # 6-Nov-98 M.Schroder Make proper use of .@sys for cra, src, lib directories # 23-Apr-98 M.Schroder update exp10, please... # 13-May-97 M.Schroder Use FilterCra.pl instaed of Cradle.machine # 27-Feb-97 M.Schroder remove the '.test' from filenames # 7-Jan-97 M.Schroder Fix problem with decoding modification # time of last years code (fileinfo) # 6-Mar-96 M.Schroder use perl5 -w (/afs/usr/local/etc/perl) # 15-May-96 M.Schroder suppress SUMMARY_LOG, use stdout instead # use perl 5.002 (/usr/local/bin/perl5) # 9-Jul-96 P.Routenburg changes so code update source is now # hpplus, not CERNVM; change parsing in # FILEINFO; check current database # modification times and copy if needed; # only create pro, etc links if $type=car # 3-Jul-96 M.Schroder initialise $processor_versions{$prefix} # before using it (avoids lots of warnings), # replace 'chop' by 'chomp' # NOTES: # ############################################################################### ;# check important environmental vars before proceeding require "pwd.pl"; &initpwd; $otop=$ENV{'otop'}; if (! $otop) {$otop='/afs/cern.ch/opal/offline';} # $otop='/afs/cern.ch/user/r/rwlj/public'; $onew=$ENV{'onew'}; if (! $onew) {$onew='/afs/cern.ch/opal/www/doc/opalnews';} $OPAL_P_DB=$ENV{'OPAL_P_DB'}; if (! $OPAL_P_DB) {$OPAL_P_DB='/afs/cern.ch/opal/offline/db';} $oUtl=$otop."/utl"; @OPAL_VERS=("pro","dev"); # OPAL software versions @OPAL_UNIX_FTYPES=("car","cra"); # OPAL file types on unix # Get month and day ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time); # $summary_log=join('_',"$otop/utl/update/run",$mday,$mon); # open (SUMMARY_LOG, ">$summary_log") # || die "Can not open $summary_log : $!\n"; $LIST="hostList"; # prefix for the name of a list of files #if ( ! -e $oUtl."/Cradle.machine" ){ # print "$0: missing $oUtl/Cradle.machine\n"; # exit 2; #} if ( ! -e $oUtl."/FilterCra.pl" ){ print "$0: missing $oUtl/FilterCra.pl\n"; exit 2; } ;# need to build a trap handler $returnOnError='( ! $? == 0 ) && return 1;'; chdir $oUtl; # First we make directory listings of what's in the code repository. $code_dir = "$otop/InstallProcs"; foreach $UnixFileType (@OPAL_UNIX_FTYPES) { foreach $ver (@OPAL_VERS) { local($listing)=join('.',$LIST,$ver,$UnixFileType); -e $listing && unlink $listing; `ls -lt $code_dir/$ver/*.$UnixFileType > $listing`; } # for each version } # for each file type ## Now we want to copy the files. As we get the cradle files, we ## want to change the '+USE,IBM' to '+USE,HPUX', and rename it as ## a '.cra' file. foreach $unixFileType (@OPAL_UNIX_FTYPES){ foreach $ver (@OPAL_VERS){ chdir $oUtl; # call the copy utility for each file type and each version # check the return code before proceeding if ( &NewGetCode($unixFileType,$ver) ){ print STDERR "$0: error returned by NewGetCode. Exiting...\n"; exit 1 } } #for each version } #for each file type unlink "hostList.*" ; ;# now create version lists 'VERlist and oversion.VER, used to create ;# environmental variables and symbolic links in links directory foreach $ver (@OPAL_VERS){ ;# set up out_list and out_file local variables; eg: prolist oversion.pro local($verlist) = ">$oUtl/".$ver."list"; open (OUT_FILE,">$oUtl/oversion.$ver.tmp"); open (OUT_FILEC,">$oUtl/oversion.$ver.tmpc"); open (OUT_FILEP,">$oUtl/oversion.$ver.tmpp"); open (OUT_LIST,$verlist); ;# remove old files first unlink $oUtl."/".$ver."list.tmp"; ;# make sure this is treated as Korn shell! print OUT_FILE "#!/usr/local/bin/ksh\n"; ## for safety, remove only links in $otop/links directory print "Remove all links in $otop/links/$ver directory\n"; chdir $otop."/links/".$ver ; # eval $exitOnError; eval $returnOnError; opendir(LINKLIST,"."); @allfiles = readdir(LINKLIST); closedir (LINKLIST); for ($i=2; $i<=$#allfiles; $i++){ # ( -l $i ) && unlink $i; if (-l "$allfiles[$i]") {unlink ("$allfiles[$i]"); } } ## now loop over tree in rope, geant, gopal trees # foreach $tree (@OPAL_PKGS) # { # print "Create version list of $ver files in $tree tree\n"; # # switch to appropriate directory # chdir join('/',$otop,$tree,$ver,"car") ; eval $exitOnError; # opendir(ENVLIST,"."); # @processors = readdir(ENVLIST); # closedir(ENVLIST); # for ($i=2; $i<= $#processors; $i++) # { # $module = $processors[$i]; # # This writes into the out_file lines like : # # version_gopal=128 ; export version_gopal # if ($module=~/([a-zA-Z]+)(\d+)/) # { # $pname=$1; # $vnum=$2; # print OUT_FILE "version_$pname=$vnum ; export version_$pname\n"; # # This writes into the out_filec lines like : # # setenv version_gopal 128 # print OUT_FILEC "setenv version_$pname $vnum\n"; # # This writes into the out_filep lines like : # # $ENV{'version_gopal'}=128; # print OUT_FILEP "\$ENV{'version_$pname'}=$vnum;\n"; # print OUT_LIST $pname.$vnum."\n"; # } # } # undef @processors; # } #end for each tree ## # mhs # print "Create version list of $ver files in $tree tree\n"; print "Create version list of $ver files\n"; chomp $all_ver{$ver}; @processors = split(/ /,$all_ver{$ver}); print "Version $ver\n Processor $all_ver{$ver}\n"; foreach $module (@processors){ # This writes into the out_file lines like : # version_gopal=128 ; export version_gopal if ($module=~/([a-zA-Z]+)(\d+)/){ $pname=$1; $vnum=$2; print OUT_FILE "version_$pname=$vnum ; export version_$pname\n"; # This writes into the out_filec lines like : # setenv version_gopal 128 print OUT_FILEC "setenv version_$pname $vnum\n"; # This writes into the out_filep lines like : # $ENV{'version_gopal'}=128; print OUT_FILEP "\$ENV{'version_$pname'}=$vnum;\n"; print OUT_LIST $pname.$vnum."\n"; } } undef @processors; close(OUT_FILE); close(OUT_FILEC); close(OUT_FILEP); close(OUT_LIST); # rename the $oversion.$ver.tmp file $oldver = join( '.', $oUtl."/oversion", $ver, "tmp" ); $newver = join( '.', $oUtl."/oversion", $ver ); print " $oldver\n"; if ( -e $oldver ){ rename($oldver, $newver); chmod 0755, $newver; } $oldver = join( '.', $oUtl."/oversion", $ver, "tmpc" ); $newver = join( '.', $oUtl."/oversion", $ver, "csh" ); if ( -e $oldver ){ rename($oldver, $newver); chmod 0755, $newver; } $oldver = join( '.', $oUtl."/oversion", $ver, "tmpp" ); $newver = join( '.', $oUtl."/oversion", $ver, "perl" ); if ( -e $oldver ){ rename($oldver, $newver); chmod 0755, $newver; } ;# rename the $ver"list" tmp file $oldver = join( '.', $oUtl."/".$ver."list", "tmp" ); $newver = $oUtl."/".$ver."list"; if ( -e $oldver ){ rename($oldver, $newver); chmod 0755, $newver; } } #for each version ;# it is time to source the environmental vars, create the symbolic links ;# and invoke make. foreach $ver (@OPAL_VERS) { print "@OPAL_VERS\n"; &NewVersionLinks($ver) ;} #for each version ;# make the code, all versions, all trees chdir $otop."/utl"; system ("make -f Makefile.opal"); # Check if the current opalcal databases have changed in the past 24 hrs. print "Checking databases ... \n"; $dbdir = '/afs/cern.ch/opal/opcal/db'; $dbmodtime = (-M "$dbdir/opalcal.rzexp10"); if ($dbmodtime < 1) { `cp $dbdir/opalcal.rzexp10 $otop/db`; } $dbmodtime = (-M "$dbdir/sudb.rzdata"); if ($dbmodtime < 1) { `cp $dbdir/sudb.rzdata $otop/db`; `cp $dbdir/sudb.fadata $otop/db`; } open(DATESTAMP,"/bin/date|"); while (defined($datestamp = )) { print "\n $datestamp\n"; } close (DATESTAMP); print "Code update finished for today\n"; exit 0; sub NewGetCode { #****************************************************************************** #* Routine: NewCodeGet #* PURPOSE: Task which copies all files of the requested type and version #* for OPAL code updating #* #* AUTHOR: Roger Jones #* DATE: October 1995 #* #* CHANGES: #* #* NOTES: The input list is processed to form a list of versions for each #* processor, in an associative array keyed by processor type #* (e.g. ROPE). #* The file details for each processor are stored as a list string #* in an associative array keyed by processor name (e.g. ROPE409) #* The version lists are sorted to determine the current version. #* The main processor of each class is dealt with first to see #* if the dev/pro/old links need to be changed. #* #*****************************************************************************/ local(@args) = @_ ; @pkgName = ( "gopal", "geant", "rope" ); # well, these aren't really bad; we just don't want to copy them %badList = ( "us", 1, "gmgm", 1, "cjop", 1, "cjcha", 1, "db", 1, "ida", 1, "oda", 1, "simp", 1, "sgml", 1, "show", 1 ); #****************************************************************************** #* This is the steering #****************************************************************************** # get important environment variables $otop & $OPAL_P_DB # $otop is the updating top directory name $otop=$ENV{'otop'}; if (! $otop) {$otop='/afs/cern.ch/opal/offline';} # $otop='/afs/cern.ch/user/r/rwlj/public'; # $OPAL_P_DB is the sudb tree top directory name $OPAL_P_DB=$ENV{'OPAL_P_DB'}; if (! $OPAL_P_DB) {$OPAL_P_DB='/afs/cern.ch/opal/offline/db';} #if (! $OPAL_P_DB ) {$OPAL_P_DB = "/afs/cern.ch/user/r/rwlj/public/db";} # check for correct command line args if ( $#args != 1 ){ print STDERR "Usage: NewGetCode FILETYPE VERSION\n"; print STDERR "Where: FILETYPE is one of CAR CRA FADATA\n"; print STDERR "Where: VERSION is one of PRO DEV\n"; goto term; } $fail = 0; if ($args[0] =~ /^car/ || $args[0] =~ /^cra/) {$type = $args[0];} else {$fail = 1;} if ($args[1] =~ /^pro/ || $args[1] =~ /^dev/) {$verType = $args[1];} else {$fail = 1;} if ( $fail ){ print STDERR "Illegal arguments $args[0], $args[1] \n"; print STDERR "Usage: NewGetCode FILETYPE VERSION\n"; print STDERR "Where: FILETYPE is one of CAR CRA FADATA\n"; print STDERR "Where: VERSION is one of PRO DEV\n"; goto term; } # now prepare the file pathnames for future checking # each of gopal, geant, rope for ( $i=0 ; $i<3; $i++){ $pkgs{$pkgName[$i]} = join('/',$otop,$pkgName[$i],$verType,$type); } #$pkgs{'db'}=$OPAL_P_DB; # and the su database &FILEINFO ; if ($args[0] =~ /^car/ ) { $all_ver{$verType} .= join(" ",values %current) . " "; # Loop over the package classes for ( $i=0; $i<=$#pkgName; $i++){ if ($current{$pkgName[$i]}){ # The current version of the `key' processor does not exist in the $verType directory if ( ! -e $pkgs{$pkgName[$i]}."/".$current{$pkgName[$i]}.".".$type ){ # This is where we should change the links before we do any damage! # See if the new pro directory already exists chdir $otop."/".$pkgName[$i]; local($newlink) = $current{$pkgName[$i]}; $linkname=$verType; $oldlink = readlink($linkname); -l $linkname && unlink $linkname; if (! -d $newlink ){ # make the required directory mkdir($newlink,0751); chdir $newlink; &MAKEDIRS ; chdir $otop."/".$pkgName[$i]; } ;# link the new $verType directory to "$verType" symlink($newlink,$linkname); ;# If the pro has changed, we need to reset "old" as well ;# and make a new "dev" if it is not already there if ($verType eq "pro"){ local($linkold) = "old"; ;# if there is an "old" link, delete it -l $linkold && unlink $linkold; ;# link the old pro directory to "old" symlink($oldlink,$linkold); ;# Now for the new "dev" directory local($linkdev) = "dev"; ;# if there is an "dev" link, delete it ;# $newlink is not numeric, use 'le' instead of '<=' ;# if (-l $linkdev && (readlink($linkdev) <= $newlink) ) if (-l $linkdev && (readlink($linkdev) le $newlink) ) { unlink $linkdev; ;# work out the next "dev" directory name $newlink =~ m/([a-zA-z]+)(\d+)/; local($newvers) = $2; $newvers++; $newdev=$1.$newvers; if (! -d $newdev ){ # make the required directory mkdir($newdev,0751); chdir $newdev; &MAKEDIRS ; chdir $otop."/".$pkgName[$i]; ;# set the link for the new "dev" directory } symlink($newdev,$linkdev); } } } } } } #Now we hand over to the copy process ©FILES; undef %processor_versions; undef %hostinfo; undef %current; return ""; } ;# End of NewGetCode sub FILEINFO { # This subroutine reads the input file list and prepares the associative # arrays of processors # # To look up month number corresponding to alpha representation, use this. %month_nums = ( "Jan","0","Feb","1","Mar","2","Apr","3","May","4", "Jun","5","Jul","6","Aug","7","Sep","8","Oct","9","Nov","10","Dec","11"); # Get current time info. Month is element 4 and year element 5. @current_time = localtime(time); # Make the list filename $findlist = "hostList." . $verType . "." . $type; # Check if the list really exists # if ( -r $findlist ) { # mhs ... and is not empty if ( -r $findlist && !-z $findlist ) { # now open the file hostList for processing unless ( open(HOSTLIST,$findlist ) ){ print STDERR "NewGetCode: Cannot open file $findlist"; return 1; } # read each line of the file; parse it into arrays and lists while () { # This is doing a pattern match for the processor name mod. date and time # Fields matched in the round brackets are passed into $1, $2 etc if (/InstallProcs/) { if (/:/) { # file is under 6 months old /.*\s(\w{3,3})\s+(\d{1,2})\s(\d+):(\d{2,2}).*$ver\/(\w*)\..*/; $lname = $5; $lmday = $2; $lmon = $month_nums{$1}; $lyear = $current_time[5]; # if ($current_time[4] <= 2) { # Is processor from this year, or last? # if ($lmon >= 9) {$year--;} # } # better try this : if ($current_time[4] < $lmon) { # This processor is from last year... $lyear--; } $lhours = $3; $lmin = $4; $lsec = 0; } else { # file is over 6 months old /.*\s(\w{3,3})\s+(\d{1,2})\s+(\d{4,4}).*$ver\/(\w*)\..*/; $lname = $4; $lmday = $2; $lmon = $month_nums{$1}; $lyear = $3-1900; $lhours = 0; $lmin = 0; $lsec = 0; } require 'timelocal.pl'; # Template for info: name prefix version pkgType modtime $lname =~ /([a-z]+)(\d*)/; local($prefix) = $1; if (! $badList{$prefix}){ local($version) = $2; local($pkgType) = ""; # which tree should we check in ?? if( $lname =~ /gopa/ ) { $pkgType = 'gopal'; } elsif ( $lname =~ /gean/ ) { $pkgType = 'geant'; } # elsif($type eq 'db' ) # { $pkgType = 'db'; } else { $pkgType = 'rope'; }; local($modtime) = &timelocal($lsec,$lmin,$lhours,$lmday,$lmon,$lyear); $hostinfo{$lname} = $lname; $hostinfo{$lname} .= " " . $prefix; $hostinfo{$lname} .= " " . $version; $hostinfo{$lname} .= " " . $pkgType; $hostinfo{$lname} .= " " . $modtime; if ( exists $processor_versions{$prefix} ) { $processor_versions{$prefix} .= " " . $lname; } else { $processor_versions{$prefix} = $lname; } } } } close (HOSTLIST); foreach $proc (keys(%processor_versions)) { if ($processor_versions{$proc}) { chomp($processor_versions{$proc}); @versions = split(/ /,$processor_versions{$proc}); @versions = reverse sort @versions; $current{$proc} = $versions[0]; } } } return ""; } sub COPYFILES { # ^^^^^^^^^ # This subroutine reads the input file list and prepares the associative # arrays of processors # local ( $copyCount ) = 0; foreach $proc (keys(%processor_versions)){ if ($current{$proc}){ local ( $copyFile ) = ""; local ( $name,$prefix,$version,$pkgType,$modtime) = split ( / /,$hostinfo{$current{$proc}} ); # The current version of the processor does not exist in the $verType directory local ( $file ) = $pkgs{$pkgType}."/".$current{$proc}.".".$type; local ( $hostfile ) = $current{$proc}.".".$type; if ( ! -e $file ){ $copyFile = 1; } else{ # See if the master copy is newer than the local one require 'stat.pl'; &Stat( $file ); if( $st_mtime < $modtime ) { $copyFile = 1; } } if ( $copyFile ){ `cp $code_dir/$verType/$hostfile $file`; $copyCount++; # This is where we should prepend the Cradle.machine file if ( $type eq "cra"){ # $cramach = $oUtl."/Cradle.machine"; # if ( ! -e $cramach){ # print STDERR "There is no $cramach file!\n"; exit 1; # } # local($copy) = $pkgs{$pkgType}."/".$current{$proc}.".cradle";; # rename ($file,$copy); # open (CRAMACH,"<$cramach"); # open (COPY,"<$copy"); # open (TARGET,">$file"); # while () {print TARGET ; } # close (CRAMACH); # while () { print TARGET ; } # close (COPY); # close (TARGET); # unlink $copy; $rc = system "FilterCra.pl $file"; warn "FilterCra.pl returned $rc\n" unless $rc == 0; } } } } print "$copyCount $verType $type file(s) copied today\n" ; return ""; # At this place we exit abnormally term: return 1; } sub NewVersionLinks { # ^^^^^^^^^^^^^^^ ############################################################################### # FILE: NewVersionLinks # PURPOSE: Sets the version numbers of rope modules and updates the links # # AUTHOR: RWL Jones # DATE: October 1995 # # RETURNS: 0 - OK # 1 - errors # # # CHANGES: # NOTES: Usage: OpalSetVersions ver # Where: 'ver' is one of pro or dev # ############################################################################### local(@argl) = @_ ; ;# check the arguments supplied if ( $#argl < 0 ){ print "Usage: $0 VER\n"; print "Where: VER is one of 'pro' or 'dev'\n"; print "EG: $0 pro\n"; exit 1; } ;# need to build a trap handler $returnOnError='( ! $? == 0 ) && return 1;'; if ( $argl[0] ne "pro" && $argl[0] ne "dev" ){ print "$0: invalid argument 0. Valid args are pro or dev\n"; print " $argl \n"; exit 1; } ;# An optional second argument allows you to skip the pro tree, if ;# the first argument was not pro if ( $#argl == 1 ){ if ( $argl[1] eq "ignorePro" && $argl[0] ne "pro" ) { $ignorePro="YES";} } ;# Add pro to the front of the list, because pro will cover most ;# of the OPAL modules. (unless of course, we are ignoring it) if ( $argl[0] eq "pro" ) { @verList=("pro"); } elsif ( ! $ignorePro ) { @verList=("pro",$argl[0]); } else { @verList=($argl[0]); } require($oUtl."/oversion.pro.perl") ; # chdir $otop."/links/".$argl[0] ; eval $returnOnError; chdir $otop."/links/".$argl[0] || die "Can not change to $otop/links/$argl[0] : $!\n"; foreach $ver (@verList){ ;# source the oversion.$ver file to set up OPAL version numbers. local($versionfile) = $oUtl."/oversion.".$ver.".perl"; ( ! -e $versionfile ) && print "$0: No $versionfile file found" && exit 1; print "Source the version environmental variables\n"; # Problem when dev version is empty?? # Pro should always be OK, what if dev dir has no cra and car files?? if ( ! -z "$versionfile") { require ($versionfile); } ;# make the pro links in the dev version just in case if ( $ver eq "dev"){ ;# set up out_list and out_file local variables $inputList="<".$oUtl."/prolist"; print "Create links from list of modules in $inputList\n"; open (IN_LIST, $inputList); ;# now loop over while (){ # get processor name with extension stripped off chomp; local($module) = $_ ; if ($module =~ s/([a-zA-Z0-9]*)\.car$/$1/){ $allLinks = ""; if( $module =~ /gopa/ ) { $tree = 'gopal'; } elsif ( $module =~ /gean/ ) { $tree = 'geant'; } else { $tree = 'rope'; $allLinks = "YES";} if (-e $module.".car" && -l $module.".car" ) {unlink $module.".car" ;} symlink(join('/',$otop,$tree,"pro/car",$module.".car"),$module.".car"); if ( $allLinks || $module =~ /gopal/ || $module =~ /geant/){ if (-e $module.".cra" && -l $module.".cra" ) {unlink $module.".cra" ;} symlink(join('/',$otop,$tree,"pro/cra",$module.".cra"),$module.".cra"); if (-e $module.".a" && -l $module.".a" ) {unlink $module.".a" ;} symlink(join('/',$otop,$tree,"pro/lib/lib".$module.".a"),"lib".$module.".a"); } } } close(IN_LIST); } ;# set up out_list and out_file local variables $inputList="<".$oUtl."/".$ver."list"; print "Create links from list of modules in $inputList\n"; open (IN_LIST, $inputList); ;# now loop over while (){ # get processor name with extension stripped off chomp; local($module) = $_ ; $module =~ s/(.*)\.car/$1/; $allLinks = ""; if( $module =~ /gopa/ ) { $tree = 'gopal'; } elsif ( $module =~ /gean/ ) { $tree = 'geant'; } else { $tree = 'rope'; $allLinks = "YES";} if (-e $module.".car" && -l $module.".car" ) {unlink $module.".car" ;} symlink(join('/',$otop,$tree,$ver,"car",$module.".car"),$module.".car"); if ( $allLinks || $module =~ /gopal/ || $module =~ /geant/){ if (-e $module.".cra" && -l $module.".cra" ) {unlink $module.".cra" ;} symlink(join('/',$otop,$tree,$ver,"cra",$module.".cra"),$module.".cra"); if (-e $module.".a" && -l $module.".a" ) {unlink $module.".a" ;} symlink(join('/',$otop,$tree,$ver,"lib/lib".$module.".a"),"lib".$module.".a"); } } close(IN_LIST); ## treat generators as never_changing for the moment if ( $ver eq "pro" ){ if ( -d $otop."/ogen" ){ foreach $xpr ("aria31gp","jets72gp","herwig43"){ if (-e $xpr.".car" && -l $xpr.".car" ) {unlink $xpr.".car" ;} symlink($otop."/ogen/".$xpr.".car",$xpr.".car"); if (-e $xpr.".a" && -l $xpr.".a" ) {unlink $xpr.".a" ;} symlink($otop."/ogen/".$xpr.".a",$xpr.".a"); } } # if ( -e "dzdoc.car" && -l "dzdoc.car" ) {unlink "dzdoc.car";} symlink($otop."/rope/pro/car/dzdoc.car","dzdoc.car"); if ( -e "dzdoc.cra" && -l "dzdoc.cra" ) {unlink "dzdoc.cra";} symlink($otop."/rope/pro/cra/dzdoc.cra","dzdoc.cra"); if ( -e "libdzdoc.a" && -l "libdzdoc.a" ) {unlink "libdzdoc.a";} symlink($otop."/rope/pro/lib/libdzdoc.a","libdzdoc.a"); # if ( -e "zebra.car" && -l "zebra.car" ) {unlink "zebra.car";} symlink("/cern/".$ver."/src/car/zebra.car","zebra.car"); if ( -e "zecde.car" && -l "zecde.car" ) {unlink "zecde.car";} symlink("/cern/".$ver."/src/car/zebra.car","zecde.car"); if ( -e "zebra" && -l "zebra" ) {unlink "zebra";} symlink("/cern/".$ver."/src/car/zebra.car","zebra"); if ( -e "zecde" && -l "zecde" ) {unlink "zecde";} symlink("/cern/".$ver."/src/car/zebra.car","zecde"); } } #for each version return 0; } sub MAKEDIRS { # ^^^^^^^^ local(@subdirs) = ("bin","cra","exe","lib","src"); ( ! -d "car") && mkdir("car",0751); ;# This bit is special for AFS-like systems open(SYSTEM,"fs sysname |"); local($system) = ; close(SYSTEM); ($system) || die(" Cannot find which system we are on\n"); chomp $system; $system =~ s/.*\'(.+)\'/$1/; (! -d $system) && mkdir($system,0751); foreach $dir (@subdirs){ local($newdir) = $system."/".$dir; if (! -d "$newdir"){ local($linkname) = ".\@sys/$dir"; mkdir($newdir,0751); symlink($linkname,$dir); } } }