--- loncom/lonnet/perl/lonnet.pm 2006/05/15 23:42:52 1.683.2.21 +++ loncom/lonnet/perl/lonnet.pm 2005/12/22 20:56:28 1.687 @@ -1,7 +1,7 @@ # The LearningOnline Network # TCP networking package # -# $Id: lonnet.pm,v 1.683.2.21 2006/05/15 23:42:52 albertel Exp $ +# $Id: lonnet.pm,v 1.687 2005/12/22 20:56:28 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -271,9 +271,7 @@ sub transfer_profile_to_env { my %Remove; for ($envi=0;$envi<=$#profile;$envi++) { chomp($profile[$envi]); - my ($envname,$envvalue)=split(/=/,$profile[$envi],2); - $envname=&unescape($envname); - $envvalue=&unescape($envvalue); + my ($envname,$envvalue)=split(/=/,$profile[$envi]); $env{$envname} = $envvalue; if (my ($key,$time) = ($envname =~ /^(cgi\.(\d+)_\d+\.)/)) { if ($time < time-300) { @@ -325,9 +323,7 @@ sub appenv { for (my $i=0; $i<=$#oldenv; $i++) { chomp($oldenv[$i]); if ($oldenv[$i] ne '') { - my ($name,$value)=split(/=/,$oldenv[$i],2); - $name=&unescape($name); - $value=&unescape($value); + my ($name,$value)=split(/=/,$oldenv[$i]); unless (defined($newenv{$name})) { $newenv{$name}=$value; } @@ -340,7 +336,7 @@ sub appenv { } my $newname; foreach $newname (keys %newenv) { - print $fh &escape($newname).'='.&escape($newenv{$newname})."\n"; + print $fh "$newname=$newenv{$newname}\n"; } close($fh); } @@ -352,6 +348,7 @@ sub appenv { sub delenv { my $delthis=shift; + my %newenv=(); if (($delthis=~/user\.role/) || ($delthis=~/user\.priv/)) { &logthis("WARNING: ". "Attempt to delete from environment ".$delthis); @@ -383,14 +380,12 @@ sub delenv { close($fh); return 'error: '.$!; } - foreach my $cur_key (@oldenv) { - my $unescaped_cur_key = &unescape($cur_key); - if ($unescaped_cur_key=~/^$delthis/) { - my ($key) = split('=',$cur_key,2); - $key = &unescape($key); + foreach (@oldenv) { + if ($_=~/^$delthis/) { + my ($key,undef) = split('=',$_); delete($env{$key}); } else { - print $fh $cur_key; + print $fh $_; } } close($fh); @@ -952,50 +947,13 @@ sub userenvironment { sub studentphoto { my ($udom,$unam,$ext) = @_; my $home=&Apache::lonnet::homeserver($unam,$udom); - if (defined($env{'request.course.id'})) { - if ($env{'course.'.$env{'request.course.id'}.'.internal.showphoto'}) { - if ($udom eq $env{'course.'.$env{'request.course.id'}.'.domain'}) { - return(&retrievestudentphoto($udom,$unam,$ext)); - } else { - my ($result,$perm_reqd)= - &Apache::lonnet::auto_photo_permission($unam,$udom); - if ($result eq 'ok') { - if (!($perm_reqd eq 'yes')) { - return(&retrievestudentphoto($udom,$unam,$ext)); - } - } - } - } - } else { - my ($result,$perm_reqd) = - &Apache::lonnet::auto_photo_permission($unam,$udom); - if ($result eq 'ok') { - if (!($perm_reqd eq 'yes')) { - return(&retrievestudentphoto($udom,$unam,$ext)); - } - } - } - return '/adm/lonKaputt/lonlogo_broken.gif'; -} - -sub retrievestudentphoto { - my ($udom,$unam,$ext,$type) = @_; - my $home=&Apache::lonnet::homeserver($unam,$udom); - my $ret=&Apache::lonnet::reply("studentphoto:$udom:$unam:$ext:$type",$home); - if ($ret eq 'ok') { - my $url="/uploaded/$udom/$unam/internal/studentphoto.$ext"; - if ($type eq 'thumbnail') { - $url="/uploaded/$udom/$unam/internal/studentphoto_tn.$ext"; - } - my $tokenurl=&Apache::lonnet::tokenwrapper($url); - return $tokenurl; - } else { - if ($type eq 'thumbnail') { - return '/adm/lonKaputt/genericstudent_tn.gif'; - } else { - return '/adm/lonKaputt/lonlogo_broken.gif'; - } + my $ret=&Apache::lonnet::reply("studentphoto:$udom:$unam:$ext",$home); + my $url="/uploaded/$udom/$unam/internal/studentphoto.".$ext; + if ($ret ne 'ok') { + return '/adm/lonKaputt/lonlogo_broken.gif'; } + my $tokenurl=&Apache::lonnet::tokenwrapper($url); + return $tokenurl; } # -------------------------------------------------------------------- New chat @@ -1322,8 +1280,15 @@ sub clean_filename { } # --------------- Take an uploaded file and put it into the userfiles directory -# input: name of form element, coursedoc=1 means this is for the course -# output: url of file in userspace +# input: $formname - the contents of the file are in $env{"form.$formname"} +# the desired filenam is in $env{"form.$formname"} +# $coursedoc - if true up to the current course +# if false +# $subdir - directory in userfile to store the file into +# $parser, $allfiles, $codebase - unknown +# +# output: url of file in userspace, or error: +# or /adm/notfound.html if failure to upload occurse sub userfileupload { @@ -3052,9 +3017,8 @@ sub tmpput { # ------------------------------------------------------------ tmpget interface sub tmpget { - my ($token,$server)=@_; - if (!defined($server)) { $server = $perlvar{'lonHostID'}; } - my $rep=&reply("tmpget:$token",$server); + my ($token)=@_; + my $rep=&reply("tmpget:$token",$perlvar{'lonHostID'}); my %returnhash; foreach my $item (split(/\&/,$rep)) { my ($key,$value)=split(/=/,$item); @@ -3063,13 +3027,6 @@ sub tmpget { return %returnhash; } -# ------------------------------------------------------------ tmpget interface -sub tmpdel { - my ($token,$server)=@_; - if (!defined($server)) { $server = $perlvar{'lonHostID'}; } - return &reply("tmpdel:$token",$server); -} - # ---------------------------------------------- Custom access rule evaluation sub customaccess { @@ -3108,7 +3065,6 @@ sub customaccess { sub allowed { my ($priv,$uri,$symb)=@_; - my $ver_orguri=$uri; $uri=&deversion($uri); my $orguri=$uri; $uri=&declutter($uri); @@ -3209,7 +3165,7 @@ sub allowed { $thisallowed.=$1; } } else { - my $refuri = $env{'httpref.'.$orguri} || $env{'httpref.'.$ver_orguri}; + my $refuri=$env{'httpref.'.$orguri}; if ($refuri) { if ($refuri =~ m|^/adm/|) { $thisallowed='F'; @@ -3389,21 +3345,17 @@ sub allowed { my $unamedom=$env{'user.name'}.':'.$env{'user.domain'}; if ($env{'course.'.$env{'request.course.id'}.'.'.$priv.'.roles.denied'} =~/\Q$rolecode\E/) { - if ($priv ne 'pch') { - &logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}.':'. - 'Denied by role: '.$priv.' for '.$uri.' as '.$rolecode.' in '. - $env{'request.course.id'}); - } + &logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}.':'. + 'Denied by role: '.$priv.' for '.$uri.' as '.$rolecode.' in '. + $env{'request.course.id'}); return ''; } if ($env{'course.'.$env{'request.course.id'}.'.'.$priv.'.users.denied'} =~/\Q$unamedom\E/) { - if ($priv ne 'pch') { - &logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}. - 'Denied by user: '.$priv.' for '.$uri.' as '.$unamedom.' in '. - $env{'request.course.id'}); - } + &logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}. + 'Denied by user: '.$priv.' for '.$uri.' as '.$unamedom.' in '. + $env{'request.course.id'}); return ''; } } @@ -3413,11 +3365,9 @@ sub allowed { if ($thisallowed=~/R/) { my $rolecode=(split(/\./,$env{'request.role'}))[0]; if (&metadata($uri,'roledeny')=~/\Q$rolecode\E/) { - if ($priv ne 'pch') { - &logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}.':'. - 'Denied by role: '.$priv.' for '.$uri.' as '.$rolecode); - } - return ''; + &logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}.':'. + 'Denied by role: '.$priv.' for '.$uri.' as '.$rolecode); + return ''; } } @@ -3440,17 +3390,15 @@ sub allowed { return 'F'; } -sub split_uri_for_cond { - my $uri=&deversion(&declutter(shift)); - my @uriparts=split(/\//,$uri); - my $filename=pop(@uriparts); - my $pathname=join('/',@uriparts); - return ($pathname,$filename); -} # --------------------------------------------------- Is a resource on the map? sub is_on_map { - my ($pathname,$filename) = &split_uri_for_cond(shift); + my $uri=&deversion(&declutter(shift)); + my @uriparts=split(/\//,$uri); + my $filename=$uriparts[$#uriparts]; + my $pathname=$uri; + $pathname=~s|/\Q$filename\E$||; + $pathname=~s/^adm\/wrapper\///; #Trying to find the conditional for the file my $match=($env{'acc.res.'.$env{'request.course.id'}.'.'.$pathname}=~ /\&\Q$filename\E\:([\d\|]+)\&/); @@ -3723,82 +3671,6 @@ sub auto_create_password { return ($authparam,$create_passwd,$authchk); } -sub auto_photo_permission { - my ($cnum,$cdom,$students) = @_; - my $homeserver = &homeserver($cnum,$cdom); - my ($outcome,$perm_reqd,$conditions) = - split(/:/,&unescape(&reply('autophotopermission:'.$cdom,$homeserver)),3); - if ($outcome =~ /^(con_lost|unknown_cmd|no_such_host)$/) { - return (undef,undef); - } - return ($outcome,$perm_reqd,$conditions); -} - -sub auto_checkphotos { - my ($uname,$udom,$pid) = @_; - my $homeserver = &homeserver($uname,$udom); - my ($result,$resulttype); - my $outcome = &unescape(&reply('autophotocheck:'.&escape($udom).':'. - &escape($uname).':'.&escape($pid), - $homeserver)); - if ($outcome =~ /^(con_lost|unknown_cmd|no_such_host)$/) { - return (undef,undef); - } - if ($outcome) { - ($result,$resulttype) = split(/:/,$outcome); - } - return ($result,$resulttype); -} - -sub auto_photochoice { - my ($cnum,$cdom) = @_; - my $homeserver = &homeserver($cnum,$cdom); - my ($update,$comment) = split(/:/,&unescape(&reply('autophotochoice:'. - &escape($cdom), - $homeserver))); - if ($update =~ /^(con_lost|unknown_cmd|no_such_host)$/) { - return (undef,undef); - } - return ($update,$comment); -} - -sub auto_photoupdate { - my ($affiliatesref,$dom,$cnum,$photo) = @_; - my $homeserver = &homeserver($cnum,$dom); - my $host=$hostname{$homeserver}; - my $cmd = ''; - my $maxtries = 1; - foreach (keys %{$affiliatesref}) { - $cmd .= $_.'='.join(",",@{$$affiliatesref{$_}}).'%%'; - } - $cmd =~ s/%%$//; - $cmd = &escape($cmd); - my $query = 'institutionalphotos'; - my $queryid=&reply("querysend:".$query.':'.$dom.':'.$cnum.':'.$cmd,$homeserver); - unless ($queryid=~/^\Q$host\E\_/) { - &logthis('institutionalphotos: invalid queryid: '.$queryid.' for host: '.$host.' and homeserver: '.$homeserver.' and course: '.$cnum); - return 'error: '.$queryid; - } - my $reply = &get_query_reply($queryid); - my $tries = 1; - while (($reply=~/^timeout/) && ($tries < $maxtries)) { - $reply = &get_query_reply($queryid); - $tries ++; - } - if ( ($reply =~/^timeout/) || ($reply =~/^error/) ) { - &logthis('institutionalphotos error: '.$reply.' for '.$dom.' '.$env{'user.name'}.' for '.$queryid.' course: '.$cnum.' maxtries: '.$maxtries.' tries: '.$tries); - } else { - my @responses = split(/:/,$reply); - my $outcome = shift(@responses); - foreach my $item (@responses) { - my ($key,$value) = split(/=/,$item); - $$photo{$key} = $value; - } - return $outcome; - } - return 'error'; -} - sub auto_instcode_format { my ($caller,$codedom,$instcodes,$codes,$codetitles,$cat_titles,$cat_order) = @_; my $courses = ''; @@ -3850,6 +3722,10 @@ sub modify_group_roles { my $role = 'gr/'.&escape($userprivs); my ($uname,$udom) = split(/:/,$user); my $result = &assignrole($udom,$uname,$url,$role,$end,$start); + if ($result eq 'ok') { + &devalidate_getgroups_cache($udom,$uname,$cdom,$cnum); + } + return $result; } @@ -4653,30 +4529,11 @@ sub GetFileTimestamp { # -------------------------------------------------------- Value of a Condition -# gets the value of a specific preevaluated condition -# stored in the string $env{user.state.} -# or looks up a condition reference in the bighash and if if hasn't -# already been evaluated recurses into docondval to get the value of -# the condition, then memoizing it to -# $env{user.state..} sub directcondval { my $number=shift; if (!defined($env{'user.state.'.$env{'request.course.id'}})) { &Apache::lonuserstate::evalstate(); } - if (exists($env{'user.state.'.$env{'request.course.id'}.".$number"})) { - return $env{'user.state.'.$env{'request.course.id'}.".$number"}; - } elsif ($number =~ /^_/) { - my $sub_condition; - if (tie(my %bighash,'GDBM_File',$env{'request.course.fn'}.'.db', - &GDBM_READER(),0640)) { - $sub_condition=$bighash{'conditions'.$number}; - untie(%bighash); - } - my $value = &docondval($sub_condition); - &appenv('user.state.'.$env{'request.course.id'}.".$number" => $value); - return $value; - } if ($env{'user.state.'.$env{'request.course.id'}}) { return substr($env{'user.state.'.$env{'request.course.id'}},$number,1); } else { @@ -4684,49 +4541,43 @@ sub directcondval { } } -# get the collection of conditions for this resource sub condval { my $condidx=shift; + my $result=0; my $allpathcond=''; - foreach my $cond (split(/\|/,$condidx)) { - if (defined($env{'acc.cond.'.$env{'request.course.id'}.'.'.$cond})) { - $allpathcond.= - '('.$env{'acc.cond.'.$env{'request.course.id'}.'.'.$cond}.')|'; - } + foreach (split(/\|/,$condidx)) { + if (defined($env{'acc.cond.'.$env{'request.course.id'}.'.'.$_})) { + $allpathcond.= + '('.$env{'acc.cond.'.$env{'request.course.id'}.'.'.$_}.')|'; + } } $allpathcond=~s/\|$//; - return &docondval($allpathcond); -} - -#evaluates an expression of conditions -sub docondval { - my ($allpathcond) = @_; - my $result=0; - if ($env{'request.course.id'} - && defined($allpathcond)) { - my $operand='|'; - my @stack; - foreach my $chunk ($allpathcond=~/(\d+|_\d+\.\d+|\(|\)|\&|\|)/g) { - if ($chunk eq '(') { - push @stack,($operand,$result); - } elsif ($chunk eq ')') { - my $before=pop @stack; - if (pop @stack eq '&') { - $result=$result>$before?$before:$result; - } else { - $result=$result>$before?$result:$before; - } - } elsif (($chunk eq '&') || ($chunk eq '|')) { - $operand=$chunk; - } else { - my $new=directcondval($chunk); - if ($operand eq '&') { - $result=$result>$new?$new:$result; - } else { - $result=$result>$new?$result:$new; - } - } - } + if ($env{'request.course.id'}) { + if ($allpathcond) { + my $operand='|'; + my @stack; + foreach ($allpathcond=~/(\d+|\(|\)|\&|\|)/g) { + if ($_ eq '(') { + push @stack,($operand,$result) + } elsif ($_ eq ')') { + my $before=pop @stack; + if (pop @stack eq '&') { + $result=$result>$before?$before:$result; + } else { + $result=$result>$before?$result:$before; + } + } elsif (($_ eq '&') || ($_ eq '|')) { + $operand=$_; + } else { + my $new=directcondval($_); + if ($operand eq '&') { + $result=$result>$new?$new:$result; + } else { + $result=$result>$new?$result:$new; + } + } + } + } } return $result; } @@ -4958,7 +4809,8 @@ sub EXT { return $env{'course.'.$courseid.'.'.$spacequalifierrest}; } elsif ($realm eq 'resource') { - my $section; + my ($section,$group); + my @groups = (); if (defined($courseid) && $courseid eq $env{'request.course.id'}) { if (!$symbparm) { $symbparm=&symbread(); } } @@ -4970,7 +4822,7 @@ sub EXT { # ----------------------------------------------------- Cascading lookup scheme my $symbp=$symbparm; - my $mapp=&deversion((&decode_symb($symbp))[0]); + my $mapp=(&decode_symb($symbp))[0]; my $symbparm=$symbp.'.'.$spacequalifierrest; my $mapparm=$mapp.'___(all).'.$spacequalifierrest; @@ -4978,14 +4830,29 @@ sub EXT { if (($env{'user.name'} eq $uname) && ($env{'user.domain'} eq $udom)) { $section=$env{'request.course.sec'}; + @groups=split(/:/,$env{'request.course.groups'}); + if (@groups > 0) { + @groups = sort(@groups); + $group = $groups[0]; + } } else { if (! defined($usection)) { $section=&getsection($udom,$uname,$courseid); } else { $section = $usection; } + my $grouplist = &get_users_groups($udom,$uname,$courseid); + if ($grouplist) { + @groups = split(/:/,$grouplist); + @groups = sort(@groups); + $group = $groups[0]; + } } + my $grplevel=$courseid.'.['.$group.'].'.$spacequalifierrest; + my $grplevelr=$courseid.'.['.$group.'].'.$symbparm; + my $grplevelm=$courseid.'.['.$group.'].'.$mapparm; + my $seclevel=$courseid.'.['.$section.'].'.$spacequalifierrest; my $seclevelr=$courseid.'.['.$section.'].'.$symbparm; my $seclevelm=$courseid.'.['.$section.'].'.$mapparm; @@ -5003,8 +4870,17 @@ sub EXT { if (defined($userreply)) { return $userreply; } # ------------------------------------------------ second, check some of course + my $coursereply; + if (defined($group)) { + $coursereply = &resdata($env{'course.'.$courseid.'.num'}, + $env{'course.'.$courseid.'.domain'}, + 'course', + ($grplevelr,$grplevelm,$grplevel, + $courselevelr)); + if (defined($coursereply)) { return $coursereply; } + } - my $coursereply=&resdata($env{'course.'.$courseid.'.num'}, + $coursereply=&resdata($env{'course.'.$courseid.'.num'}, $env{'course.'.$courseid.'.domain'}, 'course', ($seclevelr,$seclevelm,$seclevel, @@ -5075,11 +4951,6 @@ sub EXT { if ($space eq 'time') { return time; } - } elsif ($realm eq 'server') { -# ----------------------------------------------------------------- system.time - if ($space eq 'name') { - return $ENV{'SERVER_NAME'}; - } } return ''; } @@ -5311,7 +5182,7 @@ sub metadata { $metaentry{':keys'}=join(',',keys %metathesekeys); &metadata_generate_part0(\%metathesekeys,\%metaentry,$uri); $metaentry{':allpossiblekeys'}=join(',',keys %metathesekeys); - &do_cache_new('meta',$uri,\%metaentry,60*60); + &do_cache_new('meta',$uri,\%metaentry,60*60*24); # this is the end of "was not already recently cached } return $metaentry{':'.$what}; @@ -5407,17 +5278,10 @@ sub get_slot { $cdom=$env{'course.'.$courseid.'.domain'}; $cnum=$env{'course.'.$courseid.'.num'}; } - my $key=join("\0",'slots',$cdom,$cnum,$which); - my %slotinfo; - if (exists($remembered{$key})) { - $slotinfo{$which} = $remembered{$key}; - } else { - %slotinfo=&get('slots',[$which],$cdom,$cnum); - &Apache::lonhomework::showhash(%slotinfo); - my ($tmp)=keys(%slotinfo); - if ($tmp=~/^error:/) { return (); } - $remembered{$key} = $slotinfo{$which}; - } + my %slotinfo=&get('slots',[$which],$cdom,$cnum); + &Apache::lonhomework::showhash(%slotinfo); + my ($tmp)=keys(%slotinfo); + if ($tmp=~/^error:/) { return (); } if (ref($slotinfo{$which}) eq 'HASH') { return %{$slotinfo{$which}}; } @@ -5451,7 +5315,6 @@ sub symbverify { my $thisfn=$thisurl; # wrapper not part of symbs $thisfn=~s/^\/adm\/wrapper//; - $thisfn=~s/^\/adm\/coursedocs\/showdoc\///; $thisfn=&declutter($thisfn); # direct jump to resource in page or to a sequence - will construct own symbs if ($thisfn=~/\.(page|sequence)$/) { return 1; } @@ -5506,7 +5369,6 @@ sub symbclean { # remove wrapper $symb=~s/(\_\_\_\d+\_\_\_)adm\/wrapper\/(res\/)*/$1/; - $symb=~s/(\_\_\_\d+\_\_\_)adm\/coursedocs\/showdoc\/(res\/)*/$1/; return $symb; } @@ -6157,11 +6019,6 @@ sub filelocation { my ($dir,$file) = @_; my $location; $file=~ s/^\s*(\S+)\s*$/$1/; ## strip off leading and trailing spaces - - if ($file =~ m-^/adm/-) { - $file=~s-^/adm/wrapper/-/-; - $file=~s-^/adm/coursedocs/showdoc/-/-; - } if ($file=~m:^/~:) { # is a contruction space reference $location = $file; $location =~ s:/~(.*?)/(.*):/home/$1/public_html/$2:; @@ -6201,9 +6058,6 @@ sub hreflocation { my ($dir,$file)=@_; unless (($file=~m-^http://-i) || ($file=~m-^/-)) { $file=filelocation($dir,$file); - } elsif ($file=~m-^/adm/-) { - $file=~s-^/adm/wrapper/-/-; - $file=~s-^/adm/coursedocs/showdoc/-/-; } if ($file=~m-^\Q$perlvar{'lonDocRoot'}\E-) { $file=~s-^\Q$perlvar{'lonDocRoot'}\E--; @@ -6247,8 +6101,6 @@ sub declutter { if ($thisfn=~m|^/enc/|) { $thisfn=&Apache::lonenc::unencrypted($thisfn); } $thisfn=~s/^\Q$perlvar{'lonDocRoot'}\E//; $thisfn=~s/^\///; - $thisfn=~s|^adm/wrapper/||; - $thisfn=~s|^adm/coursedocs/showdoc/||; $thisfn=~s/^res\///; $thisfn=~s/\?.+$//; return $thisfn; @@ -6261,30 +6113,6 @@ sub clutter { unless ($thisfn=~/^\/(uploaded|editupload|adm|userfiles|ext|raw|priv|public)\//) { $thisfn='/res'.$thisfn; } - if ($thisfn !~m|/adm|) { - if ($thisfn =~ m|/ext/|) { - $thisfn='/adm/wrapper'.$thisfn; - } else { - my ($ext) = ($thisfn =~ /\.(\w+)$/); - my $embstyle=&Apache::loncommon::fileembstyle($ext); - if ($embstyle eq 'ssi' - || ($embstyle eq 'hdn') - || ($embstyle eq 'rat') - || ($embstyle eq 'prv') - || ($embstyle eq 'ign')) { - #do nothing with these - } elsif (($embstyle eq 'img') - || ($embstyle eq 'emb') - || ($embstyle eq 'wrp')) { - $thisfn='/adm/wrapper'.$thisfn; - } elsif ($embstyle eq 'unk' - && $thisfn!~/\.(sequence|page)$/) { - $thisfn='/adm/coursedocs/showdoc'.$thisfn; - } else { - #&logthis("Got a blank emb style"); - } - } - } return $thisfn; } @@ -6428,7 +6256,7 @@ BEGIN { } close($config); # FIXME: dev server don't want this, production servers _do_ want this - &get_iphost(); + #&get_iphost(); } sub get_iphost {