--- loncom/lonnet/perl/lonnet.pm 2010/07/20 02:42:47 1.1074 +++ loncom/lonnet/perl/lonnet.pm 2010/08/20 18:17:04 1.1082 @@ -1,7 +1,7 @@ # The LearningOnline Network # TCP networking package # -# $Id: lonnet.pm,v 1.1074 2010/07/20 02:42:47 raeburn Exp $ +# $Id: lonnet.pm,v 1.1082 2010/08/20 18:17:04 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -76,7 +76,7 @@ use HTTP::Date; use Image::Magick; use vars qw(%perlvar %spareid %pr %prp $memcache %packagetab $tmpdir - $_64bit %env %protocol %loncaparevs %serverhomeIDs); + $_64bit %env %protocol %loncaparevs %serverhomeIDs %needsrelease); my (%badServerCache, $memcache, %courselogs, %accesshash, %domainrolehash, %userrolehash, $processmarker, $dumpcount, %coursedombuf, @@ -222,7 +222,7 @@ sub get_server_loncaparev { my @ids=¤t_machine_ids(); if (grep(/^\Q$lonhost\E$/,@ids)) { $answer = $perlvar{'lonVersion'}; - if ($answer =~ /^[\'\"]?([\d.\-]+)[\'\"]?$/) { + if ($answer =~ /^[\'\"]?([\w.\-]+)[\'\"]?$/) { $loncaparev = $1; } } else { @@ -230,7 +230,7 @@ sub get_server_loncaparev { if (($answer eq 'unknown_cmd') || ($answer eq 'con_lost')) { if ($caller eq 'loncron') { my $ua=new LWP::UserAgent; - $ua->timeout(20); + $ua->timeout(4); my $protocol = $protocol{$lonhost}; $protocol = 'http' if ($protocol ne 'https'); my $url = $protocol.'://'.&hostname($lonhost).'/adm/about.html'; @@ -238,14 +238,14 @@ sub get_server_loncaparev { my $response=$ua->request($request); unless ($response->is_error()) { my $content = $response->content; - if ($content =~ /

