--- loncom/lonnet/perl/lonnet.pm 2021/11/09 20:51:53 1.1172.2.140.2.2 +++ loncom/lonnet/perl/lonnet.pm 2013/10/14 17:14:48 1.1243 @@ -1,7 +1,7 @@ # The LearningOnline Network # TCP networking package # -# $Id: lonnet.pm,v 1.1172.2.140.2.2 2021/11/09 20:51:53 raeburn Exp $ +# $Id: lonnet.pm,v 1.1243 2013/10/14 17:14:48 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -74,11 +74,13 @@ use strict; use LWP::UserAgent(); use HTTP::Date; use Image::Magick; -use CGI::Cookie; -use vars qw(%perlvar %spareid %pr %prp $memcache %packagetab $tmpdir $deftex + +use Encode; + +use vars qw(%perlvar %spareid %pr %prp $memcache %packagetab $tmpdir $apache $_64bit %env %protocol %loncaparevs %serverhomeIDs %needsrelease - %managerstab $passwdmin); + %managerstab); my (%badServerCache, $memcache, %courselogs, %accesshash, %domainrolehash, %userrolehash, $processmarker, $dumpcount, %coursedombuf, @@ -90,7 +92,7 @@ use GDBM_File; use HTML::LCParser; use Fcntl qw(:flock); use Storable qw(thaw nfreeze); -use Time::HiRes qw( sleep gettimeofday tv_interval ); +use Time::HiRes qw( gettimeofday tv_interval ); use Cache::Memcached; use Digest::MD5; use Math::Random; @@ -99,18 +101,18 @@ use LONCAPA qw(:DEFAULT :match); use LONCAPA::Configuration; use LONCAPA::lonmetadata; use LONCAPA::Lond; -use LONCAPA::transliterate; use File::Copy; my $readit; -my $max_connection_retries = 20; # Or some such value. +my $max_connection_retries = 10; # Or some such value. require Exporter; our @ISA = qw (Exporter); our @EXPORT = qw(%env); + # ------------------------------------ Logging (parameters, docs, slots, roles) { my $logid; @@ -125,27 +127,26 @@ our @EXPORT = qw(%env); $logid ++; my $now = time(); my $id=$now.'00000'.$$.'00000'.$logid; - my $ip = &get_requestor_ip(); - my $logentry = { - $id => { - 'exe_uname' => $env{'user.name'}, - 'exe_udom' => $env{'user.domain'}, - 'exe_time' => $now, - 'exe_ip' => $ip, - 'delflag' => $delflag, - 'logentry' => $storehash, - 'uname' => $uname, - 'udom' => $udom, - } + my $logentry = { + $id => { + 'exe_uname' => $env{'user.name'}, + 'exe_udom' => $env{'user.domain'}, + 'exe_time' => $now, + 'exe_ip' => $ENV{'REMOTE_ADDR'}, + 'delflag' => $delflag, + 'logentry' => $storehash, + 'uname' => $uname, + 'udom' => $udom, + } }; - return &put('nohist_'.$hash_name,$logentry,$cdom,$cnum); + return &put('nohist_'.$hash_name,$logentry,$cdom,$cnum); } } sub logtouch { my $execdir=$perlvar{'lonDaemons'}; unless (-e "$execdir/logs/lonnet.log") { - open(my $fh,">>","$execdir/logs/lonnet.log"); + open(my $fh,">>$execdir/logs/lonnet.log"); close $fh; } my ($wwwuid,$wwwgid)=(getpwnam('www'))[2,3]; @@ -157,7 +158,7 @@ sub logthis { my $execdir=$perlvar{'lonDaemons'}; my $now=time; my $local=localtime($now); - if (open(my $fh,">>","$execdir/logs/lonnet.log")) { + if (open(my $fh,">>$execdir/logs/lonnet.log")) { my $logstring = $local. " ($$): ".$message."\n"; # Keep any \'s in string. print $fh $logstring; close($fh); @@ -170,7 +171,7 @@ sub logperm { my $execdir=$perlvar{'lonDaemons'}; my $now=time; my $local=localtime($now); - if (open(my $fh,">>","$execdir/logs/lonnet.perm.log")) { + if (open(my $fh,">>$execdir/logs/lonnet.perm.log")) { print $fh "$now:$message:$local\n"; close($fh); } @@ -264,10 +265,9 @@ sub get_server_loncaparev { if ($caller eq 'loncron') { my $ua=new LWP::UserAgent; $ua->timeout(4); - my $hostname = &hostname($lonhost); my $protocol = $protocol{$lonhost}; $protocol = 'http' if ($protocol ne 'https'); - my $url = $protocol.'://'.$hostname.'/adm/about.html'; + my $url = $protocol.'://'.&hostname($lonhost).'/adm/about.html'; my $request=new HTTP::Request('GET',$url); my $response=$ua->request($request); unless ($response->is_error()) { @@ -360,7 +360,8 @@ sub remote_devalidate_cache { my $items; return unless (ref($cachekeys) eq 'ARRAY'); my $cachestr = join('&',@{$cachekeys}); - return &reply('devalidatecache:'.&escape($cachestr),$lonhost); + my $response = &reply('devalidatecache:'.&escape($cachestr),$lonhost); + return $response; } # -------------------------------------------------- Non-critical communication @@ -374,7 +375,7 @@ sub subreply { my $lockfile=$peerfile.".lock"; while (-e $lockfile) { # Need to wait for the lockfile to disappear. - sleep(0.1); + sleep(1); } # At this point, either a loncnew parent is listening or an old lonc # or loncnew child is listening so we can connect or everything's dead. @@ -392,7 +393,7 @@ sub subreply { } else { &create_connection(&hostname($server),$server); } - sleep(0.1); # Try again later if failed connection. + sleep(1); # Try again later if failed connection. } my $answer; if ($client) { @@ -411,26 +412,8 @@ sub reply { unless (defined(&hostname($server))) { return 'no_such_host'; } my $answer=subreply($cmd,$server); if (($answer=~/^refused/) || ($answer=~/^rejected/)) { - my $logged = $cmd; - if ($cmd =~ /^encrypt:([^:]+):/) { - my $subcmd = $1; - if (($subcmd eq 'auth') || ($subcmd eq 'passwd') || - ($subcmd eq 'changeuserauth') || ($subcmd eq 'makeuser') || - ($subcmd eq 'putdom') || ($subcmd eq 'autoexportgrades')) { - (undef,undef,my @rest) = split(/:/,$cmd); - if (($subcmd eq 'auth') || ($subcmd eq 'putdom')) { - splice(@rest,2,1,'Hidden'); - } elsif ($subcmd eq 'passwd') { - splice(@rest,2,2,('Hidden','Hidden')); - } elsif (($subcmd eq 'changeuserauth') || ($subcmd eq 'makeuser') || - ($subcmd eq 'autoexportgrades')) { - splice(@rest,3,1,'Hidden'); - } - $logged = join(':',('encrypt:'.$subcmd,@rest)); - } - } - &logthis("WARNING:". - " $logged to $server returned $answer"); + &logthis("WARNING:". + " $cmd to $server returned $answer"); } return $answer; } @@ -439,8 +422,8 @@ sub reply { sub reconlonc { my ($lonid) = @_; + my $hostname = &hostname($lonid); if ($lonid) { - my $hostname = &hostname($lonid); my $peerfile="$perlvar{'lonSockDir'}/$hostname"; if ($hostname && -e $peerfile) { &logthis("Trying to reconnect lonc for $lonid ($hostname)"); @@ -458,7 +441,7 @@ sub reconlonc { &logthis("Trying to reconnect lonc"); my $loncfile="$perlvar{'lonDaemons'}/logs/lonc.pid"; - if (open(my $fh,"<",$loncfile)) { + if (open(my $fh,"<$loncfile")) { my $loncpid=<$fh>; chomp($loncpid); if (kill 0 => $loncpid) { @@ -486,7 +469,7 @@ sub critical { } my $answer=reply($cmd,$server); if ($answer eq 'con_lost') { - &reconlonc($server); + &reconlonc("$perlvar{'lonSockDir'}/$server"); my $answer=reply($cmd,$server); if ($answer eq 'con_lost') { my $now=time; @@ -498,16 +481,16 @@ sub critical { $dumpcount++; { my $dfh; - if (open($dfh,">",$dfilename)) { + if (open($dfh,">$dfilename")) { print $dfh "$cmd\n"; close($dfh); } } - sleep 1; + sleep 2; my $wcmd=''; { my $dfh; - if (open($dfh,"<",$dfilename)) { + if (open($dfh,"<$dfilename")) { $wcmd=<$dfh>; close($dfh); } @@ -623,52 +606,22 @@ sub transfer_profile_to_env { # ---------------------------------------------------- Check for valid session sub check_for_valid_session { - my ($r,$name,$userhashref,$domref) = @_; + my ($r,$name) = @_; my %cookies=CGI::Cookie->parse($r->header_in('Cookie')); - my ($lonidsdir,$linkname,$pubname,$secure,$lonid); - if ($name eq 'lonDAV') { - $lonidsdir=$r->dir_config('lonDAVsessDir'); - } else { - $lonidsdir=$r->dir_config('lonIDsDir'); - if ($name eq '') { - $name = 'lonID'; - } - } - if ($name eq 'lonID') { - $secure = 'lonSID'; - $linkname = 'lonLinkID'; - $pubname = 'lonPubID'; - if (exists($cookies{$secure})) { - $lonid=$cookies{$secure}; - } elsif (exists($cookies{$name})) { - $lonid=$cookies{$name}; - } elsif ((exists($cookies{$linkname})) && ($ENV{'SERVER_PORT'} != 443)) { - $lonid=$cookies{$linkname}; - } elsif (exists($cookies{$pubname})) { - $lonid=$cookies{$pubname}; - } - } else { - $lonid=$cookies{$name}; + if ($name eq '') { + $name = 'lonID'; } + my $lonid=$cookies{$name}; return undef if (!$lonid); my $handle=&LONCAPA::clean_handle($lonid->value); - if (-l "$lonidsdir/$handle.id") { - my $link = readlink("$lonidsdir/$handle.id"); - if ((-e $link) && ($link =~ m{^\Q$lonidsdir\E/(.+)\.id$})) { - $handle = $1; - } - } - if (!-e "$lonidsdir/$handle.id") { - if ((ref($domref)) && ($name eq 'lonID') && - ($handle =~ /^($match_username)\_\d+\_($match_domain)\_(.+)$/)) { - my ($possuname,$possudom,$possuhome) = ($1,$2,$3); - if ((&domain($possudom) ne '') && (&homeserver($possuname,$possudom) eq $possuhome)) { - $$domref = $possudom; - } - } - return undef; + my $lonidsdir; + if ($name eq 'lonDAV') { + $lonidsdir=$r->dir_config('lonDAVsessDir'); + } else { + $lonidsdir=$r->dir_config('lonIDsDir'); } + return undef if (!-e "$lonidsdir/$handle.id"); my $opened = open(my $idf,'+<',"$lonidsdir/$handle.id"); return undef if (!$opened); @@ -682,16 +635,15 @@ sub check_for_valid_session { if (!defined($disk_env{'user.name'}) || !defined($disk_env{'user.domain'})) { - untie(%disk_env); return undef; } - - if (ref($userhashref) eq 'HASH') { - $userhashref->{'name'} = $disk_env{'user.name'}; - $userhashref->{'domain'} = $disk_env{'user.domain'}; + if (($r->user() eq '') && ($apache >= 2.4)) { + if ($disk_env{'user.domain'} eq $r->dir_config('lonDefDomain')) { + $r->user($disk_env{'user.name'}); + } else { + $r->user($disk_env{'user.name'}.':'.$disk_env{'user.domain'}); + } } - untie(%disk_env); - return $handle; } @@ -715,37 +667,6 @@ sub timed_flock { } } -sub get_sessionfile_vars { - my ($handle,$lonidsdir,$storearr) = @_; - my %returnhash; - unless (ref($storearr) eq 'ARRAY') { - return %returnhash; - } - if (-l "$lonidsdir/$handle.id") { - my $link = readlink("$lonidsdir/$handle.id"); - if ((-e $link) && ($link =~ m{^\Q$lonidsdir\E/(.+)\.id$})) { - $handle = $1; - } - } - if ((-e "$lonidsdir/$handle.id") && - ($handle =~ /^($match_username)\_\d+\_($match_domain)\_(.+)$/)) { - my ($possuname,$possudom,$possuhome) = ($1,$2,$3); - if ((&domain($possudom) ne '') && (&homeserver($possuname,$possudom) eq $possuhome)) { - if (open(my $idf,'+<',"$lonidsdir/$handle.id")) { - flock($idf,LOCK_SH); - if (tie(my %disk_env,'GDBM_File',"$lonidsdir/$handle.id", - &GDBM_READER(),0640)) { - foreach my $item (@{$storearr}) { - $returnhash{$item} = $disk_env{$item}; - } - untie(%disk_env); - } - } - } - } - return %returnhash; -} - # ---------------------------------------------------------- Append Environment sub appenv { @@ -756,7 +677,7 @@ sub appenv { if (($key =~ /^user\.role/) || ($key =~ /^user\.priv/)) { $refused = 1; if (ref($roles) eq 'ARRAY') { - my ($type,$role) = ($key =~ m{^user\.(role|priv)\.(.+?)\./}); + my ($type,$role) = ($key =~ /^user\.(role|priv)\.([^.]+)\./); if (grep(/^\Q$role\E$/,@{$roles})) { $refused = 0; } @@ -771,19 +692,16 @@ sub appenv { $env{$key}=$newenv->{$key}; } } - my $lonids = $perlvar{'lonIDsDir'}; - if ($env{'user.environment'} =~ m{^\Q$lonids/\E$match_username\_\d+\_$match_domain\_[\w\-.]+\.id$}) { - my $opened = open(my $env_file,'+<',$env{'user.environment'}); - if ($opened - && &timed_flock($env_file,LOCK_EX) - && - tie(my %disk_env,'GDBM_File',$env{'user.environment'}, - (&GDBM_WRITER()|&GDBM_NOLOCK()),0640)) { - while (my ($key,$value) = each(%{$newenv})) { - $disk_env{$key} = $value; - } - untie(%disk_env); - } + my $opened = open(my $env_file,'+<',$env{'user.environment'}); + if ($opened + && &timed_flock($env_file,LOCK_EX) + && + tie(my %disk_env,'GDBM_File',$env{'user.environment'}, + (&GDBM_WRITER()|&GDBM_NOLOCK()),0640)) { + while (my ($key,$value) = each(%{$newenv})) { + $disk_env{$key} = $value; + } + untie(%disk_env); } } return 'ok'; @@ -899,7 +817,6 @@ sub userload { while ($filename=readdir(LONIDS)) { next if ($filename eq '.' || $filename eq '..'); next if ($filename =~ /publicuser_\d+\.id/); - next if ($filename =~ /^[a-f0-9]+_linked\.id$/); my ($mtime)=(stat($perlvar{'lonIDsDir'}.'/'.$filename))[9]; if ($curtime-$mtime < 1800) { $numusers++; } } @@ -933,8 +850,10 @@ sub spareserver { if (ref($spareshash) eq 'HASH') { if (ref($spareshash->{'primary'}) eq 'ARRAY') { foreach my $try_server (@{ $spareshash->{'primary'} }) { - next unless (&spare_can_host($udom,$uint_dom,$remotesessions, - $try_server)); + if ($uint_dom) { + next unless (&spare_can_host($udom,$uint_dom,$remotesessions, + $try_server)); + } ($spare_server, $lowest_load) = &compare_server_load($try_server, $spare_server, $lowest_load); } @@ -945,8 +864,10 @@ sub spareserver { if (!$found_server) { if (ref($spareshash->{'default'}) eq 'ARRAY') { foreach my $try_server (@{ $spareshash->{'default'} }) { - next unless (&spare_can_host($udom,$uint_dom, - $remotesessions,$try_server)); + if ($uint_dom) { + next unless (&spare_can_host($udom,$uint_dom, + $remotesessions,$try_server)); + } ($spare_server, $lowest_load) = &compare_server_load($try_server, $spare_server, $lowest_load); } @@ -955,13 +876,13 @@ sub spareserver { } if (!$want_server_name) { + my $protocol = 'http'; + if ($protocol{$spare_server} eq 'https') { + $protocol = $protocol{$spare_server}; + } if (defined($spare_server)) { my $hostname = &hostname($spare_server); if (defined($hostname)) { - my $protocol = 'http'; - if ($protocol{$spare_server} eq 'https') { - $protocol = $protocol{$spare_server}; - } $spare_server = $protocol.'://'.$hostname; } } @@ -970,17 +891,7 @@ sub spareserver { } sub compare_server_load { - my ($try_server, $spare_server, $lowest_load, $required) = @_; - - if ($required) { - my ($reqdmajor,$reqdminor) = ($required =~ /^(\d+)\.(\d+)$/); - my $remoterev = &get_server_loncaparev(undef,$try_server); - my ($major,$minor) = ($remoterev =~ /^\'?(\d+)\.(\d+)\.[\w.\-]+\'?$/); - if (($major eq '' && $minor eq '') || - (($reqdmajor > $major) || (($reqdmajor == $major) && ($reqdminor > $minor)))) { - return ($spare_server,$lowest_load); - } - } + my ($try_server, $spare_server, $lowest_load) = @_; my $loadans = &reply('load', $try_server); my $userloadans = &reply('userload',$try_server); @@ -1028,90 +939,6 @@ sub find_existing_session { return; } -# check if user's browser sent load balancer cookie and server still has session -# and is not overloaded. -sub check_for_balancer_cookie { - my ($r,$update_mtime) = @_; - my ($otherserver,$cookie); - my %cookies=CGI::Cookie->parse($r->header_in('Cookie')); - if (exists($cookies{'balanceID'})) { - my $balid = $cookies{'balanceID'}; - $cookie=&LONCAPA::clean_handle($balid->value); - my $balancedir=$r->dir_config('lonBalanceDir'); - if ((-d $balancedir) && (-e "$balancedir/$cookie.id")) { - if ($cookie =~ /^($match_domain)_($match_username)_[a-f0-9]+$/) { - my ($possudom,$possuname) = ($1,$2); - my $has_session = 0; - if ((&domain($possudom) ne '') && - (&homeserver($possuname,$possudom) ne 'no_host')) { - my $try_server; - my $opened = open(my $idf,'+<',"$balancedir/$cookie.id"); - if ($opened) { - flock($idf,LOCK_SH); - while (my $line = <$idf>) { - chomp($line); - if (&hostname($line) ne '') { - $try_server = $line; - last; - } - } - close($idf); - if (($try_server) && - (&has_user_session($try_server,$possudom,$possuname))) { - my $lowest_load = 30000; - ($otherserver,$lowest_load) = - &compare_server_load($try_server,undef,$lowest_load); - if ($otherserver ne '' && $lowest_load < 100) { - $has_session = 1; - } else { - undef($otherserver); - } - } - } - } - if ($has_session) { - if ($update_mtime) { - my $atime = my $mtime = time; - utime($atime,$mtime,"$balancedir/$cookie.id"); - } - } else { - unlink("$balancedir/$cookie.id"); - } - } - } - } - return ($otherserver,$cookie); -} - -sub updatebalcookie { - my ($cookie,$balancer,$lastentry)=@_; - if ($cookie =~ /^($match_domain)\_($match_username)\_[a-f0-9]{32}$/) { - my ($udom,$uname) = ($1,$2); - my $uprimary_id = &domain($udom,'primary'); - my $uintdom = &internet_dom($uprimary_id); - my $intdom = &internet_dom($balancer); - my $serverhomedom = &host_domain($balancer); - if (($uintdom ne '') && ($uintdom eq $intdom)) { - return &reply('updatebalcookie:'.&escape($cookie).':'.&escape($lastentry),$balancer); - } - } - return; -} - -sub delbalcookie { - my ($cookie,$balancer) =@_; - if ($cookie =~ /^($match_domain)\_($match_username)\_[a-f0-9]{32}$/) { - my ($udom,$uname) = ($1,$2); - my $uprimary_id = &domain($udom,'primary'); - my $uintdom = &internet_dom($uprimary_id); - my $intdom = &internet_dom($balancer); - my $serverhomedom = &host_domain($balancer); - if (($uintdom ne '') && ($uintdom eq $intdom)) { - return &reply('delbalcookie:'.&escape($cookie),$balancer); - } - } -} - # -------------------------------- ask if server already has a session for user sub has_user_session { my ($lonid,$udom,$uname) = @_; @@ -1125,43 +952,26 @@ sub has_user_session { # --------- determine least loaded server in a user's domain which allows login sub choose_server { - my ($udom,$checkloginvia,$required,$skiploadbal) = @_; + my ($udom,$checkloginvia) = @_; my %domconfhash = &Apache::loncommon::get_domainconf($udom); my %servers = &get_servers($udom); my $lowest_load = 30000; - my ($login_host,$hostname,$portal_path,$isredirect,$balancers); - if ($skiploadbal) { - ($balancers,my $cached)=&is_cached_new('loadbalancing',$udom); - unless (defined($cached)) { - my $cachetime = 60*60*24; - my %domconfig = - &Apache::lonnet::get_dom('configuration',['loadbalancing'],$udom); - if (ref($domconfig{'loadbalancing'}) eq 'HASH') { - $balancers = &do_cache_new('loadbalancing',$udom,$domconfig{'loadbalancing'}, - $cachetime); - } - } - } + my ($login_host,$hostname,$portal_path,$isredirect); foreach my $lonhost (keys(%servers)) { my $loginvia; - if ($skiploadbal) { - if (ref($balancers) eq 'HASH') { - next if (exists($balancers->{$lonhost})); - } - } if ($checkloginvia) { $loginvia = $domconfhash{$udom.'.login.loginvia_'.$lonhost}; if ($loginvia) { my ($server,$path) = split(/:/,$loginvia); ($login_host, $lowest_load) = - &compare_server_load($server, $login_host, $lowest_load, $required); + &compare_server_load($server, $login_host, $lowest_load); if ($login_host eq $server) { $portal_path = $path; $isredirect = 1; } } else { ($login_host, $lowest_load) = - &compare_server_load($lonhost, $login_host, $lowest_load, $required); + &compare_server_load($lonhost, $login_host, $lowest_load); if ($login_host eq $lonhost) { $portal_path = ''; $isredirect = ''; @@ -1169,35 +979,13 @@ sub choose_server { } } else { ($login_host, $lowest_load) = - &compare_server_load($lonhost, $login_host, $lowest_load, $required); + &compare_server_load($lonhost, $login_host, $lowest_load); } } if ($login_host ne '') { $hostname = &hostname($login_host); } - return ($login_host,$hostname,$portal_path,$isredirect,$lowest_load); -} - -sub get_course_sessions { - my ($cnum,$cdom,$lastactivity) = @_; - my %servers = &internet_dom_servers($cdom); - my %returnhash; - foreach my $server (sort(keys(%servers))) { - my $rep = &reply("coursesessions:$cdom:$cnum:$lastactivity",$server); - my @pairs=split(/\&/,$rep); - unless (($rep eq 'unknown_cmd') || ($rep =~ /^error/)) { - foreach my $item (@pairs) { - my ($key,$value)=split(/=/,$item,2); - $key = &unescape($key); - next if ($key =~ /^error: 2 /); - if (exists($returnhash{$key})) { - next if ($value < $returnhash{$key}); - } - $returnhash{$key}=$value; - } - } - } - return %returnhash; + return ($login_host,$hostname,$portal_path,$isredirect); } # --------------------------------------------- Try to change a user's password @@ -1235,9 +1023,6 @@ sub changepass { } elsif ($answer =~ "invalid_client") { &logthis("$server refused to change $uname in $udom password because ". "it was a reset by e-mail originating from an invalid server."); - } elsif ($answer =~ "^prioruse") { - &logthis("$server refused to change $uname in $udom password because ". - "the password had been used before"); } return $answer; } @@ -1367,36 +1152,19 @@ sub can_host_session { sub spare_can_host { my ($udom,$uint_dom,$remotesessions,$try_server)=@_; my $canhost=1; - my $try_server_hostname = &hostname($try_server); - my $serverhomeID = &get_server_homeID($try_server_hostname); - my $serverhomedom = &host_domain($serverhomeID); - my %defdomdefaults = &get_domain_defaults($serverhomedom); - if (ref($defdomdefaults{'offloadnow'}) eq 'HASH') { - if ($defdomdefaults{'offloadnow'}{$try_server}) { - $canhost = 0; - } - } - if ($canhost) { - if (ref($defdomdefaults{'offloadoth'}) eq 'HASH') { - if ($defdomdefaults{'offloadoth'}{$try_server}) { - unless (&shared_institution($udom,$try_server)) { - $canhost = 0; - } - } - } - } - if (($canhost) && ($uint_dom)) { - my @intdoms; - my $internet_names = &get_internet_names($try_server); - if (ref($internet_names) eq 'ARRAY') { - @intdoms = @{$internet_names}; - } - unless (grep(/^\Q$uint_dom\E$/,@intdoms)) { - my $remoterev = &get_server_loncaparev(undef,$try_server); - $canhost = &can_host_session($udom,$try_server,$remoterev, - $remotesessions, - $defdomdefaults{'hostedsessions'}); - } + my @intdoms; + my $internet_names = &Apache::lonnet::get_internet_names($try_server); + if (ref($internet_names) eq 'ARRAY') { + @intdoms = @{$internet_names}; + } + unless (grep(/^\Q$uint_dom\E$/,@intdoms)) { + my $serverhomeID = &Apache::lonnet::get_server_homeID($try_server); + my $serverhomedom = &Apache::lonnet::host_domain($serverhomeID); + my %defdomdefaults = &Apache::lonnet::get_domain_defaults($serverhomedom); + my $remoterev = &Apache::lonnet::get_server_loncaparev(undef,$try_server); + $canhost = &can_host_session($udom,$try_server,$remoterev, + $remotesessions, + $defdomdefaults{'hostedsessions'}); } return $canhost; } @@ -1481,16 +1249,16 @@ sub get_lonbalancer_config { } sub check_loadbalancing { - my ($uname,$udom,$caller) = @_; + my ($uname,$udom) = @_; my ($is_balancer,$currtargets,$currrules,$dom_in_use,$homeintdom, - $rule_in_effect,$offloadto,$otherserver,$setcookie); + $rule_in_effect,$offloadto,$otherserver); my $lonhost = $perlvar{'lonHostID'}; my @hosts = ¤t_machine_ids(); my $uprimary_id = &Apache::lonnet::domain($udom,'primary'); my $uintdom = &Apache::lonnet::internet_dom($uprimary_id); my $intdom = &Apache::lonnet::internet_dom($lonhost); my $serverhomedom = &host_domain($lonhost); - my $domneedscache; + my $cachetime = 60*60*24; if (($uintdom ne '') && ($uintdom eq $intdom)) { @@ -1505,12 +1273,10 @@ sub check_loadbalancing { &Apache::lonnet::get_dom('configuration',['loadbalancing'],$dom_in_use); if (ref($domconfig{'loadbalancing'}) eq 'HASH') { $result = &do_cache_new('loadbalancing',$dom_in_use,$domconfig{'loadbalancing'},$cachetime); - } else { - $domneedscache = $dom_in_use; } } if (ref($result) eq 'HASH') { - ($is_balancer,$currtargets,$currrules,$setcookie) = + ($is_balancer,$currtargets,$currrules) = &check_balancer_result($result,@hosts); if ($is_balancer) { if (ref($currrules) eq 'HASH') { @@ -1565,13 +1331,11 @@ sub check_loadbalancing { my %domconfig = &Apache::lonnet::get_dom('configuration',['loadbalancing'],$serverhomedom); if (ref($domconfig{'loadbalancing'}) eq 'HASH') { - $result = &do_cache_new('loadbalancing',$serverhomedom,$domconfig{'loadbalancing'},$cachetime); - } else { - $domneedscache = $serverhomedom; + $result = &do_cache_new('loadbalancing',$dom_in_use,$domconfig{'loadbalancing'},$cachetime); } } if (ref($result) eq 'HASH') { - ($is_balancer,$currtargets,$currrules,$setcookie) = + ($is_balancer,$currtargets,$currrules) = &check_balancer_result($result,@hosts); if ($is_balancer) { if (ref($currrules) eq 'HASH') { @@ -1587,23 +1351,14 @@ sub check_loadbalancing { $is_balancer = 1; $offloadto = &this_host_spares($dom_in_use); } - unless (defined($cached)) { - $domneedscache = $serverhomedom; - } } } else { if ($perlvar{'lonBalancer'} eq 'yes') { $is_balancer = 1; $offloadto = &this_host_spares($dom_in_use); } - unless (defined($cached)) { - $domneedscache = $serverhomedom; - } } - if ($domneedscache) { - &do_cache_new('loadbalancing',$domneedscache,$is_balancer,$cachetime); - } - if (($is_balancer) && ($caller ne 'switchserver')) { + if ($is_balancer) { my $lowest_load = 30000; if (ref($offloadto) eq 'HASH') { if (ref($offloadto->{'primary'}) eq 'ARRAY') { @@ -1632,27 +1387,23 @@ sub check_loadbalancing { } } } - unless ($caller eq 'login') { - if (($otherserver ne '') && (grep(/^\Q$otherserver\E$/,@hosts))) { - $is_balancer = 0; - if ($uname ne '' && $udom ne '') { - if (($env{'user.name'} eq $uname) && ($env{'user.domain'} eq $udom)) { - &appenv({'user.loadbalexempt' => $lonhost, - 'user.loadbalcheck.time' => time}); - } + if (($otherserver ne '') && (grep(/^\Q$otherserver\E$/,@hosts))) { + $is_balancer = 0; + if ($uname ne '' && $udom ne '') { + if (($env{'user.name'} eq $uname) && ($env{'user.domain'} eq $udom)) { + + &appenv({'user.loadbalexempt' => $lonhost, + 'user.loadbalcheck.time' => time}); } } } } - if (($is_balancer) && (!$homeintdom)) { - undef($setcookie); - } - return ($is_balancer,$otherserver,$setcookie); + return ($is_balancer,$otherserver); } sub check_balancer_result { my ($result,@hosts) = @_; - my ($is_balancer,$currtargets,$currrules,$setcookie); + my ($is_balancer,$currtargets,$currrules); if (ref($result) eq 'HASH') { if ($result->{'lonhost'} ne '') { my $currbalancer = $result->{'lonhost'}; @@ -1668,13 +1419,12 @@ sub check_balancer_result { $is_balancer = 1; $currrules = $result->{$key}{'rules'}; $currtargets = $result->{$key}{'targets'}; - $setcookie = $result->{$key}{'cookie'}; last; } } } } - return ($is_balancer,$currtargets,$currrules,$setcookie); + return ($is_balancer,$currtargets,$currrules); } sub get_loadbalancer_targets { @@ -1779,7 +1529,7 @@ sub idget { my %servers = &get_servers($udom,'library'); foreach my $tryserver (keys(%servers)) { - my $idlist=join('&', map { &escape($_); } @ids); + my $idlist=join('&',@ids); $idlist=~tr/A-Z/a-z/; my $reply=&reply("idget:$udom:".$idlist,$tryserver); my @answer=(); @@ -1789,7 +1539,7 @@ sub idget { my $i; for ($i=0;$i<=$#ids;$i++) { if ($answer[$i]) { - $returnhash{$ids[$i]}=&unescape($answer[$i]); + $returnhash{$ids[$i]}=$answer[$i]; } } } @@ -1831,7 +1581,7 @@ sub idput { } } -# ---------------------------------------- Delete unwanted IDs from ids.db file +# ---------------------------------------- Delete unwanted IDs from ids.db file sub iddel { my ($udom,$idshashref,$uhome)=@_; @@ -1876,7 +1626,6 @@ sub dump_dom { sub get_dom { my ($namespace,$storearr,$udom,$uhome)=@_; - return if ($udom eq 'public'); my $items=''; foreach my $item (@$storearr) { $items.=&escape($item).'&'; @@ -1884,7 +1633,6 @@ sub get_dom { $items=~s/\&$//; if (!$udom) { $udom=$env{'user.domain'}; - return if ($udom eq 'public'); if (defined(&domain($udom,'primary'))) { $uhome=&domain($udom,'primary'); } else { @@ -1898,13 +1646,7 @@ sub get_dom { } } if ($udom && $uhome && ($uhome ne 'no_host')) { - my $rep; - if (grep { $_ eq $uhome } ¤t_machine_ids()) { - # domain information is hosted on this machine - $rep = &LONCAPA::Lond::get_dom("getdom:$udom:$namespace:$items"); - } else { - $rep=&reply("getdom:$udom:$namespace:$items",$uhome); - } + my $rep=&reply("getdom:$udom:$namespace:$items",$uhome); my %returnhash; if ($rep eq '' || $rep =~ /^error: 2 /) { return %returnhash; @@ -1994,13 +1736,14 @@ sub retrieve_inst_usertypes { my %domdefs = &Apache::lonnet::get_domain_defaults($udom); if ((ref($domdefs{'inststatustypes'}) eq 'HASH') && (ref($domdefs{'inststatusorder'}) eq 'ARRAY')) { - return ($domdefs{'inststatustypes'},$domdefs{'inststatusorder'}); + %returnhash = %{$domdefs{'inststatustypes'}}; + @order = @{$domdefs{'inststatusorder'}}; } else { if (defined(&domain($udom,'primary'))) { my $uhome=&domain($udom,'primary'); my $rep=&reply("inst_usertypes:$udom",$uhome); if ($rep =~ /^(con_lost|error|no_such_host|refused)/) { - &logthis("retrieve_inst_usertypes failed - $rep returned from $uhome in domain: $udom"); + &logthis("get_dom failed - $rep returned from $uhome in domain: $udom"); return (\%returnhash,\@order); } my ($hashitems,$orderitems) = split(/:/,$rep); @@ -2016,15 +1759,15 @@ sub retrieve_inst_usertypes { push(@order,&unescape($item)); } } else { - &logthis("retrieve_inst_usertypes failed - no primary domain server for $udom"); + &logthis("get_dom failed - no primary domain server for $udom"); } - return (\%returnhash,\@order); } + return (\%returnhash,\@order); } sub is_domainimage { my ($url) = @_; - if ($url=~m-^/+res/+($match_domain)/+\1\-domainconfig/+(img|logo|domlogo)/+[^/]-) { + if ($url=~m-^/+res/+($match_domain)/+\1\-domainconfig/+(img|logo|domlogo)/+-) { if (&domain($1) ne '') { return '1'; } @@ -2039,24 +1782,13 @@ sub inst_directory_query { my $homeserver = &domain($udom,'primary'); my $outcome; if ($homeserver ne '') { - unless ($homeserver eq $perlvar{'lonHostID'}) { - if ($srch->{'srchby'} eq 'email') { - my $lcrev = &get_server_loncaparev($udom,$homeserver); - my ($major,$minor,$subver) = ($lcrev =~ /^\'?(\d+)\.(\d+)\.(\d+)[\w.\-]+\'?$/); - if (($major eq '' && $minor eq '') || ($major < 2) || - (($major == 2) && ($minor < 11)) || - (($major == 2) && ($minor == 11) && ($subver < 3))) { - return; - } - } - } my $queryid=&reply("querysend:instdirsearch:". &escape($srch->{'srchby'}).':'. &escape($srch->{'srchterm'}).':'. &escape($srch->{'srchtype'}),$homeserver); my $host=&hostname($homeserver); if ($queryid !~/^\Q$host\E\_/) { - &logthis('institutional directory search invalid queryid: '.$queryid.' for host: '.$homeserver.' in domain '.$udom); + &logthis('instituional directory search invalid queryid: '.$queryid.' for host: '.$homeserver.'in domain '.$udom); return; } my $response = &get_query_reply($queryid); @@ -2091,15 +1823,6 @@ sub usersearch { my $query = 'usersearch'; foreach my $tryserver (keys(%libserv)) { if (&host_domain($tryserver) eq $dom) { - unless ($tryserver eq $perlvar{'lonHostID'}) { - if ($srch->{'srchby'} eq 'email') { - my $lcrev = &get_server_loncaparev($dom,$tryserver); - my ($major,$minor,$subver) = ($lcrev =~ /^\'?(\d+)\.(\d+)\.(\d+)[\w.\-]+\'?$/); - next if (($major eq '' && $minor eq '') || ($major < 2) || - (($major == 2) && ($minor < 11)) || - (($major == 2) && ($minor == 11) && ($subver < 3))); - } - } my $host=&hostname($tryserver); my $queryid= &reply("querysend:".&escape($query).':'. @@ -2185,63 +1908,6 @@ sub get_instuser { return ($outcome,%userinfo); } -sub get_multiple_instusers { - my ($udom,$users,$caller) = @_; - my ($outcome,$results); - if (ref($users) eq 'HASH') { - my $count = keys(%{$users}); - my $requested = &freeze_escape($users); - my $homeserver = &domain($udom,'primary'); - if ($homeserver ne '') { - my $queryid=&reply('querysend:getmultinstusers:::'.$caller.'='.$requested,$homeserver); - my $host=&hostname($homeserver); - if ($queryid !~/^\Q$host\E\_/) { - &logthis('get_multiple_instusers invalid queryid: '.$queryid. - ' for host: '.$homeserver.'in domain '.$udom); - return ($outcome,$results); - } - my $response = &get_query_reply($queryid); - my $maxtries = 5; - if ($count > 100) { - $maxtries = 1+int($count/20); - } - my $tries = 1; - while (($response=~/^timeout/) && ($tries <= $maxtries)) { - $response = &get_query_reply($queryid); - $tries ++; - } - if ($response eq '') { - $results = {}; - foreach my $key (keys(%{$users})) { - my ($uname,$id); - if ($caller eq 'id') { - $id = $key; - } else { - $uname = $key; - } - my ($resp,%info) = &get_instuser($udom,$uname,$id); - $outcome = $resp; - if ($resp eq 'ok') { - %{$results} = (%{$results}, %info); - } else { - last; - } - } - } elsif(!&error($response) && ($response ne 'refused')) { - if (($response eq 'unavailable') || ($response eq 'invalid') || ($response eq 'timeout')) { - $outcome = $response; - } else { - ($outcome,my $userdata) = split(/=/,$response,2); - if ($outcome eq 'ok') { - $results = &thaw_unescape($userdata); - } - } - } - } - } - return ($outcome,$results); -} - sub inst_rulecheck { my ($udom,$uname,$id,$item,$rules) = @_; my %returnhash; @@ -2337,10 +2003,7 @@ sub get_domain_defaults { &Apache::lonnet::get_dom('configuration',['defaults','quotas', 'requestcourses','inststatus', 'coursedefaults','usersessions', - 'requestauthor','selfenrollment', - 'coursecategories','autoenroll', - 'helpsettings'],$domain); - my @coursetypes = ('official','unofficial','community','textbook'); + 'requestauthor'],$domain); if (ref($domconfig{'defaults'}) eq 'HASH') { $domdefaults{'lang_def'} = $domconfig{'defaults'}{'lang_def'}; $domdefaults{'auth_def'} = $domconfig{'defaults'}{'auth_def'}; @@ -2348,9 +2011,6 @@ sub get_domain_defaults { $domdefaults{'timezone_def'} = $domconfig{'defaults'}{'timezone_def'}; $domdefaults{'datelocale_def'} = $domconfig{'defaults'}{'datelocale_def'}; $domdefaults{'portal_def'} = $domconfig{'defaults'}{'portal_def'}; - $domdefaults{'intauth_cost'} = $domconfig{'defaults'}{'intauth_cost'}; - $domdefaults{'intauth_switch'} = $domconfig{'defaults'}{'intauth_switch'}; - $domdefaults{'intauth_check'} = $domconfig{'defaults'}{'intauth_check'}; } else { $domdefaults{'lang_def'} = &domain($domain,'lang_def'); $domdefaults{'auth_def'} = &domain($domain,'auth_def'); @@ -2373,7 +2033,7 @@ sub get_domain_defaults { } } if (ref($domconfig{'requestcourses'}) eq 'HASH') { - foreach my $item ('official','unofficial','community','textbook') { + foreach my $item ('official','unofficial','community') { $domdefaults{$item} = $domconfig{'requestcourses'}{$item}; } } @@ -2381,44 +2041,20 @@ sub get_domain_defaults { $domdefaults{'requestauthor'} = $domconfig{'requestauthor'}; } if (ref($domconfig{'inststatus'}) eq 'HASH') { - foreach my $item ('inststatustypes','inststatusorder','inststatusguest') { + foreach my $item ('inststatustypes','inststatusorder') { $domdefaults{$item} = $domconfig{'inststatus'}{$item}; } } if (ref($domconfig{'coursedefaults'}) eq 'HASH') { - $domdefaults{'usejsme'} = $domconfig{'coursedefaults'}{'usejsme'}; - $domdefaults{'uselcmath'} = $domconfig{'coursedefaults'}{'uselcmath'}; - if (ref($domconfig{'coursedefaults'}{'postsubmit'}) eq 'HASH') { - $domdefaults{'postsubmit'} = $domconfig{'coursedefaults'}{'postsubmit'}{'client'}; - } - foreach my $type (@coursetypes) { - if (ref($domconfig{'coursedefaults'}{'coursecredits'}) eq 'HASH') { - unless ($type eq 'community') { - $domdefaults{$type.'credits'} = $domconfig{'coursedefaults'}{'coursecredits'}{$type}; - } - } - if (ref($domconfig{'coursedefaults'}{'uploadquota'}) eq 'HASH') { - $domdefaults{$type.'quota'} = $domconfig{'coursedefaults'}{'uploadquota'}{$type}; - } - if ($domdefaults{'postsubmit'} eq 'on') { - if (ref($domconfig{'coursedefaults'}{'postsubmit'}{'timeout'}) eq 'HASH') { - $domdefaults{$type.'postsubtimeout'} = - $domconfig{'coursedefaults'}{'postsubmit'}{'timeout'}{$type}; - } - } - } - if (ref($domconfig{'coursedefaults'}{'canclone'}) eq 'HASH') { - if (ref($domconfig{'coursedefaults'}{'canclone'}{'instcode'}) eq 'ARRAY') { - my @clonecodes = @{$domconfig{'coursedefaults'}{'canclone'}{'instcode'}}; - if (@clonecodes) { - $domdefaults{'canclone'} = join('+',@clonecodes); - } - } - } elsif ($domconfig{'coursedefaults'}{'canclone'}) { - $domdefaults{'canclone'}=$domconfig{'coursedefaults'}{'canclone'}; - } - if ($domconfig{'coursedefaults'}{'texengine'}) { - $domdefaults{'texengine'} = $domconfig{'coursedefaults'}{'texengine'}; + $domdefaults{'canuse_pdfforms'} = $domconfig{'coursedefaults'}{'canuse_pdfforms'}; + if (ref($domconfig{'coursedefaults'}{'coursecredits'}) eq 'HASH') { + $domdefaults{'officialcredits'} = $domconfig{'coursedefaults'}{'coursecredits'}{'official'}; + $domdefaults{'unofficialcredits'} = $domconfig{'coursedefaults'}{'coursecredits'}{'unofficial'}; + } + if (ref($domconfig{'coursedefaults'}{'uploadquota'}) eq 'HASH') { + $domdefaults{'officialquota'} = $domconfig{'coursedefaults'}{'uploadquota'}{'official'}; + $domdefaults{'unofficialquota'} = $domconfig{'coursedefaults'}{'uploadquota'}{'unofficial'}; + $domdefaults{'communityquota'} = $domconfig{'coursedefaults'}{'uploadquota'}{'community'}; } } if (ref($domconfig{'usersessions'}) eq 'HASH') { @@ -2428,146 +2064,11 @@ sub get_domain_defaults { if (ref($domconfig{'usersessions'}{'hosted'}) eq 'HASH') { $domdefaults{'hostedsessions'} = $domconfig{'usersessions'}{'hosted'}; } - if (ref($domconfig{'usersessions'}{'offloadnow'}) eq 'HASH') { - $domdefaults{'offloadnow'} = $domconfig{'usersessions'}{'offloadnow'}; - } - if (ref($domconfig{'usersessions'}{'offloadoth'}) eq 'HASH') { - $domdefaults{'offloadoth'} = $domconfig{'usersessions'}{'offloadoth'}; - } - } - if (ref($domconfig{'selfenrollment'}) eq 'HASH') { - if (ref($domconfig{'selfenrollment'}{'admin'}) eq 'HASH') { - my @settings = ('types','registered','enroll_dates','access_dates','section', - 'approval','limit'); - foreach my $type (@coursetypes) { - if (ref($domconfig{'selfenrollment'}{'admin'}{$type}) eq 'HASH') { - my @mgrdc = (); - foreach my $item (@settings) { - if ($domconfig{'selfenrollment'}{'admin'}{$type}{$item} eq '0') { - push(@mgrdc,$item); - } - } - if (@mgrdc) { - $domdefaults{$type.'selfenrolladmdc'} = join(',',@mgrdc); - } - } - } - } - if (ref($domconfig{'selfenrollment'}{'default'}) eq 'HASH') { - foreach my $type (@coursetypes) { - if (ref($domconfig{'selfenrollment'}{'default'}{$type}) eq 'HASH') { - foreach my $item (keys(%{$domconfig{'selfenrollment'}{'default'}{$type}})) { - $domdefaults{$type.'selfenroll'.$item} = $domconfig{'selfenrollment'}{'default'}{$type}{$item}; - } - } - } - } - } - if (ref($domconfig{'coursecategories'}) eq 'HASH') { - $domdefaults{'catauth'} = 'std'; - $domdefaults{'catunauth'} = 'std'; - if ($domconfig{'coursecategories'}{'auth'}) { - $domdefaults{'catauth'} = $domconfig{'coursecategories'}{'auth'}; - } - if ($domconfig{'coursecategories'}{'unauth'}) { - $domdefaults{'catunauth'} = $domconfig{'coursecategories'}{'unauth'}; - } - } - if (ref($domconfig{'autoenroll'}) eq 'HASH') { - $domdefaults{'autofailsafe'} = $domconfig{'autoenroll'}{'autofailsafe'}; - } - if (ref($domconfig{'helpsettings'}) eq 'HASH') { - $domdefaults{'submitbugs'} = $domconfig{'helpsettings'}{'submitbugs'}; - if (ref($domconfig{'helpsettings'}{'adhoc'}) eq 'HASH') { - $domdefaults{'adhocroles'} = $domconfig{'helpsettings'}{'adhoc'}; - } } &do_cache_new('domdefaults',$domain,\%domdefaults,$cachetime); return %domdefaults; } -sub get_dom_cats { - my ($dom) = @_; - return unless (&domain($dom)); - my ($cats,$cached)=&is_cached_new('cats',$dom); - unless (defined($cached)) { - my %domconfig = &get_dom('configuration',['coursecategories'],$dom); - if (ref($domconfig{'coursecategories'}) eq 'HASH') { - if (ref($domconfig{'coursecategories'}{'cats'}) eq 'HASH') { - %{$cats} = %{$domconfig{'coursecategories'}{'cats'}}; - } else { - $cats = {}; - } - } else { - $cats = {}; - } - &Apache::lonnet::do_cache_new('cats',$dom,$cats,3600); - } - return $cats; -} - -sub get_dom_instcats { - my ($dom) = @_; - return unless (&domain($dom)); - my ($instcats,$cached)=&is_cached_new('instcats',$dom); - unless (defined($cached)) { - my (%coursecodes,%codes,@codetitles,%cat_titles,%cat_order); - my $totcodes = &retrieve_instcodes(\%coursecodes,$dom); - if ($totcodes > 0) { - my $caller = 'global'; - if (&auto_instcode_format($caller,$dom,\%coursecodes,\%codes, - \@codetitles,\%cat_titles,\%cat_order) eq 'ok') { - $instcats = { - codes => \%codes, - codetitles => \@codetitles, - cat_titles => \%cat_titles, - cat_order => \%cat_order, - }; - &do_cache_new('instcats',$dom,$instcats,3600); - } - } - } - return $instcats; -} - -sub retrieve_instcodes { - my ($coursecodes,$dom) = @_; - my $totcodes; - my %courses = &courseiddump($dom,'.',1,'.','.','.',undef,undef,'Course'); - foreach my $course (keys(%courses)) { - if (ref($courses{$course}) eq 'HASH') { - if ($courses{$course}{'inst_code'} ne '') { - $$coursecodes{$course} = $courses{$course}{'inst_code'}; - $totcodes ++; - } - } - } - return $totcodes; -} - -# --------------------------------------------- Get domain config for passwords - -sub get_passwdconf { - my ($dom) = @_; - my (%passwdconf,$gotconf,$lookup); - my ($result,$cached)=&is_cached_new('passwdconf',$dom); - if (defined($cached)) { - if (ref($result) eq 'HASH') { - %passwdconf = %{$result}; - $gotconf = 1; - } - } - unless ($gotconf) { - my %domconfig = &get_dom('configuration',['passwords'],$dom); - if (ref($domconfig{'passwords'}) eq 'HASH') { - %passwdconf = %{$domconfig{'passwords'}}; - } - my $cachetime = 24*60*60; - &do_cache_new('passwdconf',$dom,\%passwdconf,$cachetime); - } - return %passwdconf; -} - # --------------------------------------------------- Assign a key to a student sub assign_access_key { @@ -2804,25 +2305,21 @@ sub make_key { sub devalidate_cache_new { my ($name,$id,$debug) = @_; if ($debug) { &Apache::lonnet::logthis("deleting $name:$id"); } - my $remembered_id=$name.':'.$id; $id=&make_key($name,$id); $memcache->delete($id); - delete($remembered{$remembered_id}); - delete($accessed{$remembered_id}); + delete($remembered{$id}); + delete($accessed{$id}); } sub is_cached_new { my ($name,$id,$debug) = @_; - my $remembered_id=$name.':'.$id; # this is to avoid make_key (which is slow) for - # keys in %remembered hash, which persists for - # duration of request (no restriction on key length). - if (exists($remembered{$remembered_id})) { - if ($debug) { &Apache::lonnet::logthis("Early return $remembered_id of $remembered{$remembered_id} "); } - $accessed{$remembered_id}=[&gettimeofday()]; + $id=&make_key($name,$id); + if (exists($remembered{$id})) { + if ($debug) { &Apache::lonnet::logthis("Early return $id of $remembered{$id} "); } + $accessed{$id}=[&gettimeofday()]; $hits++; - return ($remembered{$remembered_id},1); + return ($remembered{$id},1); } - $id=&make_key($name,$id); my $value = $memcache->get($id); if (!(defined($value))) { if ($debug) { &Apache::lonnet::logthis("getting $id is not defined"); } @@ -2832,14 +2329,13 @@ sub is_cached_new { if ($debug) { &Apache::lonnet::logthis("getting $id is __undef__"); } $value=undef; } - &make_room($remembered_id,$value,$debug); + &make_room($id,$value,$debug); if ($debug) { &Apache::lonnet::logthis("getting $id is $value"); } return ($value,1); } sub do_cache_new { my ($name,$id,$value,$time,$debug) = @_; - my $remembered_id=$name.':'.$id; $id=&make_key($name,$id); my $setvalue=$value; if (!defined($setvalue)) { @@ -2855,17 +2351,17 @@ sub do_cache_new { $memcache->disconnect_all(); } # need to make a copy of $value - &make_room($remembered_id,$value,$debug); + &make_room($id,$value,$debug); return $value; } sub make_room { - my ($remembered_id,$value,$debug)=@_; + my ($id,$value,$debug)=@_; - $remembered{$remembered_id}= (ref($value)) ? &Storable::dclone($value) + $remembered{$id}= (ref($value)) ? &Storable::dclone($value) : $value; if ($to_remember<0) { return; } - $accessed{$remembered_id}=[&gettimeofday()]; + $accessed{$id}=[&gettimeofday()]; if (scalar(keys(%remembered)) <= $to_remember) { return; } my $to_kick; my $max_time=0; @@ -3103,27 +2599,6 @@ sub repcopy { } } -# ------------------------------------------------- Unsubscribe from a resource - -sub unsubscribe { - my ($fname) = @_; - my $answer; - if ($fname=~/\/(aboutme|syllabus|bulletinboard|smppg)$/) { return $answer; } - $fname=~s/[\n\r]//g; - my $author=$fname; - $author=~s/\/home\/httpd\/html\/res\/([^\/]*)\/([^\/]*).*/$1\/$2/; - my ($udom,$uname)=split(/\//,$author); - my $home=homeserver($uname,$udom); - if ($home eq 'no_host') { - $answer = 'no_host'; - } elsif (grep { $_ eq $home } ¤t_machine_ids()) { - $answer = 'home'; - } else { - $answer = reply("unsub:$fname",$home); - } - return $answer; -} - # ------------------------------------------------ Get server side include body sub ssi_body { my ($filelink,%form)=@_; @@ -3173,51 +2648,27 @@ sub absolute_url { sub ssi { my ($fn,%form)=@_; - my ($request,$response); + my $ua=new LWP::UserAgent; + my $request; $form{'no_update_last_known'}=1; &Apache::lonenc::check_encrypt(\$fn); if (%form) { $request=new HTTP::Request('POST',&absolute_url().$fn); - $request->content(join('&',map { - my $name = escape($_); - "$name=" . ( ref($form{$_}) eq 'ARRAY' - ? join("&$name=", map {escape($_) } @{$form{$_}}) - : &escape($form{$_}) ); - } keys(%form))); + $request->content(join('&',map { &escape($_).'='.&escape($form{$_}) } keys(%form))); } else { $request=new HTTP::Request('GET',&absolute_url().$fn); } $request->header(Cookie => $ENV{'HTTP_COOKIE'}); + my $response= $ua->request($request); + my $content = $response->content; + - if (($env{'request.course.id'}) && - ($form{'grade_courseid'} eq $env{'request.course.id'}) && - ($form{'grade_username'} ne '') && ($form{'grade_domain'} ne '') && - ($form{'grade_symb'} ne '') && - (&Apache::lonnet::allowed('mgr',$env{'request.course.id'}. - ($env{'request.course.sec'}?'/'.$env{'request.course.sec'}:'')))) { - if (LWP::UserAgent->VERSION >= 5.834) { - my $ua=new LWP::UserAgent; - $ua->local_address('127.0.0.1'); - $response = $ua->request($request); - } else { - { - require LWP::Protocol::http; - local @LWP::Protocol::http::EXTRA_SOCK_OPTS = (LocalAddr => '127.0.0.1'); - my $ua=new LWP::UserAgent; - $response = $ua->request($request); - @LWP::Protocol::http::EXTRA_SOCK_OPTS = (); - } - } - } else { - my $ua=new LWP::UserAgent; - $response = $ua->request($request); - } if (wantarray) { - return ($response->content, $response); + return ($content, $response); } else { - return $response->content; + return $content; } } @@ -3233,78 +2684,6 @@ sub externalssi { } } -# If the local copy of a replicated resource is outdated, trigger a -# connection from the homeserver to flush the delayed queue. If no update -# happens, remove local copies of outdated resource (and corresponding -# metadata file). - -sub remove_stale_resfile { - my ($url) = @_; - my $removed; - if ($url=~m{^/res/($match_domain)/($match_username)/}) { - my $audom = $1; - my $auname = $2; - unless (($url =~ /\.\d+\.\w+$/) || ($url =~ m{^/res/lib/templates/})) { - my $homeserver = &homeserver($auname,$audom); - unless (($homeserver eq 'no_host') || - (grep { $_ eq $homeserver } ¤t_machine_ids())) { - my $fname = &filelocation('',$url); - if (-e $fname) { - my $hostname = &hostname($homeserver); - if ($hostname) { - my $protocol = $protocol{$homeserver}; - $protocol = 'http' if ($protocol ne 'https'); - my $uri = $protocol.'://'.$hostname.'/raw/'.&declutter($url); - my $ua=new LWP::UserAgent; - $ua->timeout(5); - my $request=new HTTP::Request('HEAD',$uri); - my $response=$ua->request($request); - if ($response->is_success()) { - my $remmodtime = &HTTP::Date::str2time( $response->header('Last-modified') ); - my $locmodtime = (stat($fname))[9]; - if ($locmodtime < $remmodtime) { - my $stale; - my $answer = &reply('pong',$homeserver); - if ($answer eq $homeserver.':'.$perlvar{'lonHostID'}) { - sleep(0.2); - $locmodtime = (stat($fname))[9]; - if ($locmodtime < $remmodtime) { - my $posstransfer = $fname.'.in.transfer'; - if ((-e $posstransfer) && ($remmodtime < (stat($posstransfer))[9])) { - $removed = 1; - } else { - $stale = 1; - } - } else { - $removed = 1; - } - } else { - $stale = 1; - } - if ($stale) { - if (unlink($fname)) { - if ($uri!~/\.meta$/) { - if (-e $fname.'.meta') { - unlink($fname.'.meta'); - } - } - my $unsubresult = &unsubscribe($fname); - unless ($unsubresult eq 'ok') { - &logthis("no unsub of $fname from $homeserver, reason: $unsubresult"); - } - $removed = 1; - } - } - } - } - } - } - } - } - } - return $removed; -} - # -------------------------------- Allow a /uploaded/ URI to be vouched for sub allowuploaded { @@ -3321,7 +2700,7 @@ sub allowuploaded { # # Determine if the current user should be able to edit a particular resource, # when viewing in course context. -# (a) When viewing resource used to determine if "Edit" item is included in +# (a) When viewing resource used to determine if "Edit" item is included in # Functions. # (b) When displaying folder contents in course editor, used to determine if # "Edit" link will be displayed alongside resource. @@ -3329,12 +2708,12 @@ sub allowuploaded { # input: six args -- filename (decluttered), course number, course domain, # url, symb (if registered) and group (if this is a group # item -- e.g., bulletin board, group page etc.). -# output: array of five scalars -- +# output: array of five scalars -- # $cfile -- url for file editing if editable on current server # $home -- homeserver of resource (i.e., for author if published, # or course if uploaded.). # $switchserver -- 1 if server switch will be needed. -# $forceedit -- 1 if icon/link should be to go to edit mode +# $forceedit -- 1 if icon/link should be to go to edit mode # $forceview -- 1 if icon/link should be to go to view mode # @@ -3423,7 +2802,7 @@ sub can_edit_resource { $forceedit = 1; } $cfile = $resurl; - } elsif (($resurl ne '') && (&is_on_map($resurl))) { + } elsif (($resurl ne '') && (&is_on_map($resurl))) { if ($resurl =~ m{^/adm/$match_domain/$match_username/\d+/smppg|bulletinboard$}) { $incourse = 1; if ($env{'form.forceedit'}) { @@ -3443,18 +2822,6 @@ sub can_edit_resource { $forceedit = 1; } $cfile = $resurl; - } elsif (($resurl =~ m{^/ext/}) && ($symb ne '')) { - my ($map,$id,$res) = &decode_symb($symb); - if ($map =~ /\.page$/) { - $incourse = 1; - if ($env{'form.forceedit'}) { - $forceview = 1; - $cfile = $map; - } else { - $forceedit = 1; - $cfile = '/adm/wrapper'.$resurl; - } - } } elsif ($resurl =~ m{^/?adm/viewclasslist$}) { $incourse = 1; if ($env{'form.forceedit'}) { @@ -3466,19 +2833,19 @@ sub can_edit_resource { } } elsif ($resurl eq '/res/lib/templates/simpleproblem.problem/smpedit') { my $template = '/res/lib/templates/simpleproblem.problem'; - if (&is_on_map($template)) { + if (&is_on_map($template)) { $incourse = 1; $forceview = 1; $cfile = $template; } } elsif (($resurl =~ m{^/adm/wrapper/ext/}) && ($env{'form.folderpath'} =~ /^supplemental/)) { - $incourse = 1; - if ($env{'form.forceedit'}) { - $forceview = 1; - } else { - $forceedit = 1; - } - $cfile = $resurl; + $incourse = 1; + if ($env{'form.forceedit'}) { + $forceview = 1; + } else { + $forceedit = 1; + } + $cfile = $resurl; } elsif (($resurl eq '/adm/extresedit') && ($symb || $env{'form.folderpath'})) { $incourse = 1; $forceview = 1; @@ -3513,7 +2880,7 @@ sub can_edit_resource { $cfile=$file; } } - if (($cfile ne '') && (!$incourse || $uploaded) && + if (($cfile ne '') && (!$incourse || $uploaded) && (($home ne '') && ($home ne 'no_host'))) { my @ids=¤t_machine_ids(); unless (grep(/^\Q$home\E$/,@ids)) { @@ -3540,9 +2907,9 @@ sub in_course { if ($hideprivileged) { my $skipuser; my %coursehash = &coursedescription($cdom.'_'.$cnum); - my @possdoms = ($cdom); - if ($coursehash{'checkforpriv'}) { - push(@possdoms,split(/,/,$coursehash{'checkforpriv'})); + my @possdoms = ($cdom); + if ($coursehash{'checkforpriv'}) { + push(@possdoms,split(/,/,$coursehash{'checkforpriv'})); } if (&privileged($uname,$udom,\@possdoms)) { $skipuser = 1; @@ -3645,7 +3012,7 @@ sub process_coursefile { $home); } } elsif ($action eq 'uploaddoc') { - open(my $fh,'>',$filepath.'/'.$fname); + open(my $fh,'>'.$filepath.'/'.$fname); print $fh $env{'form.'.$source}; close($fh); if ($parser eq 'parse') { @@ -3703,7 +3070,7 @@ sub store_edited_file { ($fpath,$fname) = ($file =~ m|^(.*)/([^/]+)$|); $fpath=$docudom.'/'.$docuname.'/'.$fpath; my $filepath = &build_filepath($fpath); - open(my $fh,'>',$filepath.'/'.$fname); + open(my $fh,'>'.$filepath.'/'.$fname); print $fh $content; close($fh); my $home=&homeserver($docuname,$docudom); @@ -3728,21 +3095,13 @@ sub clean_filename { } # Replace spaces by underscores $fname=~s/\s+/\_/g; -# Transliterate non-ascii text to ascii - my $lang = &Apache::lonlocal::current_language(); - $fname = &LONCAPA::transliterate::fname_to_ascii($fname,$lang); # Replace all other weird characters by nothing $fname=~s{[^/\w\.\-]}{}g; # Replace all .\d. sequences with _\d. so they no longer look like version # numbers $fname=~s/\.(\d+)(?=\.)/_$1/g; -# Replace three or more adjacent underscores with one for consistency -# with loncfile::filename_check() so complete url can be extracted by -# lonnet::decode_symb() - $fname=~s/_{3,}/_/g; return $fname; } - # This Function checks if an Image's dimensions exceed either $resizewidth (width) # or $resizeheight (height) - both pixels. If so, the image is scaled to produce an # image with the same aspect ratio as the original, but with dimensions which do @@ -3785,16 +3144,13 @@ sub resizeImage { # input: $formname - the contents of the file are in $env{"form.$formname"} # the desired filename is in $env{"form.$formname.filename"} # $context - possible values: coursedoc, existingfile, overwrite, -# canceloverwrite, scantron or ''. +# canceloverwrite, or ''. # if 'coursedoc': upload to the current course # if 'existingfile': write file to tmp/overwrites directory # if 'canceloverwrite': delete file written to tmp/overwrites directory # $context is passed as argument to &finishuserfileupload # $subdir - directory in userfile to store the file into -# $parser - instruction to parse file for objects ($parser = parse) or -# if context is 'scantron', $parser is hashref of csv column mapping -# (e.g.,{ PaperID => 0, LastName => 1, FirstName => 2, ID => 3, -# Section => 4, CODE => 5, FirstQuestion => 9 }). +# $parser - instruction to parse file for objects ($parser = parse) # $allfiles - reference to hash for embedded objects # $codebase - reference to hash for codebase of java objects # $desuname - username for permanent storage of uploaded file @@ -3817,14 +3173,6 @@ sub userfileupload { $fname=&clean_filename($fname); # See if there is anything left unless ($fname) { return 'error: no uploaded file'; } - # If filename now begins with a . prepend unix timestamp _ milliseconds - if ($fname =~ /^\./) { - my ($s,$usec) = &gettimeofday(); - while (length($usec) < 6) { - $usec = '0'.$usec; - } - $fname = $s.'_'.substr($usec,0,3).$fname; - } # Files uploaded to help request form, or uploaded to "create course" page are handled differently if ((($formname eq 'screenshot') && ($subdir eq 'helprequests')) || (($formname eq 'coursecreatorxml') && ($subdir eq 'batchupload')) || @@ -3838,12 +3186,12 @@ sub userfileupload { '_'.$env{'user.domain'}.'/pending'; } elsif (($context eq 'existingfile') || ($context eq 'canceloverwrite')) { my ($docuname,$docudom); - if ($destudom =~ /^$match_domain$/) { + if ($destudom) { $docudom = $destudom; } else { $docudom = $env{'user.domain'}; } - if ($destuname =~ /^$match_username$/) { + if ($destuname) { $docuname = $destuname; } else { $docuname = $env{'user.name'}; @@ -3873,7 +3221,7 @@ sub userfileupload { mkdir($fullpath,0777); } } - open(my $fh,'>',$fullpath.'/'.$fname); + open(my $fh,'>'.$fullpath.'/'.$fname); print $fh $env{'form.'.$formname}; close($fh); if ($context eq 'existingfile') { @@ -3948,7 +3296,7 @@ sub finishuserfileupload { # Save the file { - if (!open(FH,'>',$filepath.'/'.$file)) { + if (!open(FH,'>'.$filepath.'/'.$file)) { &logthis('Failed to create '.$filepath.'/'.$file); print STDERR ('Failed to create '.$filepath.'/'.$file."\n"); return '/adm/notfound.html'; @@ -3992,7 +3340,7 @@ sub finishuserfileupload { } } } - if (($context ne 'scantron') && ($parser eq 'parse')) { + if ($parser eq 'parse') { if ((ref($mimetype)) && ($$mimetype eq 'text/html')) { my $parse_result = &extract_embedded_items($filepath.'/'.$file, $allfiles,$codebase); @@ -4001,16 +3349,12 @@ sub finishuserfileupload { ' for embedded media: '.$parse_result); } } - } elsif (($context eq 'scantron') && (ref($parser) eq 'HASH')) { - my $format = $env{'form.scantron_format'}; - &bubblesheet_converter($docudom,$filepath.'/'.$file,$parser,$format); } if (($thumbwidth =~ /^\d+$/) && ($thumbheight =~ /^\d+$/)) { my $input = $filepath.'/'.$file; my $output = $filepath.'/'.'tn-'.$file; my $thumbsize = $thumbwidth.'x'.$thumbheight; - my @args = ('convert','-sample',$thumbsize,$input,$output); - system({$args[0]} @args); + system("convert -sample $thumbsize $input $output"); if (-e $filepath.'/'.'tn-'.$file) { $fetchthumb = 1; } @@ -4069,7 +3413,7 @@ sub extract_embedded_items { } if (lc($tagname) eq 'a') { unless (($attr->{'href'} =~ /^#/) || ($attr->{'href'} eq '')) { - &add_filetype($allfiles,$attr->{'href'},'href'); + &add_filetype($allfiles,$attr->{'href'},'href'); } } if (lc($tagname) eq 'script') { @@ -4244,246 +3588,6 @@ sub embedded_dependency { return; } -sub bubblesheet_converter { - my ($cdom,$fullpath,$config,$format) = @_; - if ((&domain($cdom) ne '') && - ($fullpath =~ m{^\Q$perlvar{'lonDocRoot'}/userfiles/$cdom/\E$match_courseid/scantron_orig}) && - (-e $fullpath) && (ref($config) eq 'HASH') && ($format ne '')) { - my (%csvcols,%csvoptions); - if (ref($config->{'fields'}) eq 'HASH') { - %csvcols = %{$config->{'fields'}}; - } - if (ref($config->{'options'}) eq 'HASH') { - %csvoptions = %{$config->{'options'}}; - } - my %csvbynum = reverse(%csvcols); - my %scantronconf = &get_scantron_config($format,$cdom); - if (keys(%scantronconf)) { - my %bynum = ( - $scantronconf{CODEstart} => 'CODEstart', - $scantronconf{IDstart} => 'IDstart', - $scantronconf{PaperID} => 'PaperID', - $scantronconf{FirstName} => 'FirstName', - $scantronconf{LastName} => 'LastName', - $scantronconf{Qstart} => 'Qstart', - ); - my @ordered; - foreach my $item (sort { $a <=> $b } keys(%bynum)) { - push(@ordered,$bynum{$item}); - } - my %mapstart = ( - CODEstart => 'CODE', - IDstart => 'ID', - PaperID => 'PaperID', - FirstName => 'FirstName', - LastName => 'LastName', - Qstart => 'FirstQuestion', - ); - my %maplength = ( - CODEstart => 'CODElength', - IDstart => 'IDlength', - PaperID => 'PaperIDlength', - FirstName => 'FirstNamelength', - LastName => 'LastNamelength', - ); - if (open(my $fh,'<',$fullpath)) { - my $output; - my %lettdig = &letter_to_digits(); - my %diglett = reverse(%lettdig); - my $numletts = scalar(keys(%lettdig)); - my $num = 0; - while (my $line=<$fh>) { - $num ++; - next if (($num == 1) && ($csvoptions{'hdr'} == 1)); - $line =~ s{[\r\n]+$}{}; - my %found; - my @values = split(/,/,$line); - my ($qstart,$record); - for (my $i=0; $i<@values; $i++) { - if ((($qstart ne '') && ($i > $qstart)) || - ($csvbynum{$i} eq 'FirstQuestion')) { - if ($values[$i] eq '') { - $values[$i] = $scantronconf{'Qoff'}; - } elsif ($scantronconf{'Qon'} eq 'number') { - if ($values[$i] =~ /^[A-Ja-j]$/) { - $values[$i] = $lettdig{uc($values[$i])}; - } - } elsif ($scantronconf{'Qon'} eq 'letter') { - if ($values[$i] =~ /^[0-9]$/) { - $values[$i] = $diglett{$values[$i]}; - } - } else { - if ($values[$i] =~ /^[0-9A-Ja-j]$/) { - my $digit; - if ($values[$i] =~ /^[A-Ja-j]$/) { - $digit = $lettdig{uc($values[$i])}-1; - if ($values[$i] eq 'J') { - $digit += $numletts; - } - } elsif ($values[$i] =~ /^[0-9]$/) { - $digit = $values[$i]-1; - if ($values[$i] eq '0') { - $digit += $numletts; - } - } - my $qval=''; - for (my $j=0; $j<$scantronconf{'Qlength'}; $j++) { - if ($j == $digit) { - $qval .= $scantronconf{'Qon'}; - } else { - $qval .= $scantronconf{'Qoff'}; - } - } - $values[$i] = $qval; - } - } - if (length($values[$i]) > $scantronconf{'Qlength'}) { - $values[$i] = substr($values[$i],0,$scantronconf{'Qlength'}); - } - my $numblank = $scantronconf{'Qlength'} - length($values[$i]); - if ($numblank > 0) { - $values[$i] .= ($scantronconf{'Qoff'} x $numblank); - } - if ($csvbynum{$i} eq 'FirstQuestion') { - $qstart = $i; - $found{$csvbynum{$i}} = $values[$i]; - } else { - $found{'FirstQuestion'} .= $values[$i]; - } - } elsif (exists($csvbynum{$i})) { - if ($csvoptions{'rem'}) { - $values[$i] =~ s/^\s+//; - } - if (($csvbynum{$i} eq 'PaperID') && ($csvoptions{'pad'})) { - while (length($values[$i]) < $scantronconf{$maplength{$csvbynum{$i}}}) { - $values[$i] = '0'.$values[$i]; - } - } - $found{$csvbynum{$i}} = $values[$i]; - } - } - foreach my $item (@ordered) { - my $currlength = 1+length($record); - my $numspaces = $scantronconf{$item} - $currlength; - if ($numspaces > 0) { - $record .= (' ' x $numspaces); - } - if (($mapstart{$item} ne '') && (exists($found{$mapstart{$item}}))) { - unless ($item eq 'Qstart') { - if (length($found{$mapstart{$item}}) > $scantronconf{$maplength{$item}}) { - $found{$mapstart{$item}} = substr($found{$mapstart{$item}},0,$scantronconf{$maplength{$item}}); - } - } - $record .= $found{$mapstart{$item}}; - } - } - $output .= "$record\n"; - } - close($fh); - if ($output) { - if (open(my $fh,'>',$fullpath)) { - print $fh $output; - close($fh); - } - } - } - } - return; - } -} - -sub letter_to_digits { - my %lettdig = ( - A => 1, - B => 2, - C => 3, - D => 4, - E => 5, - F => 6, - G => 7, - H => 8, - I => 9, - J => 0, - ); - return %lettdig; -} - -sub get_scantron_config { - my ($which,$cdom) = @_; - my @lines = &get_scantronformat_file($cdom); - my %config; - #FIXME probably should move to XML it has already gotten a bit much now - foreach my $line (@lines) { - my ($name,$descrip)=split(/:/,$line); - if ($name ne $which ) { next; } - chomp($line); - my @config=split(/:/,$line); - $config{'name'}=$config[0]; - $config{'description'}=$config[1]; - $config{'CODElocation'}=$config[2]; - $config{'CODEstart'}=$config[3]; - $config{'CODElength'}=$config[4]; - $config{'IDstart'}=$config[5]; - $config{'IDlength'}=$config[6]; - $config{'Qstart'}=$config[7]; - $config{'Qlength'}=$config[8]; - $config{'Qoff'}=$config[9]; - $config{'Qon'}=$config[10]; - $config{'PaperID'}=$config[11]; - $config{'PaperIDlength'}=$config[12]; - $config{'FirstName'}=$config[13]; - $config{'FirstNamelength'}=$config[14]; - $config{'LastName'}=$config[15]; - $config{'LastNamelength'}=$config[16]; - $config{'BubblesPerRow'}=$config[17]; - last; - } - return %config; -} - -sub get_scantronformat_file { - my ($cdom) = @_; - if ($cdom eq '') { - $cdom= $env{'course.'.$env{'request.course.id'}.'.domain'}; - } - my %domconfig = &get_dom('configuration',['scantron'],$cdom); - my $gottab = 0; - my @lines; - if (ref($domconfig{'scantron'}) eq 'HASH') { - if ($domconfig{'scantron'}{'scantronformat'} ne '') { - my $formatfile = &getfile($perlvar{'lonDocRoot'}.$domconfig{'scantron'}{'scantronformat'}); - if ($formatfile ne '-1') { - @lines = split("\n",$formatfile,-1); - $gottab = 1; - } - } - } - if (!$gottab) { - my $confname = $cdom.'-domainconfig'; - my $default = $perlvar{'lonDocRoot'}.'/res/'.$cdom.'/'.$confname.'/default.tab'; - my $formatfile = &getfile($default); - if ($formatfile ne '-1') { - @lines = split("\n",$formatfile,-1); - $gottab = 1; - } - } - if (!$gottab) { - my @domains = ¤t_machine_domains(); - if (grep(/^\Q$cdom\E$/,@domains)) { - if (open(my $fh,'<',$perlvar{'lonTabDir'}.'/scantronformat.tab')) { - @lines = <$fh>; - close($fh); - } - } else { - if (open(my $fh,'<',$perlvar{'lonTabDir'}.'/default_scantronformat.tab')) { - @lines = <$fh>; - close($fh); - } - } - } - return @lines; -} - sub removeuploadedurl { my ($url)=@_; my (undef,undef,$udom,$uname,$fname)=split('/',$url,5); @@ -4634,7 +3738,7 @@ sub flushcourselogs { } } # -# Reverse lookup of domain roles (dc, ad, li, sc, dh, da, au) +# Reverse lookup of domain roles (dc, ad, li, sc, au) # my %domrolebuffer = (); foreach my $entry (keys(%domainrolehash)) { @@ -4649,19 +3753,10 @@ sub flushcourselogs { delete $domainrolehash{$entry}; } foreach my $dom (keys(%domrolebuffer)) { - my %servers; - if (defined(&domain($dom,'primary'))) { - my $primary=&domain($dom,'primary'); - my $hostname=&hostname($primary); - $servers{$primary} = $hostname; - } else { - %servers = &get_servers($dom,'library'); - } + my %servers = &get_servers($dom,'library'); foreach my $tryserver (keys(%servers)) { - if (&reply('domroleput:'.$dom.':'. - $domrolebuffer{$dom},$tryserver) eq 'ok') { - last; - } else { + unless (&reply('domroleput:'.$dom.':'. + $domrolebuffer{$dom},$tryserver) eq 'ok') { &logthis('Put of domain roles failed for '.$dom.' and '.$tryserver); } } @@ -4710,11 +3805,7 @@ sub courseacclog { if ($formitem =~ /^HWFILE(?:SIZE|TOOBIG)/) { $what.=':'.$formitem.'='.$env{$key}; } elsif ($formitem !~ /^HWFILE(?:[^.]+)$/) { - if ($formitem eq 'proctorpassword') { - $what.=':'.$formitem.'=' . '*' x length($env{$key}); - } else { - $what.=':'.$formitem.'='.$env{$key}; - } + $what.=':'.$formitem.'='.$env{$key}; } } } @@ -4785,7 +3876,7 @@ sub userrolelog { {$trole.':'.$username.':'.$domain.':'.$env{'user.name'}.':'.$env{'user.domain'}.':'} =$tend.':'.$tstart; } - if ($trole =~ /^(dc|ad|li|au|dg|sc|dh|da)/ ) { + if ($trole =~ /^(dc|ad|li|au|dg|sc)/ ) { my (undef,$rudom,$runame,$rsec)=split(/\//,$area); $domainrolehash {$trole.':'.$username.':'.$domain.':'.$runame.':'.$rudom.':'.$rsec} @@ -4993,7 +4084,7 @@ sub get_my_roles { } else { my $possdoms = [$domain]; if (ref($roledoms) eq 'ARRAY') { - push(@{$possdoms},@{$roledoms}); + push(@{$possdoms},@{$roledoms}); } if (&privileged($username,$domain,$possdoms,\@privroles)) { if (!$nothide{$username.':'.$domain}) { @@ -5012,195 +4103,6 @@ sub get_my_roles { return %returnhash; } -sub get_all_adhocroles { - my ($dom) = @_; - my @roles_by_num = (); - my %domdefaults = &get_domain_defaults($dom); - my (%description,%access_in_dom,%access_info); - if (ref($domdefaults{'adhocroles'}) eq 'HASH') { - my $count = 0; - my %domcurrent = %{$domdefaults{'adhocroles'}}; - my %ordered; - foreach my $role (sort(keys(%domcurrent))) { - my ($order,$desc,$access_in_dom); - if (ref($domcurrent{$role}) eq 'HASH') { - $order = $domcurrent{$role}{'order'}; - $desc = $domcurrent{$role}{'desc'}; - $access_in_dom{$role} = $domcurrent{$role}{'access'}; - $access_info{$role} = $domcurrent{$role}{$access_in_dom{$role}}; - } - if ($order eq '') { - $order = $count; - } - $ordered{$order} = $role; - if ($desc ne '') { - $description{$role} = $desc; - } else { - $description{$role}= $role; - } - $count++; - } - foreach my $item (sort {$a <=> $b } (keys(%ordered))) { - push(@roles_by_num,$ordered{$item}); - } - } - return (\@roles_by_num,\%description,\%access_in_dom,\%access_info); -} - -sub get_my_adhocroles { - my ($cid,$checkreg) = @_; - my ($cdom,$cnum,%info,@possroles,$description,$roles_by_num); - if ($env{'request.course.id'} eq $cid) { - $cdom = $env{'course.'.$cid.'.domain'}; - $cnum = $env{'course.'.$cid.'.num'}; - $info{'internal.coursecode'} = $env{'course.'.$cid.'.internal.coursecode'}; - } elsif ($cid =~ /^($match_domain)_($match_courseid)$/) { - $cdom = $1; - $cnum = $2; - %info = &Apache::lonnet::get('environment',['internal.coursecode'], - $cdom,$cnum); - } - if (($info{'internal.coursecode'} ne '') && ($checkreg)) { - my $user = $env{'user.name'}.':'.$env{'user.domain'}; - my %rosterhash = &get('classlist',[$user],$cdom,$cnum); - if ($rosterhash{$user} ne '') { - my $type = (split(/:/,$rosterhash{$user}))[5]; - return ([],{}) if ($type eq 'auto'); - } - } - if (($cdom ne '') && ($cnum ne '')) { - if (($env{"user.role.dh./$cdom/"}) || ($env{"user.role.da./$cdom/"})) { - my $then=$env{'user.login.time'}; - my $update=$env{'user.update.time'}; - if (!$update) { - $update = $then; - } - my @liveroles; - foreach my $role ('dh','da') { - if ($env{"user.role.$role./$cdom/"}) { - my ($tstart,$tend)=split(/\./,$env{"user.role.$role./$cdom/"}); - my $limit = $update; - if ($env{'request.role'} eq "$role./$cdom/") { - $limit = $then; - } - my $activerole = 1; - if ($tstart && $tstart>$limit) { $activerole = 0; } - if ($tend && $tend <$limit) { $activerole = 0; } - if ($activerole) { - push(@liveroles,$role); - } - } - } - if (@liveroles) { - if (&homeserver($cnum,$cdom) ne 'no_host') { - my ($accessref,$accessinfo,%access_in_dom); - ($roles_by_num,$description,$accessref,$accessinfo) = &get_all_adhocroles($cdom); - if (ref($roles_by_num) eq 'ARRAY') { - if (@{$roles_by_num}) { - my %settings; - if ($env{'request.course.id'} eq $cid) { - foreach my $envkey (keys(%env)) { - if ($envkey =~ /^\Qcourse.$cid.\E(internal\.adhoc.+)$/) { - $settings{$1} = $env{$envkey}; - } - } - } else { - %settings = &dump('environment',$cdom,$cnum,'internal\.adhoc'); - } - my %setincrs; - if ($settings{'internal.adhocaccess'}) { - map { $setincrs{$_} = 1; } split(/,/,$settings{'internal.adhocaccess'}); - } - my @statuses; - if ($env{'environment.inststatus'}) { - @statuses = split(/,/,$env{'environment.inststatus'}); - } - my $user = $env{'user.name'}.':'.$env{'user.domain'}; - if (ref($accessref) eq 'HASH') { - %access_in_dom = %{$accessref}; - } - foreach my $role (@{$roles_by_num}) { - my ($curraccess,@okstatus,@personnel); - if ($setincrs{$role}) { - ($curraccess,my $rest) = split(/=/,$settings{'internal.adhoc.'.$role}); - if ($curraccess eq 'status') { - @okstatus = split(/\&/,$rest); - } elsif (($curraccess eq 'exc') || ($curraccess eq 'inc')) { - @personnel = split(/\&/,$rest); - } - } else { - $curraccess = $access_in_dom{$role}; - if (ref($accessinfo) eq 'HASH') { - if ($curraccess eq 'status') { - if (ref($accessinfo->{$role}) eq 'ARRAY') { - @okstatus = @{$accessinfo->{$role}}; - } - } elsif (($curraccess eq 'exc') || ($curraccess eq 'inc')) { - if (ref($accessinfo->{$role}) eq 'ARRAY') { - @personnel = @{$accessinfo->{$role}}; - } - } - } - } - if ($curraccess eq 'none') { - next; - } elsif ($curraccess eq 'all') { - push(@possroles,$role); - } elsif ($curraccess eq 'dh') { - if (grep(/^dh$/,@liveroles)) { - push(@possroles,$role); - } else { - next; - } - } elsif ($curraccess eq 'da') { - if (grep(/^da$/,@liveroles)) { - push(@possroles,$role); - } else { - next; - } - } elsif ($curraccess eq 'status') { - if (@okstatus) { - if (!@statuses) { - if (grep(/^default$/,@okstatus)) { - push(@possroles,$role); - } - } else { - foreach my $status (@okstatus) { - if (grep(/^\Q$status\E$/,@statuses)) { - push(@possroles,$role); - last; - } - } - } - } - } elsif (($curraccess eq 'exc') || ($curraccess eq 'inc')) { - if (grep(/^\Q$user\E$/,@personnel)) { - if ($curraccess eq 'exc') { - push(@possroles,$role); - } - } elsif ($curraccess eq 'inc') { - push(@possroles,$role); - } - } - } - } - } - } - } - } - } - unless (ref($description) eq 'HASH') { - if (ref($roles_by_num) eq 'ARRAY') { - my %desc; - map { $desc{$_} = $_; } (@{$roles_by_num}); - $description = \%desc; - } else { - $description = {}; - } - } - return (\@possroles,$description); -} - # ----------------------------------------------------- Frontpage Announcements # # @@ -5214,7 +4116,7 @@ sub postannounce { sub getannounce { - if (open(my $fh,"<",$perlvar{'lonDocRoot'}.'/announcement.txt')) { + if (open(my $fh,$perlvar{'lonDocRoot'}.'/announcement.txt')) { my $announcement=''; while (my $line = <$fh>) { $announcement .= $line; } close($fh); @@ -5276,8 +4178,7 @@ sub courseiddump { my ($domfilter,$descfilter,$sincefilter,$instcodefilter,$ownerfilter, $coursefilter,$hostidflag,$hostidref,$typefilter,$regexp_ok, $selfenrollonly,$catfilter,$showhidden,$caller,$cloner,$cc_clone, - $cloneonly,$createdbefore,$createdafter,$creationcontext,$domcloner, - $hasuniquecode,$reqcrsdom,$reqinstcode)=@_; + $cloneonly,$createdbefore,$createdafter,$creationcontext,$domcloner)=@_; my $as_hash = 1; my %returnhash; if (!$domfilter) { $domfilter=''; } @@ -5290,18 +4191,17 @@ sub courseiddump { if (($domfilter eq '') || (&host_domain($tryserver) eq $domfilter)) { my $rep; - if (grep { $_ eq $tryserver } ¤t_machine_ids()) { - $rep = &LONCAPA::Lond::dump_course_id_handler( - join(":", (&host_domain($tryserver), $sincefilter, - &escape($descfilter), &escape($instcodefilter), + if (grep { $_ eq $tryserver } current_machine_ids()) { + $rep = LONCAPA::Lond::dump_course_id_handler( + join(":", (&host_domain($tryserver), $sincefilter, + &escape($descfilter), &escape($instcodefilter), &escape($ownerfilter), &escape($coursefilter), - &escape($typefilter), &escape($regexp_ok), - $as_hash, &escape($selfenrollonly), - &escape($catfilter), $showhidden, $caller, - &escape($cloner), &escape($cc_clone), $cloneonly, - &escape($createdbefore), &escape($createdafter), - &escape($creationcontext),$domcloner,$hasuniquecode, - $reqcrsdom,&escape($reqinstcode)))); + &escape($typefilter), &escape($regexp_ok), + $as_hash, &escape($selfenrollonly), + &escape($catfilter), $showhidden, $caller, + &escape($cloner), &escape($cc_clone), $cloneonly, + &escape($createdbefore), &escape($createdafter), + &escape($creationcontext), $domcloner))); } else { $rep = &reply('courseiddump:'.&host_domain($tryserver).':'. $sincefilter.':'.&escape($descfilter).':'. @@ -5312,10 +4212,10 @@ sub courseiddump { $showhidden.':'.$caller.':'.&escape($cloner).':'. &escape($cc_clone).':'.$cloneonly.':'. &escape($createdbefore).':'.&escape($createdafter).':'. - &escape($creationcontext).':'.$domcloner.':'.$hasuniquecode. - ':'.$reqcrsdom.':'.&escape($reqinstcode),$tryserver); + &escape($creationcontext).':'.$domcloner, + $tryserver); } - + my @pairs=split(/\&/,$rep); foreach my $item (@pairs) { my ($key,$value)=split(/\=/,$item,2); @@ -5441,21 +4341,6 @@ sub get_domain_roles { return %personnel; } -sub get_active_domroles { - my ($dom,$roles) = @_; - return () unless (ref($roles) eq 'ARRAY'); - my $now = time; - my %dompersonnel = &get_domain_roles($dom,$roles,$now,$now); - my %domroles; - foreach my $server (keys(%dompersonnel)) { - foreach my $user (sort(keys(%{$dompersonnel{$server}}))) { - my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,$user); - $domroles{$uname.':'.$udom} = $dompersonnel{$server}{$user}; - } - } - return %domroles; -} - # ----------------------------------------------------------- Interval timing { @@ -5467,13 +4352,12 @@ my $cachedkey=''; # The cached times for this user my %cachedtimes=(); # When this was last done -my $cachedtime=''; +my $cachedtime=(); sub load_all_first_access { - my ($uname,$udom,$ignorecache)=@_; + my ($uname,$udom)=@_; if (($cachedkey eq $uname.':'.$udom) && - (abs($cachedtime-time)<5) && (!$env{'form.markaccess'}) && - (!$ignorecache)) { + (abs($cachedtime-time)<5) && (!$env{'form.markaccess'})) { return; } $cachedtime=time; @@ -5482,7 +4366,7 @@ sub load_all_first_access { } sub get_first_access { - my ($type,$argsymb,$argmap,$ignorecache)=@_; + my ($type,$argsymb,$argmap)=@_; my ($symb,$courseid,$udom,$uname)=&whichuser(); if ($argsymb) { $symb=$argsymb; } my ($map,$id,$res)=&decode_symb($symb); @@ -5494,7 +4378,7 @@ sub get_first_access { } else { $res=$symb; } - &load_all_first_access($uname,$udom,$ignorecache); + &load_all_first_access($uname,$udom); return $cachedtimes{"$courseid\0$res"}; } @@ -5511,12 +4395,7 @@ sub set_first_access { } $cachedkey=''; my $firstaccess=&get_first_access($type,$symb,$map); - if ($firstaccess) { - &logthis("First access time already set ($firstaccess) when attempting ". - "to set new value (type: $type, extent: $res) for $uname:$udom ". - "in $courseid"); - return 'already_set'; - } else { + if (!$firstaccess) { my $start = time; my $putres = &put('firstaccesstimes',{"$courseid\0$res"=>$start}, $udom,$uname); @@ -5529,106 +4408,12 @@ sub set_first_access { 'course.'.$courseid.'.timerinterval.'.$res => $interval, } ); - if (($cachedtime) && (abs($start-$cachedtime) < 5)) { - $cachedtimes{"$courseid\0$res"} = $start; - } - } elsif ($putres ne 'refused') { - &logthis("Result: $putres when attempting to set first access time ". - "(type: $type, extent: $res) for $uname:$udom in $courseid"); } return $putres; } return 'already_set'; } } - -sub checkout { - my ($symb,$tuname,$tudom,$tcrsid)=@_; - my $now=time; - my $lonhost=$perlvar{'lonHostID'}; - my $ip = &get_requestor_ip(); - my $infostr=&escape( - 'CHECKOUTTOKEN&'. - $tuname.'&'. - $tudom.'&'. - $tcrsid.'&'. - $symb.'&'. - $now.'&'.$ip); - my $token=&reply('tmpput:'.$infostr,$lonhost); - if ($token=~/^error\:/) { - &logthis("WARNING: ". - "Checkout tmpput failed ".$tudom.' - '.$tuname.' - '.$symb. - ""); - return ''; - } - - $token=~s/^(\d+)\_.*\_(\d+)$/$1\*$2\*$lonhost/; - $token=~tr/a-z/A-Z/; - - my %infohash=('resource.0.outtoken' => $token, - 'resource.0.checkouttime' => $now, - 'resource.0.outremote' => $ip); - - unless (&cstore(\%infohash,$symb,$tcrsid,$tudom,$tuname) eq 'ok') { - return ''; - } else { - &logthis("WARNING: ". - "Checkout cstore failed ".$tudom.' - '.$tuname.' - '.$symb. - ""); - } - - if (&log($tudom,$tuname,&homeserver($tuname,$tudom), - &escape('Checkout '.$infostr.' - '. - $token)) ne 'ok') { - return ''; - } else { - &logthis("WARNING: ". - "Checkout log failed ".$tudom.' - '.$tuname.' - '.$symb. - ""); - } - return $token; -} - -# ------------------------------------------------------------ Check in an item - -sub checkin { - my $token=shift; - my $now=time; - my ($ta,$tb,$lonhost)=split(/\*/,$token); - $lonhost=~tr/A-Z/a-z/; - my $dtoken=$ta.'_'.&hostname($lonhost).'_'.$tb; - $dtoken=~s/\W/\_/g; - my $ip = &get_requestor_ip(); - my ($dummy,$tuname,$tudom,$tcrsid,$symb,$chtim,$rmaddr)= - split(/\&/,&unescape(&reply('tmpget:'.$dtoken,$lonhost))); - - unless (($tuname) && ($tudom)) { - &logthis('Check in '.$token.' ('.$dtoken.') failed'); - return ''; - } - - unless (&allowed('mgr',$tcrsid)) { - &logthis('Check in '.$token.' ('.$dtoken.') unauthorized: '. - $env{'user.name'}.' - '.$env{'user.domain'}); - return ''; - } - - my %infohash=('resource.0.intoken' => $token, - 'resource.0.checkintime' => $now, - 'resource.0.inremote' => $ip); - - unless (&cstore(\%infohash,$symb,$tcrsid,$tudom,$tuname) eq 'ok') { - return ''; - } - - if (&log($tudom,$tuname,&homeserver($tuname,$tudom), - &escape('Checkin - '.$token)) ne 'ok') { - return ''; - } - - return ($symb,$tuname,$tudom,$tcrsid); -} - # --------------------------------------------- Set Expire Date for Spreadsheet sub expirespread { @@ -5883,7 +4668,7 @@ sub tmpreset { if (!$domain) { $domain=$env{'user.domain'}; } if (!$stuname) { $stuname=$env{'user.name'}; } if ($domain eq 'public' && $stuname eq 'public') { - $stuname=&get_requestor_ip(); + $stuname=$ENV{'REMOTE_ADDR'}; } my $path=LONCAPA::tempdir(); my %hash; @@ -5920,7 +4705,7 @@ sub tmpstore { if (!$domain) { $domain=$env{'user.domain'}; } if (!$stuname) { $stuname=$env{'user.name'}; } if ($domain eq 'public' && $stuname eq 'public') { - $stuname=&get_requestor_ip(); + $stuname=$ENV{'REMOTE_ADDR'}; } my $now=time; my %hash; @@ -5964,7 +4749,7 @@ sub tmprestore { if (!$domain) { $domain=$env{'user.domain'}; } if (!$stuname) { $stuname=$env{'user.name'}; } if ($domain eq 'public' && $stuname eq 'public') { - $stuname=&get_requestor_ip(); + $stuname=$ENV{'REMOTE_ADDR'}; } my %returnhash; $namespace=~s/\//\_/g; @@ -5999,7 +4784,7 @@ sub tmprestore { # ----------------------------------------------------------------------- Store sub store { - my ($storehash,$symb,$namespace,$domain,$stuname,$laststore) = @_; + my ($storehash,$symb,$namespace,$domain,$stuname) = @_; my $home=''; if ($stuname) { $home=&homeserver($stuname,$domain); } @@ -6020,7 +4805,7 @@ sub store { } if (!$home) { $home=$env{'user.home'}; } - $$storehash{'ip'}=&get_requestor_ip(); + $$storehash{'ip'}=$ENV{'REMOTE_ADDR'}; $$storehash{'host'}=$perlvar{'lonHostID'}; my $namevalue=''; @@ -6029,13 +4814,13 @@ sub store { } $namevalue=~s/\&$//; &courselog($symb.':'.$stuname.':'.$domain.':STORE:'.$namevalue); - return reply("store:$domain:$stuname:$namespace:$symb:$namevalue:$laststore","$home"); + return reply("store:$domain:$stuname:$namespace:$symb:$namevalue","$home"); } # -------------------------------------------------------------- Critical Store sub cstore { - my ($storehash,$symb,$namespace,$domain,$stuname,$laststore) = @_; + my ($storehash,$symb,$namespace,$domain,$stuname) = @_; my $home=''; if ($stuname) { $home=&homeserver($stuname,$domain); } @@ -6056,7 +4841,7 @@ sub cstore { } if (!$home) { $home=$env{'user.home'}; } - $$storehash{'ip'}=&get_requestor_ip(); + $$storehash{'ip'}=$ENV{'REMOTE_ADDR'}; $$storehash{'host'}=$perlvar{'lonHostID'}; my $namevalue=''; @@ -6066,7 +4851,7 @@ sub cstore { $namevalue=~s/\&$//; &courselog($symb.':'.$stuname.':'.$domain.':CSTORE:'.$namevalue); return critical - ("store:$domain:$stuname:$namespace:$symb:$namevalue:$laststore","$home"); + ("store:$domain:$stuname:$namespace:$symb:$namevalue","$home"); } # --------------------------------------------------------------------- Restore @@ -6222,7 +5007,7 @@ sub privileged { my $now = time; my $roles; if (ref($possroles) eq 'ARRAY') { - $roles = $possroles; + $roles = $possroles; } else { $roles = ['dc','su']; } @@ -6246,10 +5031,10 @@ sub privileged { my %rolesdump = &dump("roles", $domain, $username) or return 0; my $now = time; - for my $role (@rolesdump{grep { ! /^rolesdef_/ } keys(%rolesdump)}) { + for my $role (@rolesdump{grep { ! /^rolesdef_/ } keys %rolesdump}) { my ($trole, $tend, $tstart) = split(/_/, $role); if (grep(/^\Q$trole\E$/,@{$roles})) { - return 1 unless ($tend && $tend < $now) + return 1 unless ($tend && $tend < $now) or ($tstart && $tstart > $now); } } @@ -6287,7 +5072,7 @@ sub privileged_by_domain { my ($trole,$uname,$udom,$rest) = split(/:/,$item,4); my ($end,$start) = split(/:/,$dompersonnel{$server}{$item}); next if ($end && $end < $now); - $privileged{$dom}{$trole}{$uname.':'.$udom} = + $privileged{$dom}{$trole}{$uname.':'.$udom} = $dompersonnel{$server}{$item}; } } @@ -6335,7 +5120,7 @@ sub rolesinit { my %allroles=(); my %allgroups=(); - for my $area (grep { ! /^rolesdef_/ } keys(%rolesdump)) { + for my $area (grep { ! /^rolesdef_/ } keys %rolesdump) { my $role = $rolesdump{$area}; $area =~ s/\_\w\w$//; @@ -6408,10 +5193,9 @@ sub rolesinit { } } - @userroles{'user.author','user.adv','user.rar'} = &set_userprivs(\%userroles, - \%allroles, \%allgroups); + @userroles{'user.author', 'user.adv'} = &set_userprivs(\%userroles, + \%allroles, \%allgroups); $env{'user.adv'} = $userroles{'user.adv'}; - $env{'user.rar'} = $userroles{'user.rar'}; return (\%userroles,\%firstaccenv,\%timerintenv); } @@ -6428,7 +5212,7 @@ sub set_arearole { sub custom_roleprivs { my ($allroles,$trole,$tdomain,$trest,$spec,$area) = @_; my ($rdummy,$rdomain,$rauthor,$rrole)=split(/\//,$trole); - my $homsvr = &homeserver($rauthor,$rdomain); + my $homsvr=homeserver($rauthor,$rdomain); if (&hostname($homsvr) ne '') { my ($rdummy,$roledef)= &get('roles',["rolesdef_$rrole"],$rdomain,$rauthor); @@ -6447,10 +5231,6 @@ sub custom_roleprivs { $$allroles{$spec.'./'.$tdomain.'/'}.=':'.$dompriv; } if (($trest ne '') && (defined($coursepriv))) { - if ($trole =~ m{^cr/$tdomain/$tdomain\Q-domainconfig\E/([^/]+)$}) { - my $rolename = $1; - $coursepriv = &course_adhocrole_privs($rolename,$tdomain,$trest,$coursepriv); - } $$allroles{'cm.'.$area}.=':'.$coursepriv; $$allroles{$spec.'.'.$area}.=':'.$coursepriv; } @@ -6459,48 +5239,6 @@ sub custom_roleprivs { } } -sub course_adhocrole_privs { - my ($rolename,$cdom,$cnum,$coursepriv) = @_; - my %overrides = &get('environment',["internal.adhocpriv.$rolename"],$cdom,$cnum); - if ($overrides{"internal.adhocpriv.$rolename"}) { - my (%currprivs,%storeprivs); - foreach my $item (split(/:/,$coursepriv)) { - my ($priv,$restrict) = split(/\&/,$item); - $currprivs{$priv} = $restrict; - } - my (%possadd,%possremove,%full); - foreach my $item (split(/\:/,$Apache::lonnet::pr{'cr:c'})) { - my ($priv,$restrict)=split(/\&/,$item); - $full{$priv} = $restrict; - } - foreach my $item (split(/,/,$overrides{"internal.adhocpriv.$rolename"})) { - next if ($item eq ''); - my ($rule,$rest) = split(/=/,$item); - next unless (($rule eq 'off') || ($rule eq 'on')); - foreach my $priv (split(/:/,$rest)) { - if ($priv ne '') { - if ($rule eq 'off') { - $possremove{$priv} = 1; - } else { - $possadd{$priv} = 1; - } - } - } - } - foreach my $priv (sort(keys(%full))) { - if (exists($currprivs{$priv})) { - unless (exists($possremove{$priv})) { - $storeprivs{$priv} = $currprivs{$priv}; - } - } elsif (exists($possadd{$priv})) { - $storeprivs{$priv} = $full{$priv}; - } - } - $coursepriv = ':'.join(':',map { $_.'&'.$storeprivs{$_}; } sort(keys(%storeprivs))); - } - return $coursepriv; -} - sub group_roleprivs { my ($allgroups,$area,$group_privs,$tend,$tstart) = @_; my $access = 1; @@ -6535,7 +5273,6 @@ sub set_userprivs { my ($userroles,$allroles,$allgroups,$groups_roles) = @_; my $author=0; my $adv=0; - my $rar=0; my %grouproles = (); if (keys(%{$allgroups}) > 0) { my @groupkeys; @@ -6583,7 +5320,6 @@ sub set_userprivs { $thesepriv{$privilege}.=$restrictions; } if ($thesepriv{'adv'} eq 'F') { $adv=1; } - if ($thesepriv{'rar'} eq 'F') { $rar=1; } } } my $thesestr=''; @@ -6592,16 +5328,16 @@ sub set_userprivs { } $userroles->{'user.priv.'.$role} = $thesestr; } - return ($author,$adv,$rar); + return ($author,$adv); } sub role_status { my ($rolekey,$update,$refresh,$now,$role,$where,$trolecode,$tstatus,$tstart,$tend) = @_; + my @pwhere = (); if (exists($env{$rolekey}) && $env{$rolekey} ne '') { - my ($one,$two) = split(m{\./},$rolekey,2); - (undef,undef,$$role) = split(/\./,$one,3); + (undef,undef,$$role,@pwhere)=split(/\./,$rolekey); unless (!defined($$role) || $$role eq '') { - $$where = '/'.$two; + $$where=join('.',@pwhere); $$trolecode=$$role.'.'.$$where; ($$tstart,$$tend)=split(/\./,$env{$rolekey}); $$tstatus='is'; @@ -6637,10 +5373,9 @@ sub role_status { push(@rolecodes,$$role); &standard_roleprivs(\%allroles,$$role,$tdomain,$spec,$trest,$$where); } - my ($author,$adv,$rar)= &set_userprivs(\%userroles,\%allroles,\%allgroups, - \%groups_roles); + my ($author,$adv)= &set_userprivs(\%userroles,\%allroles,\%allgroups,\%groups_roles); &appenv(\%userroles,\@rolecodes); - &log($env{'user.domain'},$env{'user.name'},$env{'user.home'},"Role ".$spec); + &log($env{'user.domain'},$env{'user.name'},$env{'user.home'},"Role ".$role); } } $$tstatus = 'is'; @@ -6716,56 +5451,39 @@ sub delete_env_groupprivs { } sub check_adhoc_privs { - my ($cdom,$cnum,$update,$refresh,$now,$checkrole,$caller,$sec) = @_; + my ($cdom,$cnum,$update,$refresh,$now,$checkrole,$caller) = @_; my $cckey = 'user.role.'.$checkrole.'./'.$cdom.'/'.$cnum; - if ($sec) { - $cckey .= '/'.$sec; - } my $setprivs; if ($env{$cckey}) { my ($role,$where,$trolecode,$tstart,$tend,$tremark,$tstatus,$tpstart,$tpend); &role_status($cckey,$update,$refresh,$now,\$role,\$where,\$trolecode,\$tstatus,\$tstart,\$tend); unless (($tstatus eq 'is') || ($tstatus eq 'will_not')) { - &set_adhoc_privileges($cdom,$cnum,$checkrole,$caller,$sec); + &set_adhoc_privileges($cdom,$cnum,$checkrole,$caller); $setprivs = 1; } } else { - &set_adhoc_privileges($cdom,$cnum,$checkrole,$caller,$sec); + &set_adhoc_privileges($cdom,$cnum,$checkrole,$caller); $setprivs = 1; } return $setprivs; } sub set_adhoc_privileges { -# role can be cc, ca, or cr//-domainconfig/role - my ($dcdom,$pickedcourse,$role,$caller,$sec) = @_; +# role can be cc or ca + my ($dcdom,$pickedcourse,$role,$caller) = @_; my $area = '/'.$dcdom.'/'.$pickedcourse; - if ($sec ne '') { - $area .= '/'.$sec; - } my $spec = $role.'.'.$area; my %userroles = &set_arearole($role,$area,'','',$env{'user.domain'}, $env{'user.name'},1); - my %rolehash = (); - if ($role =~ m{^\Qcr/$dcdom/$dcdom\E\-domainconfig/(\w+)$}) { - my $rolename = $1; - &custom_roleprivs(\%rolehash,$role,$dcdom,$pickedcourse,$spec,$area); - my %domdef = &get_domain_defaults($dcdom); - if (ref($domdef{'adhocroles'}) eq 'HASH') { - if (ref($domdef{'adhocroles'}{$rolename}) eq 'HASH') { - &appenv({'request.role.desc' => $domdef{'adhocroles'}{$rolename}{'desc'},}); - } - } - } else { - &standard_roleprivs(\%rolehash,$role,$dcdom,$spec,$pickedcourse,$area); - } - my ($author,$adv,$rar)= &set_userprivs(\%userroles,\%rolehash); + my %ccrole = (); + &standard_roleprivs(\%ccrole,$role,$dcdom,$spec,$pickedcourse,$area); + my ($author,$adv)= &set_userprivs(\%userroles,\%ccrole); &appenv(\%userroles,[$role,'cm']); - &log($env{'user.domain'},$env{'user.name'},$env{'user.home'},"Role ".$spec); + &log($env{'user.domain'},$env{'user.name'},$env{'user.home'},"Role ".$role); unless ($caller eq 'constructaccess' && $env{'request.course.id'}) { &appenv( {'request.role' => $spec, 'request.role.domain' => $dcdom, - 'request.course.sec' => $sec, + 'request.course.sec' => '' } ); my $tadv=0; @@ -6825,14 +5543,15 @@ sub unserialize { return {} if $rep =~ /^error/; my %returnhash=(); - foreach my $item (split(/\&/,$rep)) { - my ($key, $value) = split(/=/, $item, 2); - $key = unescape($key) unless $escapedkeys; - next if $key =~ /^error: 2 /; - $returnhash{$key} = &thaw_unescape($value); - } + foreach my $item (split /\&/, $rep) { + my ($key, $value) = split(/=/, $item, 2); + $key = unescape($key) unless $escapedkeys; + next if $key =~ /^error: 2 /; + $returnhash{$key} = Apache::lonnet::thaw_unescape($value); + } + #return %returnhash; return \%returnhash; -} +} # see Lond::dump_with_regexp # if $escapedkeys hash keys won't get unescaped. @@ -6842,16 +5561,17 @@ sub dump { if (!$uname) { $uname=$env{'user.name'}; } my $uhome=&homeserver($uname,$udomain); - if ($regexp) { - $regexp=&escape($regexp); - } else { - $regexp='.'; - } - if (grep { $_ eq $uhome } ¤t_machine_ids()) { + my $reply; + if (grep { $_ eq $uhome } current_machine_ids()) { # user is hosted on this machine - my $reply = LONCAPA::Lond::dump_with_regexp(join(':', ($udomain, + $reply = LONCAPA::Lond::dump_with_regexp(join(":", ($udomain, $uname, $namespace, $regexp, $range)), $perlvar{'lonVersion'}); - return %{&unserialize($reply, $escapedkeys)}; + return %{unserialize($reply, $escapedkeys)}; + } + if ($regexp) { + $regexp=&escape($regexp); + } else { + $regexp='.'; } my $rep=&reply("dump:$udomain:$uname:$namespace:$regexp:$range",$uhome); my @pairs=split(/\&/,$rep); @@ -6859,7 +5579,8 @@ sub dump { if (!($rep =~ /^error/ )) { foreach my $item (@pairs) { my ($key,$value)=split(/=/,$item,2); - $key = &unescape($key) unless ($escapedkeys); + $key = unescape($key) unless $escapedkeys; + #$key = &unescape($key); next if ($key =~ /^error: 2 /); $returnhash{$key}=&thaw_unescape($value); } @@ -6903,7 +5624,7 @@ sub currentdump { my $rep; if (grep { $_ eq $uhome } current_machine_ids()) { - $rep = LONCAPA::Lond::dump_profile_database(join(":", ($sdom, $sname, + $rep = LONCAPA::Lond::dump_profile_database(join(":", ($sdom, $sname, $courseid))); } else { $rep = reply('currentdump:'.$sdom.':'.$sname.':'.$courseid,$uhome); @@ -7029,7 +5750,7 @@ sub newput { # --------------------------------------------------------- putstore interface sub putstore { - my ($namespace,$symb,$version,$storehash,$udomain,$uname,$tolog)=@_; + my ($namespace,$symb,$version,$storehash,$udomain,$uname)=@_; if (!$udomain) { $udomain=$env{'user.domain'}; } if (!$uname) { $uname=$env{'user.name'}; } my $uhome=&homeserver($uname,$udomain); @@ -7043,18 +5764,6 @@ sub putstore { my $reply = &reply("putstore:$udomain:$uname:$namespace:$esc_symb:$esc_v:$items", $uhome); - if (($tolog) && ($reply eq 'ok')) { - my $namevalue=''; - foreach my $key (keys(%{$storehash})) { - $namevalue.=&escape($key).'='.&freeze_escape($storehash->{$key}).'&'; - } - my $ip = &get_requestor_ip(); - $namevalue .= 'ip='.&escape($ip). - '&host='.&escape($perlvar{'lonHostID'}). - '&version='.$esc_v. - '&by='.&escape($env{'user.name'}.':'.$env{'user.domain'}); - &Apache::lonnet::courselog($symb.':'.$uname.':'.$udomain.':PUTSTORE:'.$namevalue); - } if ($reply eq 'unknown_cmd') { # gfall back to way things use to be done return &old_putstore($namespace,$symb,$version,$storehash,$udomain, @@ -7148,11 +5857,9 @@ sub tmpget { if (!defined($server)) { $server = $perlvar{'lonHostID'}; } my $rep=&reply("tmpget:$token",$server); my %returnhash; - if ($rep =~ /^(con_lost|error|no_such_host)/i) { - return %returnhash; - } foreach my $item (split(/\&/,$rep)) { my ($key,$value)=split(/=/,$item); + next if ($key =~ /^error: 2 /); $returnhash{&unescape($key)}=&thaw_unescape($value); } return %returnhash; @@ -7165,13 +5872,13 @@ sub tmpdel { return &reply("tmpdel:$token",$server); } -# ------------------------------------------------------------ get_timebased_id +# ------------------------------------------------------------ get_timebased_id sub get_timebased_id { my ($prefix,$keyid,$namespace,$cdom,$cnum,$idtype,$who,$locktries, $maxtries) = @_; my ($newid,$error,$dellock); - unless (($prefix =~ /^\w+$/) && ($keyid =~ /^\w+$/) && ($namespace ne '')) { + unless (($prefix =~ /^\w+$/) && ($keyid =~ /^\w+$/) && ($namespace ne '')) { return ('','ok','invalid call to get suffix'); } @@ -7185,7 +5892,7 @@ sub get_timebased_id { if (!$maxtries) { $maxtries = 10; } - + if (($cdom eq '') || ($cnum eq '')) { if ($env{'request.course.id'}) { $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; @@ -7215,15 +5922,10 @@ sub get_timebased_id { my %inuse = &Apache::lonnet::dump('nohist_'.$namespace,$cdom,$cnum,$prefix); my $id = time; $newid = $id; - if ($idtype eq 'addcode') { - $newid .= &sixnum_code(); - } my $idtries = 0; while (exists($inuse{$prefix."\0".$newid}) && $idtries < $maxtries) { if ($idtype eq 'concat') { $newid = $id.$idtries; - } elsif ($idtype eq 'addcode') { - $newid = $newid.&sixnum_code(); } else { $newid ++; } @@ -7240,7 +5942,6 @@ sub get_timebased_id { $error = 'error saving new item: '.$putresult; } } else { - undef($newid); $error = ('error: no unique suffix available for the new item '); } # remove lock @@ -7249,27 +5950,16 @@ sub get_timebased_id { } else { $error = "error: could not obtain lockfile\n"; $dellock = 'ok'; - if (($prefix eq 'paste') && ($namespace eq 'courseeditor') && ($keyid eq 'num')) { - $dellock = 'nolock'; - } } return ($newid,$dellock,$error); } -sub sixnum_code { - my $code; - for (0..6) { - $code .= int( rand(9) ); - } - return $code; -} - # -------------------------------------------------- portfolio access checking sub portfolio_access { - my ($requrl,$clientip) = @_; + my ($requrl) = @_; my (undef,$udom,$unum,$file_name,$group) = &parse_portfolio_url($requrl); - my $result = &get_portfolio_access($udom,$unum,$file_name,$group,$clientip); + my $result = &get_portfolio_access($udom,$unum,$file_name,$group); if ($result) { my %setters; if ($env{'user.name'} eq 'public' && $env{'user.domain'} eq 'public') { @@ -7295,7 +5985,7 @@ sub portfolio_access { } sub get_portfolio_access { - my ($udom,$unum,$file_name,$group,$clientip,$access_hash) = @_; + my ($udom,$unum,$file_name,$group,$access_hash) = @_; if (!ref($access_hash)) { my $current_perms = &get_portfile_permissions($udom,$unum); @@ -7304,7 +5994,7 @@ sub get_portfolio_access { $access_hash = $access_controls{$file_name}; } - my ($public,$guest,@domains,@users,@courses,@groups,@ips); + my ($public,$guest,@domains,@users,@courses,@groups); my $now = time; if (ref($access_hash) eq 'HASH') { foreach my $key (keys(%{$access_hash})) { @@ -7328,25 +6018,10 @@ sub get_portfolio_access { push(@courses,$key); } elsif ($scope eq 'group') { push(@groups,$key); - } elsif ($scope eq 'ip') { - push(@ips,$key); } } if ($public) { return 'ok'; - } elsif (@ips > 0) { - my $allowed; - foreach my $ipkey (@ips) { - if (ref($access_hash->{$ipkey}{'ip'}) eq 'ARRAY') { - if (&Apache::loncommon::check_ip_acc(join(',',@{$access_hash->{$ipkey}{'ip'}}),$clientip)) { - $allowed = 1; - last; - } - } - } - if ($allowed) { - return 'ok'; - } } if ($env{'user.name'} eq 'public' && $env{'user.domain'} eq 'public') { if ($guest) { @@ -7533,7 +6208,6 @@ sub usertools_access { official => 1, unofficial => 1, community => 1, - textbook => 1, ); } elsif ($context eq 'requestauthor') { %tools = ( @@ -7568,7 +6242,7 @@ sub usertools_access { my ($toolstatus,$inststatus,$envkey); if ($context eq 'requestauthor') { - $envkey = $context; + $envkey = $context; } else { $envkey = $context.'.'.$tool; } @@ -7830,7 +6504,7 @@ sub customaccess { # ------------------------------------------------- Check for a user privilege sub allowed { - my ($priv,$uri,$symb,$role,$clientip,$noblockcheck,$ignorecache)=@_; + my ($priv,$uri,$symb,$role)=@_; my $ver_orguri=$uri; $uri=&deversion($uri); my $orguri=$uri; @@ -7847,7 +6521,7 @@ sub allowed { if (defined($env{'allowed.'.$priv})) { return $env{'allowed.'.$priv}; } # Free bre access to adm and meta resources - if (((($uri=~/^adm\//) && ($uri !~ m{/(?:smppg|bulletinboard|viewclasslist|aboutme)$})) + if (((($uri=~/^adm\//) && ($uri !~ m{/(?:smppg|bulletinboard)$})) || (($uri=~/\.meta$/) && ($uri!~m|^uploaded/|) )) && ($priv eq 'bre')) { return 'F'; @@ -8012,34 +6686,8 @@ sub allowed { if ($env{'user.priv.'.$env{'request.role'}.'.'.$courseuri} =~/\Q$priv\E\&([^\:]*)/) { - if ($priv eq 'mip') { - my $rem = $1; - if (($uri ne '') && ($env{'request.course.id'} eq $uri) && - ($env{'course.'.$env{'request.course.id'}.'.internal.courseowner'} eq $env{'user.name'}.':'.$env{'user.domain'})) { - my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - if ($cdom ne '') { - my %passwdconf = &get_passwdconf($cdom); - if (ref($passwdconf{'crsownerchg'}) eq 'HASH') { - if (ref($passwdconf{'crsownerchg'}{'by'}) eq 'ARRAY') { - if (@{$passwdconf{'crsownerchg'}{'by'}}) { - my @inststatuses = split(':',$env{'environment.inststatus'}); - unless (@inststatuses) { - @inststatuses = ('default'); - } - foreach my $status (@inststatuses) { - if (grep(/^\Q$status\E$/,@{$passwdconf{'crsownerchg'}{'by'}})) { - $thisallowed.=$rem; - } - } - } - } - } - } - } - } else { - unless (($priv eq 'bro') && (!$ownaccess)) { - $thisallowed.=$1; - } + unless (($priv eq 'bro') && (!$ownaccess)) { + $thisallowed.=$1; } } @@ -8051,16 +6699,11 @@ sub allowed { if ($match) { if ($env{'user.priv.'.$env{'request.role'}.'./'} =~/\Q$priv\E\&([^\:]*)/) { - my $value = $1; - if ($noblockcheck) { - $thisallowed.=$value; + my @blockers = &has_comm_blocking($priv,$symb,$uri); + if (@blockers > 0) { + $thisallowed = 'B'; } else { - my @blockers = &has_comm_blocking($priv,$symb,$uri,$ignorecache); - if (@blockers > 0) { - $thisallowed = 'B'; - } else { - $thisallowed.=$value; - } + $thisallowed.=$1; } } } else { @@ -8072,15 +6715,11 @@ sub allowed { $refuri=&declutter($refuri); my ($match) = &is_on_map($refuri); if ($match) { - if ($noblockcheck) { - $thisallowed='F'; + my @blockers = &has_comm_blocking($priv,$symb,$refuri); + if (@blockers > 0) { + $thisallowed = 'B'; } else { - my @blockers = &has_comm_blocking($priv,'',$refuri,'',1); - if (@blockers > 0) { - $thisallowed = 'B'; - } else { - $thisallowed='F'; - } + $thisallowed='F'; } } } @@ -8092,7 +6731,7 @@ sub allowed { && $thisallowed ne 'F' && $thisallowed ne '2' && &is_portfolio_url($uri)) { - $thisallowed = &portfolio_access($uri,$clientip); + $thisallowed = &portfolio_access($uri); } # Full access at system, domain or course-wide level? Exit. @@ -8122,16 +6761,6 @@ sub allowed { if ($env{'request.course.id'}) { -# If this is modifying password (internal auth) domains must match for user and user's role. - - if ($priv eq 'mip') { - if ($env{'user.domain'} eq $env{'request.role.domain'}) { - return $thisallowed; - } else { - return ''; - } - } - $courseprivid=$env{'request.course.id'}; if ($env{'request.course.sec'}) { $courseprivid.='/'.$env{'request.course.sec'}; @@ -8145,15 +6774,11 @@ sub allowed { =~/\Q$priv\E\&([^\:]*)/) { my $value = $1; if ($priv eq 'bre') { - if ($noblockcheck) { - $thisallowed.=$value; + my @blockers = &has_comm_blocking($priv,$symb,$uri); + if (@blockers > 0) { + $thisallowed = 'B'; } else { - my @blockers = &has_comm_blocking($priv,$symb,$uri,$ignorecache); - if (@blockers > 0) { - $thisallowed = 'B'; - } else { - $thisallowed.=$value; - } + $thisallowed.=$value; } } else { $thisallowed.=$value; @@ -8161,7 +6786,7 @@ sub allowed { $checkreferer=0; } } - + if ($checkreferer) { my $refuri=$env{'httpref.'.$orguri}; unless ($refuri) { @@ -8187,15 +6812,11 @@ sub allowed { =~/\Q$priv\E\&([^\:]*)/) { my $value = $1; if ($priv eq 'bre') { - if ($noblockcheck) { - $thisallowed.=$value; + my @blockers = &has_comm_blocking($priv,$symb,$refuri); + if (@blockers > 0) { + $thisallowed = 'B'; } else { - my @blockers = &has_comm_blocking($priv,'',$refuri,'',1); - if (@blockers > 0) { - $thisallowed = 'B'; - } else { - $thisallowed.=$value; - } + $thisallowed.=$value; } } else { $thisallowed.=$value; @@ -8276,7 +6897,7 @@ sub allowed { } } } - + # # Rest of the restrictions depend on selected course # @@ -8371,7 +6992,7 @@ sub constructaccess { my ($ownername,$ownerdomain,$ownerhome); ($ownerdomain,$ownername) = - ($url=~ m{^(?:\Q$perlvar{'lonDocRoot'}\E|)/priv/($match_domain)/($match_username)(?:/|$)}); + ($url=~ m{^(?:\Q$perlvar{'lonDocRoot'}\E|)/priv/($match_domain)/($match_username)/}); # The URL does not really point to any authorspace, forget it unless (($ownername) && ($ownerdomain)) { return ''; } @@ -8426,37 +7047,6 @@ sub constructaccess { return ''; } -# ----------------------------------------------------------- Content Blocking - -{ -# Caches for faster Course Contents display where content blocking -# is in operation (i.e., interval param set) for timed quiz. -# -# User for whom data are being temporarily cached. -my $cacheduser=''; -# Course for which data are being temporarily cached. -my $cachedcid=''; -# Cached blockers for this user (a hash of blocking items). -my %cachedblockers=(); -# When the data were last cached. -my $cachedlast=''; - -sub load_all_blockers { - my ($uname,$udom)=@_; - if (($uname ne '') && ($udom ne '')) { - if (($cacheduser eq $uname.':'.$udom) && - ($cachedcid eq $env{'request.course.id'}) && - (abs($cachedlast-time)<5)) { - return; - } - } - $cachedlast=time; - $cacheduser=$uname.':'.$udom; - $cachedcid=$env{'request.course.id'}; - %cachedblockers = &get_commblock_resources(); - return; -} - sub get_comm_blocks { my ($cdom,$cnum) = @_; if ($cdom eq '' || $cnum eq '') { @@ -8477,25 +7067,27 @@ sub get_comm_blocks { return %commblocks; } -sub get_commblock_resources { - my ($blocks) = @_; - my %blockers = (); - return %blockers unless ($env{'request.course.id'}); - my $courseurl = &courseid_to_courseurl($env{'request.course.id'}); - if ($env{'request.course.sec'}) { - $courseurl .= '/'.$env{'request.course.sec'}; - } - return %blockers if ($env{'user.priv.'.$env{'request.role'}.'.'.$courseurl} =~/evb\&([^\:]*)/); +sub has_comm_blocking { + my ($priv,$symb,$uri,$blocks) = @_; + return unless ($env{'request.course.id'}); + return unless ($priv eq 'bre'); + return if ($env{'user.priv.'.$env{'request.role'}} =~/evb\&([^\:]*)/); my %commblocks; if (ref($blocks) eq 'HASH') { %commblocks = %{$blocks}; } else { %commblocks = &get_comm_blocks(); } - return %blockers unless (keys(%commblocks) > 0); - my $navmap = Apache::lonnavmaps::navmap->new(); - return %blockers unless (ref($navmap)); + return unless (keys(%commblocks) > 0); + if (!$symb) { $symb=&symbread($uri,1); } + my ($map,$resid,undef)=&decode_symb($symb); + my %tocheck = ( + maps => $map, + resources => $symb, + ); + my @blockers; my $now = time; + my $navmap = Apache::lonnavmaps::navmap->new(); foreach my $block (keys(%commblocks)) { if ($block =~ /^(\d+)____(\d+)$/) { my ($start,$end) = ($1,$2); @@ -8503,13 +7095,17 @@ sub get_commblock_resources { if (ref($commblocks{$block}{'blocks'}) eq 'HASH') { if (ref($commblocks{$block}{'blocks'}{'docs'}) eq 'HASH') { if (ref($commblocks{$block}{'blocks'}{'docs'}{'maps'}) eq 'HASH') { - if (keys(%{$commblocks{$block}{'blocks'}{'docs'}{'maps'}})) { - $blockers{$block}{maps} = $commblocks{$block}{'blocks'}{'docs'}{'maps'}; + if ($commblocks{$block}{'blocks'}{'docs'}{'maps'}{$map}) { + unless (grep(/^\Q$block\E$/,@blockers)) { + push(@blockers,$block); + } } } if (ref($commblocks{$block}{'blocks'}{'docs'}{'resources'}) eq 'HASH') { - if (keys(%{$commblocks{$block}{'blocks'}{'docs'}{'resources'}})) { - $blockers{$block}{'resources'} = $commblocks{$block}{'blocks'}{'docs'}{'resources'}; + if ($commblocks{$block}{'blocks'}{'docs'}{'resources'}{$symb}) { + unless (grep(/^\Q$block\E$/,@blockers)) { + push(@blockers,$block); + } } } } @@ -8520,77 +7116,59 @@ sub get_commblock_resources { my @to_test; if (ref($commblocks{$block}{'blocks'}) eq 'HASH') { if (ref($commblocks{$block}{'blocks'}{'docs'}) eq 'HASH') { - my @interval; - my $type = 'map'; - if ($item eq 'course') { - $type = 'course'; - @interval=&EXT("resource.0.interval"); - } else { - if ($item =~ /___\d+___/) { - $type = 'resource'; - @interval=&EXT("resource.0.interval",$item); - if (ref($navmap)) { - my $res = $navmap->getBySymb($item); - push(@to_test,$res); - } + my $check_interval; + if (&check_docs_block($commblocks{$block}{'blocks'}{'docs'},\%tocheck)) { + my @interval; + my $type = 'map'; + if ($item eq 'course') { + $type = 'course'; + @interval=&EXT("resource.0.interval"); } else { - my $mapsymb = &symbread($item,1); - if ($mapsymb) { - if (ref($navmap)) { - my $mapres = $navmap->getBySymb($mapsymb); - if (ref($mapres)) { - my $first = $mapres->map_start(); - my $finish = $mapres->map_finish(); - my $it = $navmap->getIterator($first,$finish,undef,0,0); - if (ref($it)) { - my $res; - while ($res = $it->next(undef,1)) { - next unless (ref($res)); - my $symb = $res->symb(); - next if (($symb eq $mapsymb) || ($symb eq '')); + if ($item =~ /___\d+___/) { + $type = 'resource'; + @interval=&EXT("resource.0.interval",$item); + if (ref($navmap)) { + my $res = $navmap->getBySymb($item); + push(@to_test,$res); + } + } else { + my $mapsymb = &symbread($item,1); + if ($mapsymb) { + if (ref($navmap)) { + my $mapres = $navmap->getBySymb($mapsymb); + @to_test = $mapres->retrieveResources($mapres,undef,0,1); + foreach my $res (@to_test) { + my $symb = $res->symb(); + next if ($symb eq $mapsymb); + if ($symb ne '') { @interval=&EXT("resource.0.interval",$symb); - if ($interval[1] eq 'map') { - if ($res->answerable()) { - push(@to_test,$res); - last; - } - } + last; } } } } } } - } - if ($interval[0] =~ /^(\d+)/) { - my $timelimit = $1; - my $first_access; - if ($type eq 'resource') { - $first_access=&get_first_access($interval[1],$item); - } elsif ($type eq 'map') { - $first_access=&get_first_access($interval[1],undef,$item); - } else { - $first_access=&get_first_access($interval[1]); - } - if ($first_access) { - my $timesup = $first_access+$timelimit; - if ($timesup > $now) { - my $activeblock; - foreach my $res (@to_test) { - if ($res->answerable()) { - $activeblock = 1; - last; - } - } - if ($activeblock) { - if (ref($commblocks{$block}{'blocks'}{'docs'}{'maps'}) eq 'HASH') { - if (keys(%{$commblocks{$block}{'blocks'}{'docs'}{'maps'}})) { - $blockers{$block}{'maps'} = $commblocks{$block}{'blocks'}{'docs'}{'maps'}; - } - } - if (ref($commblocks{$block}{'blocks'}{'docs'}{'resources'}) eq 'HASH') { - if (keys(%{$commblocks{$block}{'blocks'}{'docs'}{'resources'}})) { - $blockers{$block}{'resources'} = $commblocks{$block}{'blocks'}{'docs'}{'resources'}; + if ($interval[0] =~ /\d+/) { + my $first_access; + if ($type eq 'resource') { + $first_access=&get_first_access($interval[1],$item); + } elsif ($type eq 'map') { + $first_access=&get_first_access($interval[1],undef,$item); + } else { + $first_access=&get_first_access($interval[1]); + } + if ($first_access) { + my $timesup = $first_access+$interval[0]; + if ($timesup > $now) { + foreach my $res (@to_test) { + if ($res->is_problem()) { + if ($res->completable()) { + unless (grep(/^\Q$block\E$/,@blockers)) { + push(@blockers,$block); + } + last; + } } } } @@ -8601,80 +7179,33 @@ sub get_commblock_resources { } } } - return %blockers; + return @blockers; } -sub has_comm_blocking { - my ($priv,$symb,$uri,$ignoresymbdb,$noenccheck,$blocked,$blocks) = @_; - my @blockers; - return unless ($env{'request.course.id'}); - return unless ($priv eq 'bre'); - return if ($env{'request.state'} eq 'construct'); - my $courseurl = &courseid_to_courseurl($env{'request.course.id'}); - if ($env{'request.course.sec'}) { - $courseurl .= '/'.$env{'request.course.sec'}; - } - return if ($env{'user.priv.'.$env{'request.role'}.'.'.$courseurl} =~/evb\&([^\:]*)/); - my %blockinfo; - if (ref($blocks) eq 'HASH') { - %blockinfo = &get_commblock_resources($blocks); - } else { - &load_all_blockers($env{'user.name'},$env{'user.domain'}); - %blockinfo = %cachedblockers; - } - return unless (keys(%blockinfo) > 0); - my (%possibles,@symbs); - if (!$symb) { - $symb = &symbread($uri,1,1,1,\%possibles,$ignoresymbdb,$noenccheck); +sub check_docs_block { + my ($docsblock,$tocheck) =@_; + if ((ref($docsblock) ne 'HASH') || (ref($tocheck) ne 'HASH')) { + return; } - if ($symb) { - @symbs = ($symb); - } elsif (keys(%possibles)) { - @symbs = keys(%possibles); - } - my $noblock; - foreach my $symb (@symbs) { - last if ($noblock); - my ($map,$resid,$resurl)=&decode_symb($symb); - foreach my $block (keys(%blockinfo)) { - if ($block =~ /^firstaccess____(.+)$/) { - my $item = $1; - unless ($blocked) { - if (($item eq $map) || ($item eq $symb)) { - $noblock = 1; - last; - } - } - } - if (ref($blockinfo{$block}) eq 'HASH') { - if (ref($blockinfo{$block}{'resources'}) eq 'HASH') { - if ($blockinfo{$block}{'resources'}{$symb}) { - unless (grep(/^\Q$block\E$/,@blockers)) { - push(@blockers,$block); - } - } - } - if (ref($blockinfo{$block}{'maps'}) eq 'HASH') { - if ($blockinfo{$block}{'maps'}{$map}) { - unless (grep(/^\Q$block\E$/,@blockers)) { - push(@blockers,$block); - } - } - } + if (ref($docsblock->{'maps'}) eq 'HASH') { + if ($tocheck->{'maps'}) { + if ($docsblock->{'maps'}{$tocheck->{'maps'}}) { + return 1; } } } - unless ($noblock) { - return @blockers; + if (ref($docsblock->{'resources'}) eq 'HASH') { + if ($tocheck->{'resources'}) { + if ($docsblock->{'resources'}{$tocheck->{'resources'}}) { + return 1; + } + } } return; } -} - -# -------------------------------- Deversion and split uri into path an filename # -# Removes the version from a URI and +# Removes the versino from a URI and # splits it in to its filename and path to the filename. # Seems like File::Basename could have done this more clearly. # Parameters: @@ -8742,7 +7273,7 @@ sub get_symb_from_alias { sub definerole { if (allowed('mcr','/')) { - my ($rolename,$sysrole,$domrole,$courole,$uname,$udom)=@_; + my ($rolename,$sysrole,$domrole,$courole)=@_; foreach my $role (split(':',$sysrole)) { my ($crole,$cqual)=split(/\&/,$role); if ($pr{'cr:s'}!~/\Q$crole\E/) { return "refused:s:$crole"; } @@ -8770,19 +7301,11 @@ sub definerole { } } } - my $uhome; - if (($uname ne '') && ($udom ne '')) { - $uhome = &homeserver($uname,$udom); - return $uhome if ($uhome eq 'no_host'); - } else { - $uname = $env{'user.name'}; - $udom = $env{'user.domain'}; - $uhome = $env{'user.home'}; - } my $command="encrypt:rolesput:$env{'user.domain'}:$env{'user.name'}:". - "$udom:$uname:rolesdef_$rolename=". + "$env{'user.domain'}:$env{'user.name'}:". + "rolesdef_$rolename=". escape($sysrole.'_'.$domrole.'_'.$courole); - return reply($command,$uhome); + return reply($command,$env{'user.home'}); } else { return 'refused'; } @@ -8797,9 +7320,9 @@ sub metadata_query { my @server_list = (defined($server_array) ? @$server_array : keys(%libserv) ); for my $server (@server_list) { - my $domains = ''; + my $domains = ''; if (ref($domains_hash) eq 'HASH') { - $domains = $domains_hash->{$server}; + $domains = $domains_hash->{$server}; } unless ($custom or $customshow) { my $reply=&reply("querysend:".&escape($query).':::'.&escape($domains),$server); @@ -8864,12 +7387,10 @@ sub update_allusers_table { sub fetch_enrollment_query { my ($context,$affiliatesref,$replyref,$dom,$cnum) = @_; - my ($homeserver,$sleep,$loopmax); + my $homeserver; my $maxtries = 1; if ($context eq 'automated') { $homeserver = $perlvar{'lonHostID'}; - $sleep = 2; - $loopmax = 100; $maxtries = 10; # will wait for up to 2000s for retrieval of classlist data before timeout } else { $homeserver = &homeserver($cnum,$dom); @@ -8887,17 +7408,17 @@ sub fetch_enrollment_query { &logthis('fetch_enrollment_query: invalid queryid: '.$queryid.' for host: '.$host.' and homeserver: '.$homeserver.' context: '.$context.' '.$cnum); return 'error: '.$queryid; } - my $reply = &get_query_reply($queryid,$sleep,$loopmax); + my $reply = &get_query_reply($queryid); my $tries = 1; while (($reply=~/^timeout/) && ($tries < $maxtries)) { - $reply = &get_query_reply($queryid,$sleep,$loopmax); + $reply = &get_query_reply($queryid); $tries ++; } if ( ($reply =~/^timeout/) || ($reply =~/^error/) ) { &logthis('fetch_enrollment_query error: '.$reply.' for '.$dom.' '.$env{'user.name'}.' for '.$queryid.' context: '.$context.' '.$cnum.' maxtries: '.$maxtries.' tries: '.$tries); } else { my @responses = split(/:/,$reply); - if (grep { $_ eq $homeserver } ¤t_machine_ids()) { + if ($homeserver eq $perlvar{'lonHostID'}) { foreach my $line (@responses) { my ($key,$value) = split(/=/,$line,2); $$replyref{$key} = $value; @@ -8915,7 +7436,7 @@ sub fetch_enrollment_query { if ($xml_classlist =~ /^error/) { &logthis('fetch_enrollment_query - autoretrieve error: '.$xml_classlist.' for '.$filename.' from server: '.$homeserver.' '.$context.' '.$cnum); } else { - if ( open(FILE,">",$destname) ) { + if ( open(FILE,">$destname") ) { print FILE &unescape($xml_classlist); close(FILE); } else { @@ -8932,19 +7453,13 @@ sub fetch_enrollment_query { } sub get_query_reply { - my ($queryid,$sleep,$loopmax) = @_; - if (($sleep eq '') || ($sleep !~ /^\d+\.?\d*$/)) { - $sleep = 0.2; - } - if (($loopmax eq '') || ($loopmax =~ /\D/)) { - $loopmax = 100; - } + my $queryid=shift; my $replyfile=LONCAPA::tempdir().$queryid; my $reply=''; - for (1..$loopmax) { - sleep($sleep); + for (1..100) { + sleep 2; if (-e $replyfile.'.end') { - if (open(my $fh,"<",$replyfile)) { + if (open(my $fh,$replyfile)) { $reply = join('',<$fh>); close($fh); } else { return 'error: reply_file_error'; } @@ -9304,20 +7819,17 @@ sub auto_courserequest_checks { } sub auto_courserequest_validation { - my ($dom,$owner,$crstype,$inststatuslist,$instcode,$instseclist,$custominfo) = @_; + my ($dom,$owner,$crstype,$inststatuslist,$instcode,$instseclist) = @_; my ($homeserver,$response); if ($dom =~ /^$match_domain$/) { $homeserver = &domain($dom,'primary'); } - unless ($homeserver eq 'no_host') { - my $customdata; - if (ref($custominfo) eq 'HASH') { - $customdata = &freeze_escape($custominfo); - } + unless ($homeserver eq 'no_host') { + $response=&unescape(&reply('autocrsreqvalidation:'.$dom.':'.&escape($owner). ':'.&escape($crstype).':'.&escape($inststatuslist). - ':'.&escape($instcode).':'.&escape($instseclist).':'. - $customdata,$homeserver)); + ':'.&escape($instcode).':'.&escape($instseclist), + $homeserver)); } return $response; } @@ -9336,162 +7848,6 @@ sub auto_validate_class_sec { return $response; } -sub auto_validate_instclasses { - my ($cdom,$cnum,$owners,$classesref) = @_; - my ($homeserver,%validations); - $homeserver = &homeserver($cnum,$cdom); - unless ($homeserver eq 'no_host') { - my $ownerlist; - if (ref($owners) eq 'ARRAY') { - $ownerlist = join(',',@{$owners}); - } else { - $ownerlist = $owners; - } - if (ref($classesref) eq 'HASH') { - my $classes = &freeze_escape($classesref); - my $response=&reply('autovalidateinstclasses:'.&escape($ownerlist). - ':'.$cdom.':'.$classes,$homeserver); - unless ($response =~ /(con_lost|error|no_such_host|refused)/) { - my @items = split(/&/,$response); - foreach my $item (@items) { - my ($key,$value) = split('=',$item); - $validations{&unescape($key)} = &thaw_unescape($value); - } - } - } - } - return %validations; -} - -sub auto_crsreq_update { - my ($cdom,$cnum,$crstype,$action,$ownername,$ownerdomain,$fullname,$title, - $code,$accessstart,$accessend,$inbound) = @_; - my ($homeserver,%crsreqresponse); - if ($cdom =~ /^$match_domain$/) { - $homeserver = &domain($cdom,'primary'); - } - unless (($homeserver eq 'no_host') || ($homeserver eq '')) { - my $info; - if (ref($inbound) eq 'HASH') { - $info = &freeze_escape($inbound); - } - my $response=&reply('autocrsrequpdate:'.$cdom.':'.$cnum.':'.&escape($crstype). - ':'.&escape($action).':'.&escape($ownername).':'. - &escape($ownerdomain).':'.&escape($fullname).':'. - &escape($title).':'.&escape($code).':'. - &escape($accessstart).':'.&escape($accessend).':'.$info,$homeserver); - unless ($response =~ /(con_lost|error|no_such_host|refused)/) { - my @items = split(/&/,$response); - foreach my $item (@items) { - my ($key,$value) = split('=',$item); - $crsreqresponse{&unescape($key)} = &thaw_unescape($value); - } - } - } - return \%crsreqresponse; -} - -sub auto_export_grades { - my ($cdom,$cnum,$inforef,$gradesref) = @_; - my ($homeserver,%exportresponse); - if ($cdom =~ /^$match_domain$/) { - $homeserver = &domain($cdom,'primary'); - } - unless (($homeserver eq 'no_host') || ($homeserver eq '')) { - my $info; - if (ref($inforef) eq 'HASH') { - $info = &freeze_escape($inforef); - } - if (ref($gradesref) eq 'HASH') { - my $grades = &freeze_escape($gradesref); - my $response=&reply('encrypt:autoexportgrades:'.$cdom.':'.$cnum.':'. - $info.':'.$grades,$homeserver); - unless ($response =~ /(con_lost|error|no_such_host|refused|unknown_command)/) { - my @items = split(/&/,$response); - foreach my $item (@items) { - my ($key,$value) = split('=',$item); - $exportresponse{&unescape($key)} = &thaw_unescape($value); - } - } - } - } - return \%exportresponse; -} - -sub check_instcode_cloning { - my ($codedefaults,$code_order,$cloner,$clonefromcode,$clonetocode) = @_; - unless ((ref($codedefaults) eq 'HASH') && (ref($code_order) eq 'ARRAY')) { - return; - } - my $canclone; - if (@{$code_order} > 0) { - my $instcoderegexp ='^'; - my @clonecodes = split(/\&/,$cloner); - foreach my $item (@{$code_order}) { - if (grep(/^\Q$item\E=/,@clonecodes)) { - foreach my $pair (@clonecodes) { - my ($key,$val) = split(/\=/,$pair,2); - $val = &unescape($val); - if ($key eq $item) { - $instcoderegexp .= '('.$val.')'; - last; - } - } - } else { - $instcoderegexp .= $codedefaults->{$item}; - } - } - $instcoderegexp .= '$'; - my (@from,@to); - eval { - (@from) = ($clonefromcode =~ /$instcoderegexp/); - (@to) = ($clonetocode =~ /$instcoderegexp/); - }; - if ((@from > 0) && (@to > 0)) { - my @diffs = &Apache::loncommon::compare_arrays(\@from,\@to); - if (!@diffs) { - $canclone = 1; - } - } - } - return $canclone; -} - -sub default_instcode_cloning { - my ($clonedom,$domdefclone,$clonefromcode,$clonetocode,$codedefaultsref,$codeorderref) = @_; - my (%codedefaults,@code_order,$canclone); - if ((ref($codedefaultsref) eq 'HASH') && (ref($codeorderref) eq 'ARRAY')) { - %codedefaults = %{$codedefaultsref}; - @code_order = @{$codeorderref}; - } elsif ($clonedom) { - &auto_instcode_defaults($clonedom,\%codedefaults,\@code_order); - } - if (($domdefclone) && (@code_order)) { - my @clonecodes = split(/\+/,$domdefclone); - my $instcoderegexp ='^'; - foreach my $item (@code_order) { - if (grep(/^\Q$item\E$/,@clonecodes)) { - $instcoderegexp .= '('.$codedefaults{$item}.')'; - } else { - $instcoderegexp .= $codedefaults{$item}; - } - } - $instcoderegexp .= '$'; - my (@from,@to); - eval { - (@from) = ($clonefromcode =~ /$instcoderegexp/); - (@to) = ($clonetocode =~ /$instcoderegexp/); - }; - if ((@from > 0) && (@to > 0)) { - my @diffs = &Apache::loncommon::compare_arrays(\@from,\@to); - if (!@diffs) { - $canclone = 1; - } - } - } - return $canclone; -} - # ------------------------------------------------------- Course Group routines sub get_coursegroups { @@ -9760,7 +8116,7 @@ sub assignrole { } } } elsif ($context eq 'requestauthor') { - if (($udom eq $env{'user.domain'}) && ($uname eq $env{'user.name'}) && + if (($udom eq $env{'user.domain'}) && ($uname eq $env{'user.name'}) && ($url eq '/'.$udom.'/') && ($role eq 'au')) { if ($env{'environment.requestauthor'} eq 'automatic') { $refused = ''; @@ -9768,13 +8124,13 @@ sub assignrole { my %domdefaults = &get_domain_defaults($udom); if (ref($domdefaults{'requestauthor'}) eq 'HASH') { my $checkbystatus; - if ($env{'user.adv'}) { + if ($env{'user.adv'}) { my $disposition = $domdefaults{'requestauthor'}{'_LC_adv'}; if ($disposition eq 'automatic') { $refused = ''; } elsif ($disposition eq '') { $checkbystatus = 1; - } + } } else { $checkbystatus = 1; } @@ -9856,13 +8212,12 @@ sub assignrole { &courserolelog($role,$uname,$udom,$url,$origstart,$origend,$delflag, $selfenroll,$context); } elsif (($role eq 'li') || ($role eq 'dg') || ($role eq 'sc') || - ($role eq 'au') || ($role eq 'dc') || ($role eq 'dh') || - ($role eq 'da')) { + ($role eq 'au') || ($role eq 'dc')) { &domainrolelog($role,$uname,$udom,$url,$origstart,$origend,$delflag, $context); } elsif (($role eq 'ca') || ($role eq 'aa')) { &coauthorrolelog($role,$uname,$udom,$url,$origstart,$origend,$delflag, - $context); + $context); } if ($role eq 'cc') { &autoupdate_coowners($url,$end,$start,$uname,$udom); @@ -9961,35 +8316,19 @@ sub store_coowners { sub modifyuserauth { my ($udom,$uname,$umode,$upass)=@_; my $uhome=&homeserver($uname,$udom); - my $allowed; - if (&allowed('mau',$udom)) { - $allowed = 1; - } elsif (($umode eq 'internal') && ($udom eq $env{'user.domain'}) && - ($env{'request.course.id'}) && (&allowed('mip',$env{'request.course.id'})) && - (!$env{'course.'.$env{'request.course.id'}.'.internal.nopasswdchg'})) { - my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'}; - my $cnum = $env{'course.'.$env{'request.course.id'}.'.num'}; - if (($cdom ne '') && ($cnum ne '')) { - my $is_owner = &is_course_owner($cdom,$cnum); - if ($is_owner) { - $allowed = 1; - } - } - } - unless ($allowed) { return 'refused'; } + unless (&allowed('mau',$udom)) { return 'refused'; } &logthis('Call to modify user authentication '.$udom.', '.$uname.', '. $umode.' by '.$env{'user.name'}.' at '.$env{'user.domain'}. ' in domain '.$env{'request.role.domain'}); my $reply=&reply('encrypt:changeuserauth:'.$udom.':'.$uname.':'.$umode.':'. &escape($upass),$uhome); - my $ip = &get_requestor_ip(); &log($env{'user.domain'},$env{'user.name'},$env{'user.home'}, 'Authentication changed for '.$udom.', '.$uname.', '.$umode. - '(Remote '.$ip.'): '.$reply); + '(Remote '.$ENV{'REMOTE_ADDR'}.'): '.$reply); &log($udom,,$uname,$uhome, 'Authentication changed by '.$env{'user.domain'}.', '. $env{'user.name'}.', '.$umode. - '(Remote '.$ip.'): '.$reply); + '(Remote '.$ENV{'REMOTE_ADDR'}.'): '.$reply); unless ($reply eq 'ok') { &logthis('Authentication mode error: '.$reply); return 'error: '.$reply; @@ -10178,7 +8517,7 @@ sub modifyuser { sub modifystudent { my ($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene,$usec, $end,$start,$forceid,$desiredhome,$email,$type,$locktype,$cid, - $selfenroll,$context,$inststatus,$credits,$instsec)=@_; + $selfenroll,$context,$inststatus,$credits)=@_; if (!$cid) { unless ($cid=$env{'request.course.id'}) { return 'not_in_class'; @@ -10193,14 +8532,14 @@ sub modifystudent { # student's environment $uid = undef if (!$forceid); $reply = &modify_student_enrollment($udom,$uname,$uid,$first,$middle,$last, - $gene,$usec,$end,$start,$type,$locktype, - $cid,$selfenroll,$context,$credits,$instsec); + $gene,$usec,$end,$start,$type,$locktype, + $cid,$selfenroll,$context,$credits); return $reply; } sub modify_student_enrollment { my ($udom,$uname,$uid,$first,$middle,$last,$gene,$usec,$end,$start,$type, - $locktype,$cid,$selfenroll,$context,$credits,$instsec) = @_; + $locktype,$cid,$selfenroll,$context,$credits) = @_; my ($cdom,$cnum,$chome); if (!$cid) { unless ($cid=$env{'request.course.id'}) { @@ -10247,7 +8586,7 @@ sub modify_student_enrollment { my %old_entry = &Apache::lonnet::get('classlist',[$user],$cdom,$cnum); my $reply=cput('classlist', {$user => - join(':',$end,$start,$uid,$usec,$fullname,$type,$locktype,$credits,$instsec) }, + join(':',$end,$start,$uid,$usec,$fullname,$type,$locktype,$credits) }, $cdom,$cnum); if (($reply eq 'ok') || ($reply eq 'delayed')) { &devalidate_getsection_cache($udom,$uname,$cid); @@ -10470,25 +8809,13 @@ sub generate_coursenum { sub is_course { my ($cdom, $cnum) = scalar(@_) == 1 ? ($_[0] =~ /^($match_domain)_($match_courseid)$/) : @_; - return unless (($cdom =~ /^$match_domain$/) && ($cnum =~ /^$match_courseid$/)); - my $uhome=&homeserver($cnum,$cdom); - my $iscourse; - if (grep { $_ eq $uhome } current_machine_ids()) { - $iscourse = &LONCAPA::Lond::is_course($cdom,$cnum); - } else { - my $hashid = $cdom.':'.$cnum; - ($iscourse,my $cached) = &is_cached_new('iscourse',$hashid); - unless (defined($cached)) { - my %courses = &courseiddump($cdom, '.', 1, '.', '.', - $cnum,undef,undef,'.'); - $iscourse = 0; - if (exists($courses{$cdom.'_'.$cnum})) { - $iscourse = 1; - } - &do_cache_new('iscourse',$hashid,$iscourse,3600); - } - } - return unless($iscourse); + + return unless $cdom and $cnum; + + my %courses = &courseiddump($cdom, '.', 1, '.', '.', $cnum, undef, undef, + '.'); + + return unless(exists($courses{$cdom.'_'.$cnum})); return wantarray ? ($cdom, $cnum) : $cdom.'_'.$cnum; } @@ -10505,7 +8832,7 @@ sub store_userdata { if (($uhome eq '') || ($uhome eq 'no_host')) { $result = 'error: no_host'; } else { - $storehash->{'ip'} = &get_requestor_ip(); + $storehash->{'ip'} = $ENV{'REMOTE_ADDR'}; $storehash->{'host'} = $perlvar{'lonHostID'}; my $namevalue=''; @@ -10624,7 +8951,7 @@ sub save_selected_files { my ($user, $path, @files) = @_; my $filename = $user."savedfiles"; my @other_files = &files_not_in_path($user, $path); - open (OUT,'>',LONCAPA::tempdir().$filename); + open (OUT, '>'.$tmpdir.$filename); foreach my $file (@files) { print (OUT $env{'form.currentpath'}.$file."\n"); } @@ -10638,7 +8965,7 @@ sub save_selected_files { sub clear_selected_files { my ($user) = @_; my $filename = $user."savedfiles"; - open (OUT,'>',LONCAPA::tempdir().$filename); + open (OUT, '>'.LONCAPA::tempdir().$filename); print (OUT undef); close (OUT); return ("ok"); @@ -10648,7 +8975,7 @@ sub files_in_path { my ($user, $path) = @_; my $filename = $user."savedfiles"; my %return_files; - open (IN,'<',LONCAPA::tempdir().$filename); + open (IN, '<'.LONCAPA::tempdir().$filename); while (my $line_in = ) { chomp ($line_in); my @paths_and_file = split (m!/!, $line_in); @@ -10670,7 +8997,7 @@ sub files_not_in_path { my $filename = $user."savedfiles"; my @return_files; my $path_part; - open(IN, '<',LONCAPA::tempdir().$filename); + open(IN, '<'.LONCAPA::.$filename); while (my $line = ) { #ok, I know it's clunky, but I want it to work my @paths_and_file = split(m|/|, $line); @@ -10783,9 +9110,9 @@ sub modify_access_controls { my $tries = 0; my $gotlock = &newput('file_permissions',$lockhash,$domain,$user); - while (($gotlock ne 'ok') && $tries < 10) { + while (($gotlock ne 'ok') && $tries <3) { $tries ++; - sleep(0.1); + sleep 1; $gotlock = &newput('file_permissions',$lockhash,$domain,$user); } if ($gotlock eq 'ok') { @@ -11078,23 +9405,7 @@ sub dirlist { foreach my $user (sort(keys(%allusers))) { push(@alluserslist,$user.'&user'); } - if (!%listerror) { - # no errors - return (\@alluserslist); - } elsif (scalar(keys(%servers)) == 1) { - # one library server, one error - my ($key) = keys(%listerror); - return (\@alluserslist, $listerror{$key}); - } elsif ( grep { $_ eq 'con_lost' } values(%listerror) ) { - # con_lost indicates that we might miss data from at least one - # library server - return (\@alluserslist, 'con_lost'); - } else { - # multiple library servers and no con_lost -> data should be - # complete. - return (\@alluserslist); - } - + return (\@alluserslist); } else { return ([],'missing username'); } @@ -11311,12 +9622,10 @@ sub get_userresdata { } #error 2 occurs when the .db doesn't exist if ($tmp!~/error: 2 /) { - if ((!defined($cached)) || ($tmp ne 'con_lost')) { - &logthis("WARNING:". - " Trying to get resource data for ". - $uname." at ".$udom.": ". - $tmp.""); - } + &logthis("WARNING:". + " Trying to get resource data for ". + $uname." at ".$udom.": ". + $tmp.""); } elsif ($tmp=~/error: 2 /) { #&EXT_cache_set($udom,$uname); &do_cache_new('userres',$hashid,undef,600); @@ -11368,7 +9677,7 @@ sub get_numsuppfiles { unless ($chome eq 'no_host') { ($suppcount,my $errors) = (0,0); my $suppmap = 'supplemental.sequence'; - ($suppcount,$errors) = + ($suppcount,$errors) = &Apache::loncommon::recurse_supplemental($cnum,$cdom,$suppmap,$suppcount,$errors); } &do_cache_new('suppcount',$hashid,$suppcount,600); @@ -11563,7 +9872,7 @@ sub EXT { $courseid = $cid; } if (($symbparm && $courseid) && - (($courseid eq $env{'request.course.id'}) || ($courseid eq $cid))) { + (($courseid eq $env{'request.course.id'}) || ($courseid eq $cid))) { #print '
'.$space.' - '.$qualifier.' - '.$spacequalifierrest; @@ -11804,7 +10113,6 @@ sub add_prefix_and_part { my %metaentry; my %importedpartids; -my %importedrespids; sub metadata { my ($uri,$what,$liburi,$prefix,$depthcount)=@_; $uri=&declutter($uri); @@ -11815,7 +10123,7 @@ sub metadata { ($uri =~ m|/$|) || ($uri =~ m|/.meta$|) || ($uri =~ m{^/*uploaded/.+\.sequence$})) { return undef; } - if (($uri =~ /^priv/ || $uri=~m{^home/httpd/html/priv}) + if (($uri =~ /^priv/ || $uri=~/home\/httpd\/html\/priv/) && &Apache::lonxml::get_state('target') =~ /^(|meta)$/) { return undef; } @@ -11832,11 +10140,9 @@ sub metadata { } { # Imported parts would go here - my @origfiletagids=(); + my %importedids=(); + my @origfileimportpartids=(); my $importedparts=0; - -# Imported responseids would go here - my $importedresponses=0; # # Is this a recursive call for a library? # @@ -11931,37 +10237,8 @@ sub metadata { my $dir=$filename; $dir=~s|[^/]*$||; $location=&filelocation($dir,$location); - - my $importid=$token->[2]->{'id'}; + my $importmode=$token->[2]->{'importmode'}; -# -# Check metadata for imported file to -# see if it contained response items -# - my %currmetaentry = %metaentry; - my $libresponseorder = &metadata($location,'responseorder'); - my $origfile; - if ($libresponseorder ne '') { - if ($#origfiletagids<0) { - undef(%importedrespids); - undef(%importedpartids); - } - @{$importedrespids{$importid}} = split(/\s*,\s*/,$libresponseorder); - if (@{$importedrespids{$importid}} > 0) { - $importedresponses = 1; -# We need to get the original file and the imported file to get the response order correct -# Load and inspect original file - if ($#origfiletagids<0) { - my $origfilelocation=$perlvar{'lonDocRoot'}.&clutter($uri); - $origfile=&getfile($origfilelocation); - @origfiletagids=($origfile=~/<((?:\w+)response|import|part)[^>]*id\s*=\s*[\"\']([^\"\']+)[\"\'][^>]*>/gs); - } - } - } -# Do not overwrite contents of %metaentry hash for resource itself with -# hash populated for imported library file - %metaentry = %currmetaentry; - undef(%currmetaentry); if ($importmode eq 'problem') { # Import as problem/response $unikey=&add_prefix_and_part($prefix,$token->[2]->{'part'}); @@ -11970,15 +10247,12 @@ sub metadata { $importedparts=1; # We need to get the original file and the imported file to get the part order correct # Good news: we do not need to worry about nested libraries, since parts cannot be nested -# Load and inspect original file if we didn't do that already - if ($#origfiletagids<0) { - undef(%importedrespids); - undef(%importedpartids); - if ($origfile eq '') { - my $origfilelocation=$perlvar{'lonDocRoot'}.&clutter($uri); - $origfile=&getfile($origfilelocation); - @origfiletagids=($origfile=~/<(part|import)[^>]*id\s*=\s*[\"\']([^\"\']+)[\"\'][^>]*>/gs); - } +# Load and inspect original file + if ($#origfileimportpartids<0) { + undef(%importedpartids); + my $origfilelocation=$perlvar{'lonDocRoot'}.&clutter($uri); + my $origfile=&getfile($origfilelocation); + @origfileimportpartids=($origfile=~/<(part|import)[^>]*id\s*=\s*[\"\']([^\"\']+)[\"\'][^>]*>/gs); } # Load and inspect imported file @@ -12092,53 +10366,25 @@ sub metadata { grep { ! $seen{$_} ++ } (split(',',$metaentry{':packages'})); $metaentry{':packages'} = join(',',@uniq_packages); - if (($importedresponses) || ($importedparts)) { - if ($importedparts) { + if ($importedparts) { # We had imported parts and need to rebuild partorder - $metaentry{':partorder'}=''; - $metathesekeys{'partorder'}=1; - } - if ($importedresponses) { -# We had imported responses and need to rebuild responseorder - $metaentry{':responseorder'}=''; - $metathesekeys{'responseorder'}=1; - } - for (my $index=0;$index<$#origfiletagids;$index+=2) { - my $origid = $origfiletagids[$index+1]; - if ($origfiletagids[$index] eq 'part') { -# Original part, part of the problem - if ($importedparts) { - $metaentry{':partorder'}.=','.$origid; - } - } elsif ($origfiletagids[$index] eq 'import') { - if ($importedparts) { -# We have imported parts at this position - $metaentry{':partorder'}.=','.$importedpartids{$origid}; - } - if ($importedresponses) { -# We have imported responses at this position - if (ref($importedrespids{$origid}) eq 'ARRAY') { - $metaentry{':responseorder'}.=','.join(',',map { $origid.'_'.$_ } @{$importedrespids{$origid}}); - } - } - } else { -# Original response item, part of the problem - if ($importedresponses) { - $metaentry{':responseorder'}.=','.$origid; - } - } - } - if ($importedparts) { - $metaentry{':partorder'}=~s/^\,//; - } - if ($importedresponses) { - $metaentry{':responseorder'}=~s/^\,//; - } + $metaentry{':partorder'}=''; + $metathesekeys{'partorder'}=1; + for (my $index=0;$index<$#origfileimportpartids;$index+=2) { + if ($origfileimportpartids[$index] eq 'part') { +# original part, part of the problem + $metaentry{':partorder'}.=','.$origfileimportpartids[$index+1]; + } else { +# we have imported parts at this position + $metaentry{':partorder'}.=','.$importedpartids{$origfileimportpartids[$index+1]}; + } + } + $metaentry{':partorder'}=~s/^\,//; } $metaentry{':keys'} = join(',',keys(%metathesekeys)); &metadata_generate_part0(\%metathesekeys,\%metaentry,$uri); - $metaentry{':allpossiblekeys'}=join(',',keys(%metathesekeys)); + $metaentry{':allpossiblekeys'}=join(',',keys %metathesekeys); &do_cache_new('meta',$uri,\%metaentry,$cachetime); # this is the end of "was not already recently cached } @@ -12398,21 +10644,23 @@ sub symbverify { if (tie(%bighash,'GDBM_File',$env{'request.course.fn'}.'.db', &GDBM_READER(),0640)) { + my $noclutter; if (($thisurl =~ m{^/adm/wrapper/ext/}) || ($thisurl =~ m{^ext/})) { $thisurl =~ s/\?.+$//; if ($map =~ m{^uploaded/.+\.page$}) { $thisurl =~ s{^(/adm/wrapper|)/ext/}{http://}; $thisurl =~ s{^\Qhttp://https://\E}{https://}; + $noclutter = 1; } } my $ids; - if ($map =~ m{^uploaded/.+\.page$}) { - $ids=$bighash{'ids_'.&clutter_with_no_wrapper($thisurl)}; + if ($noclutter) { + $ids=$bighash{'ids_'.$thisurl}; } else { $ids=$bighash{'ids_'.&clutter($thisurl)}; } unless ($ids) { - my $idkey = 'ids_'.($thisurl =~ m{^/}? '' : '/').$thisurl; + my $idkey = 'ids_'.($thisurl =~ m{^/}? '' : '/').$thisurl; $ids=$bighash{$idkey}; } if ($ids) { @@ -12428,14 +10676,14 @@ sub symbverify { if (ref($encstate)) { $$encstate = $bighash{'encrypted_'.$id}; } - if (($env{'request.role.adv'}) || - ($bighash{'encrypted_'.$id} eq $env{'request.enc'}) || + if (($env{'request.role.adv'}) || + ($bighash{'encrypted_'.$id} eq $env{'request.enc'}) || ($thisurl eq '/adm/navmaps')) { - $okay=1; + $okay=1; last; - } - } - } + } + } + } } untie(%bighash); } @@ -12507,24 +10755,19 @@ sub deversion { # ------------------------------------------------------ Return symb list entry sub symbread { - my ($thisfn,$donotrecurse,$ignorecachednull,$checkforblock,$possibles, - $ignoresymbdb,$noenccheck)=@_; - my $cache_str='request.symbread.cached.'.$thisfn; - if (defined($env{$cache_str})) { - unless (ref($possibles) eq 'HASH') { - if ($ignorecachednull) { - return $env{$cache_str} unless ($env{$cache_str} eq ''); - } else { - return $env{$cache_str}; - } + my ($thisfn,$donotrecurse)=@_; + my $cache_str; + if ($thisfn ne '') { + $cache_str='request.symbread.cached.'.$thisfn; + if ($env{$cache_str} ne '') { + return $env{$cache_str}; } - } + } else { # no filename provided? try from environment - unless ($thisfn) { if ($env{'request.symb'}) { - return $env{$cache_str}=&symbclean($env{'request.symb'}); - } - $thisfn=$env{'request.filename'}; + return $env{$cache_str}=&symbclean($env{'request.symb'}); + } + $thisfn=$env{'request.filename'}; } if ($thisfn=~m|^/enc/|) { $thisfn=&Apache::lonenc::unencrypted($thisfn); } # is that filename actually a symb? Verify, clean, and return @@ -12545,18 +10788,10 @@ sub symbread { if ($targetfn =~ m|^adm/wrapper/(ext/.*)|) { $targetfn=$1; } - unless ($ignoresymbdb) { - if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db', - &GDBM_READER(),0640)) { - $syval=$hash{$targetfn}; - untie(%hash); - } - if ($syval && $checkforblock) { - my @blockers = &has_comm_blocking('bre',$syval,$thisfn,$ignoresymbdb,$noenccheck); - if (@blockers) { - $syval=''; - } - } + if (tie(%hash,'GDBM_File',$env{'request.course.fn'}.'_symb.db', + &GDBM_READER(),0640)) { + $syval=$hash{$targetfn}; + untie(%hash); } # ---------------------------------------------------------- There was an entry if ($syval) { @@ -12588,57 +10823,18 @@ sub symbread { my ($mapid,$resid)=split(/\./,$ids); $syval=&encode_symb($bighash{'map_id_'.$mapid}, $resid,$thisfn); - if (ref($possibles) eq 'HASH') { - unless ($bighash{'randomout_'.$ids} || $env{'request.role.adv'}) { - $possibles->{$syval} = 1; - } - } - if ($checkforblock) { - unless ($bighash{'randomout_'.$ids} || $env{'request.role.adv'}) { - my @blockers = &has_comm_blocking('bre',$syval,$bighash{'src_'.$ids},'',$noenccheck); - if (@blockers) { - $syval = ''; - untie(%bighash); - return $env{$cache_str}=''; - } - } - } - } elsif ((!$donotrecurse) || ($checkforblock) || (ref($possibles) eq 'HASH')) { + } elsif (!$donotrecurse) { # ------------------------------------------ There is more than one possibility my $realpossible=0; foreach my $id (@possibilities) { my $file=$bighash{'src_'.$id}; - my $canaccess; - if (($donotrecurse) || ($checkforblock) || (ref($possibles) eq 'HASH')) { - $canaccess = 1; - } else { - $canaccess = &allowed('bre',$file); - } - if ($canaccess) { - my ($mapid,$resid)=split(/\./,$id); - if ($bighash{'map_type_'.$mapid} ne 'page') { - my $poss_syval=&encode_symb($bighash{'map_id_'.$mapid}, - $resid,$thisfn); - next if ($bighash{'randomout_'.$id} && !$env{'request.role.adv'}); - next unless (($noenccheck) || ($bighash{'encrypted_'.$id} eq $env{'request.enc'})); - if ($checkforblock) { - my @blockers = &has_comm_blocking('bre',$poss_syval,$file,'',$noenccheck); - if (@blockers > 0) { - $syval = ''; - } else { - $syval = $poss_syval; - $realpossible++; - } - } else { - $syval = $poss_syval; - $realpossible++; - } - if ($syval) { - if (ref($possibles) eq 'HASH') { - $possibles->{$syval} = 1; - } - } - } + if (&allowed('bre',$file)) { + my ($mapid,$resid)=split(/\./,$id); + if ($bighash{'map_type_'.$mapid} ne 'page') { + $realpossible++; + $syval=&encode_symb($bighash{'map_id_'.$mapid}, + $resid,$thisfn); + } } } if ($realpossible!=1) { $syval=''; } @@ -12646,7 +10842,7 @@ sub symbread { $syval=''; } } - untie(%bighash); + untie(%bighash) } } if ($syval) { @@ -12799,6 +10995,7 @@ sub rndseed { $which =&get_rand_alg($courseid); } if (defined(&getCODE())) { + if ($which eq '64bit5') { return &rndseed_CODE_64bit5($symb,$courseid,$domain,$username); } elsif ($which eq '64bit4') { @@ -12984,12 +11181,8 @@ sub rndseed_CODE_64bit5 { sub setup_random_from_rndseed { my ($rndseed)=@_; if ($rndseed =~/([,:])/) { - my ($num1,$num2) = map { abs($_); } (split(/[,:]/,$rndseed)); - if ((!$num1) || (!$num2) || ($num1 > 2147483562) || ($num2 > 2147483398)) { - &Math::Random::random_set_seed_from_phrase($rndseed); - } else { - &Math::Random::random_set_seed($num1,$num2); - } + my ($num1,$num2)=split(/[,:]/,$rndseed); + &Math::Random::random_set_seed(abs($num1),abs($num2)); } else { &Math::Random::random_set_seed_from_phrase($rndseed); } @@ -13175,10 +11368,9 @@ sub repcopy_userfile { my $request; $uri=~s/^\///; my $homeserver = &homeserver($cnum,$cdom); - my $hostname = &hostname($homeserver); my $protocol = $protocol{$homeserver}; $protocol = 'http' if ($protocol ne 'https'); - $request=new HTTP::Request('GET',$protocol.'://'.$hostname.'/raw/'.$uri); + $request=new HTTP::Request('GET',$protocol.'://'.&hostname($homeserver).'/raw/'.$uri); my $response=$ua->request($request,$transferfile); # did it work? if ($response->is_error()) { @@ -13202,10 +11394,9 @@ sub tokenwrapper { $file=~s|(\?\.*)*$||; &appenv({"userfile.$udom/$uname/$file" => $env{'request.course.id'}}); my $homeserver = &homeserver($uname,$udom); - my $hostname = &hostname($homeserver); my $protocol = $protocol{$homeserver}; $protocol = 'http' if ($protocol ne 'https'); - return $protocol.'://'.$hostname.'/'.$uri. + return $protocol.'://'.&hostname($homeserver).'/'.$uri. (($uri=~/\?/)?'&':'?').'token='.$token. '&tokenissued='.$perlvar{'lonHostID'}; } else { @@ -13221,10 +11412,9 @@ sub getuploaded { my ($reqtype,$uri,$cdom,$cnum,$info,$rtncode) = @_; $uri=~s/^\///; my $homeserver = &homeserver($cnum,$cdom); - my $hostname = &hostname($homeserver); my $protocol = $protocol{$homeserver}; $protocol = 'http' if ($protocol ne 'https'); - $uri = $protocol.'://'.$hostname.'/raw/'.$uri; + $uri = $protocol.'://'.&hostname($homeserver).'/raw/'.$uri; my $ua=new LWP::UserAgent; my $request=new HTTP::Request($reqtype,$uri); my $response=$ua->request($request); @@ -13244,7 +11434,7 @@ sub readfile { my $file = shift; if ( (! -e $file ) || ($file eq '') ) { return -1; }; my $fh; - open($fh,"<",$file); + open($fh,"<$file"); my $a=''; while (my $line = <$fh>) { $a .= $line; } return $a; @@ -13357,7 +11547,7 @@ sub machine_ids { sub additional_machine_domains { my @domains; - open(my $fh,"<","$perlvar{'lonTabDir'}/expected_domains.tab"); + open(my $fh,"<$perlvar{'lonTabDir'}/expected_domains.tab"); while( my $line = <$fh>) { $line =~ s/\s//g; push(@domains,$line); @@ -13378,88 +11568,12 @@ sub default_login_domain { return $domain; } -sub shared_institution { - my ($dom,$lonhost) = @_; - if ($lonhost eq '') { - $lonhost = $perlvar{'lonHostID'}; - } - my $same_intdom; - my $hostintdom = &internet_dom($lonhost); - if ($hostintdom ne '') { - my %iphost = &get_iphost(); - my $primary_id = &domain($dom,'primary'); - my $primary_ip = &get_host_ip($primary_id); - if (ref($iphost{$primary_ip}) eq 'ARRAY') { - foreach my $id (@{$iphost{$primary_ip}}) { - my $intdom = &internet_dom($id); - if ($intdom eq $hostintdom) { - $same_intdom = 1; - last; - } - } - } - } - return $same_intdom; -} - -sub uses_sts { - my ($ignore_cache) = @_; - my $lonhost = $perlvar{'lonHostID'}; - my $hostname = &hostname($lonhost); - my $sts_on; - if ($protocol{$lonhost} eq 'https') { - my $cachetime = 12*3600; - if (!$ignore_cache) { - ($sts_on,my $cached)=&is_cached_new('stspolicy',$lonhost); - if (defined($cached)) { - return $sts_on; - } - } - my $ua=new LWP::UserAgent; - my $url = $protocol{$lonhost}.'://'.$hostname.'/index.html'; - my $request=new HTTP::Request('HEAD',$url); - my $response=$ua->request($request); - if ($response->is_success) { - my $has_sts = $response->header('Strict-Transport-Security'); - if ($has_sts eq '') { - $sts_on = 0; - } else { - if ($has_sts =~ /\Qmax-age=\E(\d+)/) { - my $maxage = $1; - if ($maxage) { - $sts_on = 1; - } else { - $sts_on = 0; - } - } else { - $sts_on = 0; - } - } - return &do_cache_new('stspolicy',$lonhost,$sts_on,$cachetime); - } - } - return; -} - -sub get_requestor_ip { - my ($r,$nolookup,$noproxy) = @_; - my $from_ip; - if (ref($r)) { - $from_ip = $r->get_remote_host($nolookup); - } else { - $from_ip = $ENV{'REMOTE_ADDR'}; - } - return $from_ip; -} - # ------------------------------------------------------------- Declutters URLs sub declutter { my $thisfn=shift; if ($thisfn=~m|^/enc/|) { $thisfn=&Apache::lonenc::unencrypted($thisfn); } - unless ($thisfn=~m{^/home/httpd/html/priv/}) { - $thisfn=~s{^/home/httpd/html}{}; - } + $thisfn=~s/^\Q$perlvar{'lonDocRoot'}\E//; $thisfn=~s/^\///; $thisfn=~s|^adm/wrapper/||; $thisfn=~s|^adm/coursedocs/showdoc/||; @@ -13575,20 +11689,18 @@ sub get_dns { } my %alldns; - if (open(my $config,"<","$perlvar{'lonTabDir'}/hosts.tab")) { - foreach my $dns (<$config>) { - next if ($dns !~ /^\^(\S*)/x); - my $line = $1; - my ($host,$protocol) = split(/:/,$line); - if ($protocol ne 'https') { - $protocol = 'http'; - } - $alldns{$host} = $protocol; + open(my $config,"<$perlvar{'lonTabDir'}/hosts.tab"); + foreach my $dns (<$config>) { + next if ($dns !~ /^\^(\S*)/x); + my $line = $1; + my ($host,$protocol) = split(/:/,$line); + if ($protocol ne 'https') { + $protocol = 'http'; } - close($config); + $alldns{$host} = $protocol; } while (%alldns) { - my ($dns) = sort { $b cmp $a } keys(%alldns); + my ($dns) = keys(%alldns); my $ua=new LWP::UserAgent; $ua->timeout(30); my $request=new HTTP::Request('GET',"$alldns{$dns}://$dns$url"); @@ -13596,53 +11708,34 @@ sub get_dns { delete($alldns{$dns}); next if ($response->is_error()); my @content = split("\n",$response->content); - unless ($nocache) { + unless ($nocache) { &do_cache_new('dns',$url,\@content,30*24*60*60); - } + } &$func(\@content,$hashref); return; } + close($config); my $which = (split('/',$url))[3]; &logthis("unable to contact DNS defaulting to on disk file dns_$which.tab\n"); - if (open(my $config,"<","$perlvar{'lonTabDir'}/dns_$which.tab")) { - my @content = <$config>; - &$func(\@content,$hashref); - } + open($config,"<$perlvar{'lonTabDir'}/dns_$which.tab"); + my @content = <$config>; + &$func(\@content,$hashref); return; } # ------------------------------------------------------Get DNS checksums file sub parse_dns_checksums_tab { my ($lines,$hashref) = @_; - my $lonhost = $perlvar{'lonHostID'}; - my $machine_dom = &Apache::lonnet::host_domain($lonhost); + my $machine_dom = &Apache::lonnet::host_domain($perlvar{'lonHostID'}); my $loncaparev = &get_server_loncaparev($machine_dom); - my $distro = (split(/\:/,&get_server_distarch($lonhost)))[0]; - my $webconfdir = '/etc/httpd/conf'; - if ($distro =~ /^(ubuntu|debian)(\d+)$/) { - $webconfdir = '/etc/apache2'; - } elsif ($distro =~ /^sles(\d+)$/) { - if ($1 >= 10) { - $webconfdir = '/etc/apache2'; - } - } elsif ($distro =~ /^suse(\d+\.\d+)$/) { - if ($1 >= 10.0) { - $webconfdir = '/etc/apache2'; - } - } my ($release,$timestamp) = split(/\-/,$loncaparev); my (%chksum,%revnum); if (ref($lines) eq 'ARRAY') { chomp(@{$lines}); my $version = shift(@{$lines}); - if ($version eq $release) { + if ($version eq $release) { foreach my $line (@{$lines}) { my ($file,$version,$shasum) = split(/,/,$line); - if ($file =~ m{^/etc/httpd/conf}) { - if ($webconfdir eq '/etc/apache2') { - $file =~ s{^\Q/etc/httpd/conf/\E}{$webconfdir/}; - } - } $chksum{$file} = $shasum; $revnum{$file} = $version; } @@ -13660,7 +11753,7 @@ sub parse_dns_checksums_tab { sub fetch_dns_checksums { my %checksums; my $machine_dom = &Apache::lonnet::host_domain($perlvar{'lonHostID'}); - my $loncaparev = &get_server_loncaparev($machine_dom,$perlvar{'lonHostID'}); + my $loncaparev = &get_server_loncaparev($machine_dom); my ($release,$timestamp) = split(/\-/,$loncaparev); &get_dns("/adm/dns/checksums/$release",\&parse_dns_checksums_tab,1,1, \%checksums); @@ -13695,10 +11788,10 @@ sub fetch_dns_checksums { } sub load_domain_tab { - my ($ignore_cache,$nocache) = @_; - &get_dns('/adm/dns/domain',\&parse_domain_tab,$ignore_cache,$nocache); + my ($ignore_cache) = @_; + &get_dns('/adm/dns/domain',\&parse_domain_tab,$ignore_cache); my $fh; - if (open($fh,"<",$perlvar{'lonTabDir'}.'/domain.tab')) { + if (open($fh,"<".$perlvar{'lonTabDir'}.'/domain.tab')) { my @lines = <$fh>; &parse_domain_tab(\@lines); } @@ -13750,23 +11843,8 @@ sub fetch_dns_checksums { my ($id,$domain,$role,$name,$protocol,$intdom)=split(/:/,$configline); $name=~s/\s//g; if ($id && $domain && $role && $name) { - if ((exists($hostname{$id})) && ($hostname{$id} ne '')) { - my $curr = $hostname{$id}; - my $skip; - if (ref($name_to_host{$curr}) eq 'ARRAY') { - if (($curr eq $name) && (@{$name_to_host{$curr}} == 1)) { - $skip = 1; - } else { - @{$name_to_host{$curr}} = grep { $_ ne $id } @{$name_to_host{$curr}}; - } - } - unless ($skip) { - push(@{$name_to_host{$name}},$id); - } - } else { - push(@{$name_to_host{$name}},$id); - } $hostname{$id}=$name; + push(@{$name_to_host{$name}}, $id); $hostdom{$id}=$domain; if ($role eq 'library') { $libserv{$id}=$name; } if (defined($protocol)) { @@ -13797,9 +11875,9 @@ sub fetch_dns_checksums { } sub load_hosts_tab { - my ($ignore_cache,$nocache) = @_; - &get_dns('/adm/dns/hosts',\&parse_hosts_tab,$ignore_cache,$nocache); - open(my $config,"<","$perlvar{'lonTabDir'}/hosts.tab"); + my ($ignore_cache) = @_; + &get_dns('/adm/dns/hosts',\&parse_hosts_tab,$ignore_cache); + open(my $config,"<$perlvar{'lonTabDir'}/hosts.tab"); my @config = <$config>; &parse_hosts_tab(\@config); close($config); @@ -13820,8 +11898,7 @@ sub fetch_dns_checksums { } sub all_names { - my ($ignore_cache,$nocache) = @_; - &load_hosts_tab($ignore_cache,$nocache) if (!$loaded); + &load_hosts_tab() if (!$loaded); return %name_to_host; } @@ -13943,7 +12020,7 @@ sub fetch_dns_checksums { } sub get_iphost { - my ($ignore_cache,$nocache) = @_; + my ($ignore_cache) = @_; if (!$ignore_cache) { if (%iphost) { @@ -13967,7 +12044,7 @@ sub fetch_dns_checksums { %old_name_to_ip = %{$ip_info->[1]}; } - my %name_to_host = &all_names($ignore_cache,$nocache); + my %name_to_host = &all_names(); foreach my $name (keys(%name_to_host)) { my $ip; if (!exists($name_to_ip{$name})) { @@ -13992,11 +12069,9 @@ sub fetch_dns_checksums { } push(@{$iphost{$ip}},@{$name_to_host{$name}}); } - unless ($nocache) { - &do_cache_new('iphost','iphost', - [\%iphost,\%name_to_ip,\%lonid_to_ip], - 48*60*60); - } + &do_cache_new('iphost','iphost', + [\%iphost,\%name_to_ip,\%lonid_to_ip], + 48*60*60); return %iphost; } @@ -14058,14 +12133,14 @@ sub fetch_dns_checksums { } 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 2.11); + 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); } -# ------------------------------------------------------- Read loncaparev table +# ---------------------------------------------------------- Read loncaparev table { - sub load_loncaparevs { + sub load_loncaparevs { if (-e "$perlvar{'lonTabDir'}/loncaparevs.tab") { - if (open(my $config,"<","$perlvar{'lonTabDir'}/loncaparevs.tab")) { + if (open(my $config,"<$perlvar{'lonTabDir'}/loncaparevs.tab")) { while (my $configline=<$config>) { chomp($configline); my ($hostid,$loncaparev)=split(/:/,$configline); @@ -14077,11 +12152,11 @@ sub all_loncaparevs { } } -# ----------------------------------------------------- Read serverhostID table +# ---------------------------------------------------------- Read serverhostID table { sub load_serverhomeIDs { if (-e "$perlvar{'lonTabDir'}/serverhomeIDs.tab") { - if (open(my $config,"<","$perlvar{'lonTabDir'}/serverhomeIDs.tab")) { + if (open(my $config,"<$perlvar{'lonTabDir'}/serverhomeIDs.tab")) { while (my $configline=<$config>) { chomp($configline); my ($name,$id)=split(/:/,$configline); @@ -14106,7 +12181,7 @@ BEGIN { # ------------------------------------------------------ Read spare server file { - open(my $config,"<","$perlvar{'lonTabDir'}/spare.tab"); + open(my $config,"<$perlvar{'lonTabDir'}/spare.tab"); while (my $configline=<$config>) { chomp($configline); @@ -14120,7 +12195,7 @@ BEGIN { } # ------------------------------------------------------------ Read permissions { - open(my $config,"<","$perlvar{'lonTabDir'}/roles.tab"); + open(my $config,"<$perlvar{'lonTabDir'}/roles.tab"); while (my $configline=<$config>) { chomp($configline); @@ -14134,7 +12209,7 @@ BEGIN { # -------------------------------------------- Read plain texts for permissions { - open(my $config,"<","$perlvar{'lonTabDir'}/rolesplain.tab"); + open(my $config,"<$perlvar{'lonTabDir'}/rolesplain.tab"); while (my $configline=<$config>) { chomp($configline); @@ -14154,7 +12229,7 @@ BEGIN { # ---------------------------------------------------------- Read package table { - open(my $config,"<","$perlvar{'lonTabDir'}/packages.tab"); + open(my $config,"<$perlvar{'lonTabDir'}/packages.tab"); while (my $configline=<$config>) { if ($configline !~ /\S/ || $configline=~/^#/) { next; } @@ -14169,11 +12244,11 @@ BEGIN { close($config); } -# --------------------------------------------------------- Read loncaparev table +# ---------------------------------------------------------- Read loncaparev table &load_loncaparevs(); -# ------------------------------------------------------- Read serverhostID table +# ---------------------------------------------------------- Read serverhostID table &load_serverhomeIDs(); @@ -14200,7 +12275,7 @@ BEGIN { # ---------------------------------------------------------- Read managers table { if (-e "$perlvar{'lonTabDir'}/managers.tab") { - if (open(my $config,"<","$perlvar{'lonTabDir'}/managers.tab")) { + if (open(my $config,"<$perlvar{'lonTabDir'}/managers.tab")) { while (my $configline=<$config>) { chomp($configline); next if ($configline =~ /^\#/); @@ -14219,16 +12294,6 @@ BEGIN { } -# ------------- set default texengine (domain default overrides this) -{ - $deftex = LONCAPA::texengine(); -} - -# ------------- set default minimum length for passwords for internal auth users -{ - $passwdmin = LONCAPA::passwd_min(); -} - $memcache=new Cache::Memcached({'servers' => ['127.0.0.1:11211'], 'compress_threshold'=> 20_000, }); @@ -14246,6 +12311,17 @@ $readit=1; if ($test != 0) { $_64bit=1; } else { $_64bit=0; } &logthis(" Detected 64bit platform ($_64bit)"); } + + { + eval { + ($apache) = + (Apache2::ServerUtil::get_server_version() =~ m{Apache/(\d+\.\d+)}); + }; + if ($@) { + $apache = 1.3; + } + } + } } @@ -14387,7 +12463,7 @@ were new keys. I.E. 1:foo will become 1: Calling convention: my %record=&Apache::lonnet::restore($symb,$courseid,$domain,$uname); - &Apache::lonnet::cstore(\%newrecord,$symb,$courseid,$domain,$uname,$laststore); + &Apache::lonnet::cstore(\%newrecord,$symb,$courseid,$domain,$uname); For more detailed information, see lonnet specific documentation. @@ -14523,29 +12599,13 @@ escaped strings of the action recorded i =item * -allowed($priv,$uri,$symb,$role,$clientip,$noblockcheck) : check for a user privilege; -returns codes for allowed actions. - -The first argument is required, all others are optional. - -$priv is the privilege being checked. -$uri contains additional information about what is being checked for access (e.g., -URL, course ID etc.). -$symb is the unique resource instance identifier in a course; if needed, -but not provided, it will be retrieved via a call to &symbread(). -$role is the role for which a priv is being checked (only used if priv is evb). -$clientip is the user's IP address (only used when checking for access to portfolio -files). -$noblockcheck, if true, skips calls to &has_comm_blocking() for the bre priv. This -prevents recursive calls to &allowed. - +allowed($priv,$uri,$symb,$role) : check for a user privilege; returns codes for allowed actions F: full access U,I,K: authentication modes (cxx only) '': forbidden 1: user needs to choose course 2: browse allowed A: passphrase authentication needed - B: access temporarily blocked because of a blocking event in a course. =item * @@ -14564,10 +12624,9 @@ in which case the null string is returne =item * -definerole($rolename,$sysrole,$domrole,$courole,$uname,$udom) : define role; -define a custom role rolename set privileges in format of lonTabs/roles.tab -for system, domain, and course level. $uname and $udom are optional (current -user's username and domain will be used when either of $uname or $udom are absent. +definerole($rolename,$sysrole,$domrole,$courole) : define role; define a custom +role rolename set privileges in format of lonTabs/roles.tab for system, domain, +and course level =item * @@ -14598,9 +12657,9 @@ provided for types, will default to retu =item * in_course($udom,$uname,$cdom,$cnum,$type,$hideprivileged) : determine if -user: $uname:$udom has a role in the course: $cdom_$cnum. +user: $uname:$udom has a role in the course: $cdom_$cnum. -Additional optional arguments are: $type (if role checking is to be restricted +Additional optional arguments are: $type (if role checking is to be restricted to certain user status types -- previous (expired roles), active (currently available roles) or future (roles available in the future), and $hideprivileged -- if true will not report course roles for users who @@ -14771,8 +12830,6 @@ Inputs: =item $credits, number of credits student will earn from this class -=item $instsec, institutional course section code for student - =back @@ -14839,7 +12896,7 @@ values that are the resource value. I b versions are also returned. get_numsuppfiles($cnum,$cdom) : retrieve number of files in a course's -supplemental content area. This routine caches the number of files for +supplemental content area. This routine caches the number of files for 10 minutes. =back @@ -14876,88 +12933,6 @@ Returns: =back -=head2 Bubblesheet Configuration - -=over 4 - -=item * - -get_scantron_config($which) - -$which - the name of the configuration to parse from the file. - -Parses and returns the bubblesheet configuration line selected as a -hash of configuration file fields. - - -Returns: - If the named configuration is not in the file, an empty - hash is returned. - - a hash with the fields - name - internal name for the this configuration setup - description - text to display to operator that describes this config - CODElocation - if 0 or the string 'none' - - no CODE exists for this config - if -1 || the string 'letter' - - a CODE exists for this config and is - a string of letters - Unsupported value (but planned for future support) - if a positive integer - - The CODE exists as the first n items from - the question section of the form - if the string 'number' - - The CODE exists for this config and is - a string of numbers - CODEstart - (only matter if a CODE exists) column in the line where - the CODE starts - CODElength - length of the CODE - IDstart - column where the student/employee ID starts - IDlength - length of the student/employee ID info - Qstart - column where the information from the bubbled - 'questions' start - Qlength - number of columns comprising a single bubble line from - the sheet. (usually either 1 or 10) - Qon - either a single character representing the character used - to signal a bubble was chosen in the positional setup, or - the string 'letter' if the letter of the chosen bubble is - in the final, or 'number' if a number representing the - chosen bubble is in the file (1->A 0->J) - Qoff - the character used to represent that a bubble was - left blank - PaperID - if the scanning process generates a unique number for each - sheet scanned the column that this ID number starts in - PaperIDlength - number of columns that comprise the unique ID number - for the sheet of paper - FirstName - column that the first name starts in - FirstNameLength - number of columns that the first name spans - LastName - column that the last name starts in - LastNameLength - number of columns that the last name spans - BubblesPerRow - number of bubbles available in each row used to - bubble an answer. (If not specified, 10 assumed). - - -=item * - -get_scantronformat_file($cdom) - -$cdom - the course's domain (optional); if not supplied, uses -domain for current $env{'request.course.id'}. - -Returns an array containing lines from the scantron format file for -the domain of the course. - -If a url for a custom.tab file is listed in domain's configuration.db, -lines are from this file. - -Otherwise, if a default.tab has been published in RES space by the -domainconfig user, lines are from this file. - -Otherwise, fall back to getting lines from the legacy file on the -local server: /home/httpd/lonTabs/default_scantronformat.tab - -=back - =head2 Resource Subroutines =over 4 @@ -15024,20 +12999,7 @@ will be stored for query =item * -symbread($filename,$donotrecurse,$ignorecachednull,$checkforblock,$possibles) : -return symbolic list entry (all arguments optional). - -Args: filename is the filename (including path) for the file for which a symb -is required; donotrecurse, if true will prevent calls to allowed() being made -to check access status if more than one resource was found in the bighash -(see rev. 1.249) to avoid an infinite loop if an ambiguous resource is part of -a randompick); ignorecachednull, if true will prevent a symb of '' being -returned if $env{$cache_str} is defined as ''; checkforblock if true will -cause possible symbs to be checked to determine if they are subject to content -blocking, if so they will not be included as possible symbs; possibles is a -ref to a hash, which, as a side effect, will be populated with all possible -symbs (content blocking not tested). - +symbread($filename) : return symbolic list entry (filename argument optional); returns the data handle =item * @@ -15047,9 +13009,9 @@ and is a possible symb for the URL in $t resource that the user accessed using /enc/ returns a 1 on success, 0 on failure, user must be in a course, as it assumes the existence of the course initial hash, and uses $env('request.course.id'}. The third -arg is an optional reference to a scalar. If this arg is passed in the +arg is an optional reference to a scalar. If this arg is passed in the call to symbverify, it will be set to 1 if the symb has been set to be -encrypted; otherwise it will be null. +encrypted; otherwise it will be null. =item * @@ -15102,13 +13064,13 @@ expirespread($uname,$udom,$stype,$usymb) devalidate($symb) : devalidate temporary spreadsheet calculations, forcing spreadsheet to reevaluate the resource scores next time. -=item * +=item * can_edit_resource($file,$cnum,$cdom,$resurl,$symb,$group) : determine if current user can edit a particular resource, when viewing in course context. input: six args -- filename (decluttered), course number, course domain, - url, symb (if registered) and group (if this is a + url, symb (if registered) and group (if this is a group item -- e.g., bulletin board, group page etc.). output: array of five scalars -- @@ -15116,15 +13078,15 @@ when viewing in course context. $home -- homeserver of resource (i.e., for author if published, or course if uploaded.). $switchserver -- 1 if server switch will be needed. - $forceedit -- 1 if icon/link should be to go to edit mode + $forceedit -- 1 if icon/link should be to go to edit mode $forceview -- 1 if icon/link should be to go to view mode =item * is_course_upload($file,$cnum,$cdom) -Used in course context to determine if current file was uploaded to -the course (i.e., would be found in /userfiles/docs on the course's +Used in course context to determine if current file was uploaded to +the course (i.e., would be found in /userfiles/docs on the course's homeserver. input: 3 args -- filename (decluttered), course number and course domain. @@ -15138,21 +13100,15 @@ homeserver. =item * -store($storehash,$symb,$namespace,$udom,$uname,$laststore) : stores hash -permanently for this url; hashref needs to be given and should be a \%hashname; -the remaining args aren't required and if they aren't passed or are '' they will -be derived from the env (with the exception of $laststore, which is an -optional arg used when a user's submission is stored in grading). -$laststore is $version=$timestamp, where $version is the most recent version -number retrieved for the corresponding $symb in the $namespace db file, and -$timestamp is the timestamp for that transaction (UNIX time). -$laststore is currently only passed when cstore() is called by -structuretags::finalize_storage(). +store($storehash,$symb,$namespace,$udom,$uname) : stores hash permanently +for this url; hashref needs to be given and should be a \%hashname; the +remaining args aren't required and if they aren't passed or are '' they will +be derived from the env =item * -cstore($storehash,$symb,$namespace,$udom,$uname,$laststore) : same as store -but uses critical subroutine +cstore($storehash,$symb,$namespace,$udom,$uname) : same as store but +uses critical subroutine =item * @@ -15175,11 +13131,10 @@ $range should be either an integer '100' =item * -putstore($namespace,$symb,$version,$storehash,$udomain,$uname,$tolog) : +putstore($namespace,$symb,$version,$storehash,$udomain,$uname) : replaces a &store() version of data with a replacement set of data for a particular resource in a namespace passed in the $storehash hash -reference. If $tolog is true, the transaction is logged in the courselog -with an action=PUTSTORE. +reference =item * @@ -15289,7 +13244,7 @@ server ($udom and $uhome are optional) =item * -get_domain_defaults($target_domain,$ignore_cache) : returns hash with defaults +get_domain_defaults($target_domain,$ignore_cache) : returns hash with defaults for: authentication, language, quotas, timezone, date locale, and portal URL in the target domain. @@ -15323,7 +13278,7 @@ requestcourses: ability to request cours =over =item -official, unofficial, community, textbook +official, unofficial, community =back @@ -15333,7 +13288,7 @@ inststatus: types of institutional affil =over =item -inststatustypes, inststatusorder, inststatusguest +inststatustypes, inststatusorder =back @@ -15344,8 +13299,7 @@ for course's uploaded content. =over =item -canuse_pdfforms, officialcredits, unofficialcredits, textbookcredits, officialquota, unofficialquota, -communityquota, textbookquota +canuse_pdfforms, officialcredits, unofficialcredits, officialquota, unofficialquota, communityquota =back @@ -15355,7 +13309,7 @@ on your servers. =over -=item +=item remotesessions, hostedsessions =back @@ -15363,10 +13317,10 @@ remotesessions, hostedsessions =back In cases where a domain coordinator has never used the "Set Domain Configuration" -utility to create a configuration.db file on a domain's primary library server +utility to create a configuration.db file on a domain's primary library server only the following domain defaults: auth_def, auth_arg_def, lang_def -- corresponding values are authentication type (internal, krb4, krb5, -or localauth), initial password or a kerberos realm, language (e.g., en-us) -- +or localauth), initial password or a kerberos realm, language (e.g., en-us) -- will be available. Values are retrieved from cache (if current), unless the optional $ignore_cache arg is true, or from domain's configuration.db (if available), or lastly from values in lonTabs/dns_domain,tab, or lonTabs/domain.tab. @@ -15598,8 +13552,7 @@ filelocation except for hrefs =item * -declutter() : declutters URLs -- remove beginning slashes, 'res' etc. -also removes beginning /home/httpd/html unless /priv/ follows it. +declutter() : declutters URLs (remove docroot, beginning slashes, 'res' etc) =back @@ -15649,7 +13602,6 @@ userspace, probably shouldn't be called formname: same as for userfileupload() fname: filename (including subdirectories) for the file parser: if 'parse', will parse (html) file to extract references to objects, links etc. - if hashref, and context is scantron, will convert csv format to standard format allfiles: reference to hash used to store objects found by parser codebase: reference to hash used for codebases of java objects found by parser thumbwidth: width (pixels) of thumbnail to be created for uploaded image @@ -15795,8 +13747,8 @@ Returns: get_timebased_id(): -Attempts to get a unique timestamp-based suffix for use with items added to a -course via the Course Editor (e.g., folders, composite pages, +Attempts to get a unique timestamp-based suffix for use with items added to a +course via the Course Editor (e.g., folders, composite pages, group bulletin boards). Args: (first three required; six others optional) @@ -15807,24 +13759,24 @@ Args: (first three required; six others 2. keyid (alphanumeric): name of temporary locking key in hash, e.g., num, boardids -3. namespace: name of gdbm file used to store suffixes already assigned; +3. namespace: name of gdbm file used to store suffixes already assigned; file will be named nohist_namespace.db 4. cdom: domain of course; default is current course domain from %env 5. cnum: course number; default is current course number from %env -6. idtype: set to concat if an additional digit is to be appended to the +6. idtype: set to concat if an additional digit is to be appended to the unix timestamp to form the suffix, if the plain timestamp is already - in use. Default is to not do this, but simply increment the unix + in use. Default is to not do this, but simply increment the unix timestamp by 1 until a unique key is obtained. 7. who: holder of locking key; defaults to user:domain for user. -8. locktries: number of attempts to obtain a lock (sleep of 1s before +8. locktries: number of attempts to obtain a lock (sleep of 1s before retrying); default is 3. -9. maxtries: number of attempts to obtain a unique suffix; default is 20. +9. maxtries: number of attempts to obtain a unique suffix; default is 20. Returns: 500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.