VERSION\:\s*([\d.\-]+)<\/p>/) { + if ($content =~ /

VERSION\:\s*([\w.\-]+)<\/p>/) { $loncaparev = $1; } } } else { $loncaparev = $loncaparevs{$lonhost}; } - } elsif ($answer =~ /^[\'\"]?([\d.\-]+)[\'\"]?$/) { + } elsif ($answer =~ /^[\'\"]?([\w.\-]+)[\'\"]?$/) { $loncaparev = $1; } } @@ -812,6 +812,27 @@ sub has_user_session { return 0; } +# --------- determine least loaded server in a user's domain which allows login + +sub choose_server { + my ($udom) = @_; + my %domconfhash = &Apache::loncommon::get_domainconf($udom); + my %servers = &get_servers($udom); + my $lowest_load = 30000; + my ($login_host,$hostname); + foreach my $lonhost (keys(%servers)) { + my $loginvia = $domconfhash{$udom.'.login.loginvia_'.$lonhost}; + if ($loginvia eq '') { + ($login_host, $lowest_load) = + &compare_server_load($lonhost, $login_host, $lowest_load); + } + } + if ($login_host ne '') { + $hostname = $servers{$login_host}; + } + return ($login_host,$hostname); +} + # --------------------------------------------- Try to change a user's password sub changepass { @@ -3883,6 +3904,44 @@ sub coursedescription { return %returnhash; } +sub update_released_required { + my ($needsrelease,$cdom,$cnum,$chome,$cid) = @_; + if ($cdom eq '' || $cnum eq '' || $chome eq '' || $cid eq '') { + $cid = $env{'request.course.id'}; + $cdom = $env{'course.'.$cid.'.domain'}; + $cnum = $env{'course.'.$cid.'.num'}; + $chome = $env{'course.'.$cid.'.home'}; + } + if ($needsrelease) { + my %curr_reqd_hash = &userenvironment($cdom,$cnum,'internal.releaserequired'); + my $needsupdate; + if ($curr_reqd_hash{'internal.releaserequired'} eq '') { + $needsupdate = 1; + } else { + my ($currmajor,$currminor) = split(/\./,$curr_reqd_hash{'internal.releaserequired'}); + my ($needsmajor,$needsminor) = split(/\./,$needsrelease); + if (($currmajor < $needsmajor) || ($currmajor == $needsmajor && $currminor < $needsminor)) { + $needsupdate = 1; + } + } + if ($needsupdate) { + my %needshash = ( + 'internal.releaserequired' => $needsrelease, + ); + my $putresult = &put('environment',\%needshash,$cdom,$cnum); + if ($putresult eq 'ok') { + &appenv({'course.'.$cid.'.internal.releaserequired' => $needsrelease}); + my %crsinfo = &courseiddump($cdom,'.',1,'.','.',$cnum,undef,undef,'.'); + if (ref($crsinfo{$cid}) eq 'HASH') { + $crsinfo{$cid}{'releaserequired'} = $needsrelease; + &courseidput($cdom,\%crsinfo,$chome,'notime'); + } + } + } + } + return; +} + # -------------------------------------------------See if a user is privileged sub privileged { @@ -3922,9 +3981,10 @@ sub rolesinit { my ($domain,$username,$authhost)=@_; my $now=time; my %userroles = ('user.login.time' => $now); - my $rolesdump=reply("dump:$domain:$username:roles",$authhost); + my $extra = &freeze_escape({'clientcheckrole' => 1}); + my $rolesdump=reply("dump:$domain:$username:roles:.::$extra",$authhost); if (($rolesdump eq 'con_lost') || ($rolesdump eq '') || - ($rolesdump =~ /^error:/)) { + ($rolesdump =~ /^error:/)) { return \%userroles; } my %allroles=(); @@ -5679,8 +5739,7 @@ sub update_allusers_table { 'generation='.&escape($names->{'generation'}).'%%'. 'permanentemail='.&escape($names->{'permanentemail'}).'%%'. 'id='.&escape($names->{'id'}),$homeserver); - my $reply = &get_query_reply($queryid); - return $reply; + return; } # ------- Request retrieval of institutional classlists for course(s) @@ -6603,6 +6662,10 @@ sub modifyuser { ' by '.$env{'user.name'}.' at '.$env{'user.domain'}. ' in domain '.$env{'request.role.domain'}); my $uhome=&homeserver($uname,$udom,'true'); + my $newuser; + if ($uhome eq 'no_host') { + $newuser = 1; + } # ----------------------------------------------------------------- Create User if (($uhome eq 'no_host') && (($umode && $upass) || ($umode eq 'localauth'))) { @@ -6655,11 +6718,12 @@ sub modifyuser { ['firstname','middlename','lastname','generation','id', 'permanentemail','inststatus'], $udom,$uname); - my %names; + my (%names,%oldnames); if ($tmp[0] =~ m/^error:.*/) { %names=(); } else { %names = @tmp; + %oldnames = %names; } # # If name, email and/or uid are blank (e.g., because an uploaded file @@ -6713,18 +6777,37 @@ sub modifyuser { } } } - my $reply = &put('environment', \%names, $udom,$uname); - if ($reply ne 'ok') { return 'error: '.$reply; } - my $sqlresult = &update_allusers_table($uname,$udom,\%names); - &devalidate_cache_new('namescache',$uname.':'.$udom); - my $logmsg = 'Success modifying user '.$udom.', '.$uname.', '.$uid.', '. + my $logmsg = $udom.', '.$uname.', '.$uid.', '. $umode.', '.$first.', '.$middle.', '. - $last.', '.$gene.', '.$email.', '.$inststatus; + $last.', '.$gene.', '.$email.', '.$inststatus; if ($env{'user.name'} ne '' && $env{'user.domain'}) { $logmsg .= ' by '.$env{'user.name'}.' at '.$env{'user.domain'}; } else { $logmsg .= ' during self creation'; } + my $changed; + if ($newuser) { + $changed = 1; + } else { + foreach my $field (@fields) { + if ($names{$field} ne $oldnames{$field}) { + $changed = 1; + last; + } + } + } + unless ($changed) { + $logmsg = 'No changes in user information needed for: '.$logmsg; + &logthis($logmsg); + return 'ok'; + } + my $reply = &put('environment', \%names, $udom,$uname); + if ($reply ne 'ok') { + return 'error: '.$reply; + } + my $sqlresult = &update_allusers_table($uname,$udom,\%names); + &devalidate_cache_new('namescache',$uname.':'.$udom); + $logmsg = 'Success modifying user '.$logmsg; &logthis($logmsg); return 'ok'; } @@ -10094,6 +10177,10 @@ sub get_dns { } +sub all_loncaparevs { + return qw(1.1 1.2 1.3 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10); +} + BEGIN { # ----------------------------------- Read loncapa.conf and loncapa_apache.conf @@ -10197,8 +10284,23 @@ BEGIN { } } -sub all_loncaparevs { - return qw(1.1 1.2 1.3 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10); +{ + my $file = $Apache::lonnet::perlvar{'lonTabDir'}.'/releaseslist.xml'; + if (-e $file) { + my $parser = HTML::LCParser->new($file); + while (my $token = $parser->get_token()) { + if ($token->[0] eq 'S') { + my $item = $token->[1]; + my $name = $token->[2]{'name'}; + my $value = $token->[2]{'value'}; + if ($item ne '' && $name ne '' && $value ne '') { + my $release = $parser->get_text(); + $release =~ s/(^\s*|\s*$ )//gx; + $needsrelease{$item.':'.$name.':'.$value} = $release; + } + } + } + } } # ------------- set up temporary directory