--- loncom/lonnet/perl/lonnet.pm 2004/10/12 20:37:04 1.545.2.3
+++ loncom/lonnet/perl/lonnet.pm 2004/11/08 19:19:12 1.564
@@ -1,7 +1,7 @@
# The LearningOnline Network
# TCP networking package
#
-# $Id: lonnet.pm,v 1.545.2.3 2004/10/12 20:37:04 albertel Exp $
+# $Id: lonnet.pm,v 1.564 2004/11/08 19:19:12 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -36,23 +36,22 @@ use HTTP::Date;
# use Date::Parse;
use vars
qw(%perlvar %hostname %homecache %badServerCache %hostip %iphost %spareid %hostdom
- %libserv %pr %prp $metacache %packagetab %titlecache %courseresversioncache %resversioncache
+ %libserv %pr %prp %metacache %packagetab %titlecache %courseresversioncache %resversioncache
%courselogs %accesshash %userrolehash $processmarker $dumpcount
%coursedombuf %coursenumbuf %coursehombuf %coursedescrbuf %courseinstcodebuf %courseresdatacache
- %userresdatacache %usectioncache %domaindescription %domain_auth_def %domain_auth_arg_def
- %domain_lang_def %domain_city %domain_longi %domain_lati $tmpdir);
+ %userresdatacache %getsectioncache %domaindescription %domain_auth_def %domain_auth_arg_def
+ %domain_lang_def %domain_city %domain_longi %domain_lati $tmpdir $_64bit);
use IO::Socket;
use GDBM_File;
use Apache::Constants qw(:common :http);
use HTML::LCParser;
use Fcntl qw(:flock);
-use Apache::loncoursedata;
use Apache::lonlocal;
-use Storable qw(lock_store lock_nstore lock_retrieve freeze thaw);
+use Storable qw(lock_store lock_nstore lock_retrieve freeze thaw nfreeze);
use Time::HiRes qw( gettimeofday tv_interval );
-use Cache::Memcached;
my $readit;
+my $max_connection_retries = 10; # Or some such value.
=pod
@@ -117,14 +116,40 @@ sub logperm {
sub subreply {
my ($cmd,$server)=@_;
my $peerfile="$perlvar{'lonSockDir'}/$server";
- my $client=IO::Socket::UNIX->new(Peer =>"$peerfile",
- Type => SOCK_STREAM,
- Timeout => 10)
- or return "con_lost";
- print $client "$cmd\n";
- my $answer=<$client>;
- if (!$answer) { $answer="con_lost"; }
- chomp($answer);
+ #
+ # With loncnew process trimming, there's a timing hole between lonc server
+ # process exit and the master server picking up the listen on the AF_UNIX
+ # socket. In that time interval, a lock file will exist:
+
+ my $lockfile=$peerfile.".lock";
+ while (-e $lockfile) { # Need to wait for the lockfile to disappear.
+ 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.
+ #
+ # We'll give the connection a few tries before abandoning it. If
+ # connection is not possible, we'll con_lost back to the client.
+ #
+ my $client;
+ for (my $retries = 0; $retries < $max_connection_retries; $retries++) {
+ $client=IO::Socket::UNIX->new(Peer =>"$peerfile",
+ Type => SOCK_STREAM,
+ Timeout => 10);
+ if($client) {
+ last; # Connected!
+ }
+ sleep(1); # Try again later if failed connection.
+ }
+ my $answer;
+ if ($client) {
+ print $client "$cmd\n";
+ $answer=<$client>;
+ if (!$answer) { $answer="con_lost"; }
+ chomp($answer);
+ } else {
+ $answer = 'con_lost'; # Failed connection.
+ }
return $answer;
}
@@ -435,7 +460,7 @@ sub overloaderror {
if ($overload>0) {
$r->err_headers_out->{'Retry-After'}=$overload;
$r->log_error('Overload of '.$overload.' on '.$checkserver);
- return 409;
+ return 413;
}
return '';
}
@@ -772,6 +797,11 @@ sub getsection {
my ($udom,$unam,$courseid)=@_;
$courseid=~s/\_/\//g;
$courseid=~s/^(\w)/\/$1/;
+
+ my $hashid="$udom:$unam:$courseid";
+ my ($result,$cached)=&is_cached(\%getsectioncache,$hashid,'getsection');
+ if (defined($cached)) { return $result; }
+
my %Pending;
my %Expired;
#
@@ -796,29 +826,29 @@ sub getsection {
if ($key eq $courseid.'_st') { $section=''; }
my ($dummy,$end,$start)=split(/\_/,&unescape($value));
my $now=time;
- if (defined($end) && ($now > $end)) {
+ if (defined($end) && $end && ($now > $end)) {
$Expired{$end}=$section;
next;
}
- if (defined($start) && ($now < $start)) {
+ if (defined($start) && $start && ($now < $start)) {
$Pending{$start}=$section;
next;
}
- return $section;
+ return &do_cache(\%getsectioncache,$hashid,$section,'getsection');
}
#
# Presumedly there will be few matching roles from the above
# loop and the sorting time will be negligible.
if (scalar(keys(%Pending))) {
my ($time) = sort {$a <=> $b} keys(%Pending);
- return $Pending{$time};
+ return &do_cache(\%getsectioncache,$hashid,$Pending{$time},'getsection');
}
if (scalar(keys(%Expired))) {
my @sorted = sort {$a <=> $b} keys(%Expired);
my $time = pop(@sorted);
- return $Expired{$time};
+ return &do_cache(\%getsectioncache,$hashid,$Expired{$time},'getsection');
}
- return '-1';
+ return &do_cache(\%getsectioncache,$hashid,'-1','getsection');
}
@@ -874,7 +904,7 @@ sub is_cached {
# &logthis("Upping $mtime - ".$$cache{$id.'.time'}.
# "$id because of $filename");
} else {
-# &logthis("Devalidating $filename $id - ".(time-($$cache{$id.'.time'})));
+ &logthis("Devalidating $filename $id - ".(time-($$cache{$id.'.time'})));
&devalidate_cache($cache,$id,$name);
return (undef,undef);
}
@@ -1009,84 +1039,6 @@ EVALBLOCK
# &logthis("load_cache_item $name took ".(&Time::HiRes::time()-$starttime));
}
-sub devalidate_cache_new {
- my ($cache,$name,$id) = @_;
- if (0) { &Apache::lonnet::logthis("deleting $name:$id"); }
- $cache->delete(&escape($name.':'.$id));
-}
-
-my $lastone;
-my $lastname;
-sub is_cached_new {
- my ($cache,$name,$id,$debug) = @_;
- $debug=0;
- $id=&escape($name.':'.$id);
- if ($lastname eq $id) {
- if ($debug) { &Apache::lonnet::logthis("Earyl return $id of $lastone <= $lastname "); }
- return ($lastone,1);
- }
- undef($lastone);
- undef($lastname);
- my $value = $cache->get($id);
- if (!(defined($value))) {
- if ($debug) { &Apache::lonnet::logthis("getting $id is not defined"); }
- return (undef,undef);
- }
- $lastname=$id;
- if ($value eq '__undef__') {
- if ($debug) { &Apache::lonnet::logthis("getting $id is __undef__"); }
- return (undef,1);
- }
- if ($debug) { &Apache::lonnet::logthis("getting $id is $value"); }
- $lastone=$value;
- return ($value,1);
-}
-
-sub do_cache_new {
- my ($cache,$name,$id,$value,$time,$debug) = @_;
- $debug=0;
- $id=&escape($name.':'.$id);
- my $setvalue=$value;
- if (!defined($setvalue)) {
- $setvalue='__undef__';
- }
- if ($debug) { &Apache::lonnet::logthis("Setting $id to $value"); }
- $cache->set($id,$setvalue,300);
- return $value;
-}
-
-sub usection {
- my ($udom,$unam,$courseid)=@_;
- my $hashid="$udom:$unam:$courseid";
-
- my ($result,$cached)=&is_cached(\%usectioncache,$hashid,'usection');
- if (defined($cached)) { return $result; }
- $courseid=~s/\_/\//g;
- $courseid=~s/^(\w)/\/$1/;
- foreach (split(/\&/,&reply('dump:'.$udom.':'.$unam.':roles',
- &homeserver($unam,$udom)))) {
- my ($key,$value)=split(/\=/,$_);
- $key=&unescape($key);
- if ($key=~/^\Q$courseid\E(?:\/)*(\w+)*\_st$/) {
- my $section=$1;
- if ($key eq $courseid.'_st') { $section=''; }
- my ($dummy,$end,$start)=split(/\_/,&unescape($value));
- my $now=time;
- my $notactive=0;
- if ($start) {
- if ($now<$start) { $notactive=1; }
- }
- if ($end) {
- if ($now>$end) { $notactive=1; }
- }
- unless ($notactive) {
- return &do_cache(\%usectioncache,$hashid,$section,'usection');
- }
- }
- }
- return &do_cache(\%usectioncache,$hashid,'-1','usection');
-}
-
# ------------------------------------- Read an entry from a user's environment
sub userenvironment {
@@ -1920,6 +1872,7 @@ sub devalidate {
# - the student level sheet of this user in course's homespace
# - the assessment level sheet for this resource
# for this user in user's homespace
+ # - current conditional state info
my $key=$uname.':'.$udom.':';
my $status=
&del('nohist_calculatedsheets',
@@ -1934,6 +1887,7 @@ sub devalidate {
$uname.' at '.$udom.' for '.
$symb.': '.$status);
}
+ &delenv('user.state.'.$cid);
}
}
@@ -2253,6 +2207,7 @@ sub tmprestore {
}
# ----------------------------------------------------------------------- Store
+
sub store {
my ($storehash,$symb,$namespace,$domain,$stuname) = @_;
my $home='';
@@ -2266,6 +2221,7 @@ sub store {
if (!$stuname) { $stuname=$ENV{'user.name'}; }
&devalidate($symb,$stuname,$domain);
+
$symb=escape($symb);
if (!$namespace) {
unless ($namespace=$ENV{'request.course.id'}) {
@@ -2301,6 +2257,7 @@ sub cstore {
if (!$stuname) { $stuname=$ENV{'user.name'}; }
&devalidate($symb,$stuname,$domain);
+
$symb=escape($symb);
if (!$namespace) {
unless ($namespace=$ENV{'request.course.id'}) {
@@ -2343,7 +2300,6 @@ sub restore {
if (!$domain) { $domain=$ENV{'user.domain'}; }
if (!$stuname) { $stuname=$ENV{'user.name'}; }
if (!$home) { $home=$ENV{'user.home'}; }
-
my $answer=&reply("restore:$domain:$stuname:$namespace:$symb","$home");
my %returnhash=();
@@ -2513,7 +2469,6 @@ sub rolesinit {
my $author=0;
foreach (keys %allroles) {
%thesepriv=();
- if (($_!~/^st/) && ($_!~/^ta/) && ($_!~/^cm/)) { $adv=1; }
if (($_=~/^au/) || ($_=~/^ca/)) { $author=1; }
foreach (split(/:/,$allroles{$_})) {
if ($_ ne '') {
@@ -2525,6 +2480,7 @@ sub rolesinit {
$thesepriv{$privilege}.=$restrictions;
}
}
+ if ($thesepriv{'adv'} eq 'F') { $adv=1; }
}
}
$thesestr='';
@@ -2559,7 +2515,7 @@ sub get {
my %returnhash=();
my $i=0;
foreach (@$storearr) {
- $returnhash{$_}=unescape($pairs[$i]);
+ $returnhash{$_}=&thaw_unescape($pairs[$i]);
$i++;
}
return %returnhash;
@@ -2598,7 +2554,7 @@ sub dump {
my %returnhash=();
foreach (@pairs) {
my ($key,$value)=split(/=/,$_);
- $returnhash{unescape($key)}=unescape($value);
+ $returnhash{unescape($key)}=&thaw_unescape($value);
}
return %returnhash;
}
@@ -2644,7 +2600,7 @@ sub currentdump {
my ($key,$value)=split(/=/,$_);
my ($symb,$param) = split(/:/,$key);
$returnhash{&unescape($symb)}->{&unescape($param)} =
- &unescape($value);
+ &thaw_unescape($value);
}
}
return %returnhash;
@@ -2710,7 +2666,7 @@ sub put {
my $uhome=&homeserver($uname,$udomain);
my $items='';
foreach (keys %$storehash) {
- $items.=&escape($_).'='.&escape($$storehash{$_}).'&';
+ $items.=&escape($_).'='.&freeze_escape($$storehash{$_}).'&';
}
$items=~s/\&$//;
return &reply("put:$udomain:$uname:$namespace:$items",$uhome);
@@ -2749,7 +2705,7 @@ sub cput {
my $uhome=&homeserver($uname,$udomain);
my $items='';
foreach (keys %$storehash) {
- $items.=escape($_).'='.escape($$storehash{$_}).'&';
+ $items.=escape($_).'='.&freeze_escape($$storehash{$_}).'&';
}
$items=~s/\&$//;
return &critical("put:$udomain:$uname:$namespace:$items",$uhome);
@@ -2772,7 +2728,7 @@ sub eget {
my %returnhash=();
my $i=0;
foreach (@$storearr) {
- $returnhash{$_}=unescape($pairs[$i]);
+ $returnhash{$_}=&thaw_unescape($pairs[$i]);
$i++;
}
return %returnhash;
@@ -2830,12 +2786,14 @@ sub allowed {
}
# Free bre access to user's own portfolio contents
- $uri=~m:([^/]+)/([^/]+)/([^/]+)/([^/]+)/:;
- if (('uploaded' eq $1)&&($ENV{'user.name'} eq $3) && ($ENV{'user.domain'} eq $2) && ('portfolio' eq $4)) {
+ my ($space,$domain,$name,$dir)=split('/',$uri);
+ if (('uploaded' eq $space) && ($ENV{'user.name'} eq $name) &&
+ ($ENV{'user.domain'} eq $domain) && ('portfolio' eq $dir)) {
return 'F';
}
# Free bre to public access
+
if ($priv eq 'bre') {
my $copyright=&metadata($uri,'copyright');
if (($copyright eq 'public') && (!$ENV{'request.course.id'})) {
@@ -3235,8 +3193,10 @@ sub log_query {
sub fetch_enrollment_query {
my ($context,$affiliatesref,$replyref,$dom,$cnum) = @_;
my $homeserver;
+ my $maxtries = 1;
if ($context eq 'automated') {
$homeserver = $perlvar{'lonHostID'};
+ $maxtries = 10; # will wait for up to 2000s for retrieval of classlist data before timeout
} else {
$homeserver = &homeserver($cnum,$dom);
}
@@ -3254,8 +3214,13 @@ sub fetch_enrollment_query {
return 'error: '.$queryid;
}
my $reply = &get_query_reply($queryid);
+ my $tries = 1;
+ while (($reply=~/^timeout/) && ($tries < $maxtries)) {
+ $reply = &get_query_reply($queryid);
+ $tries ++;
+ }
if ( ($reply =~/^timeout/) || ($reply =~/^error/) ) {
- &logthis('fetch_enrollment_query error: '.$reply.' for '.$dom.' '.$ENV{'user.name'}.' for '.$queryid.' context: '.$context.' '.$cnum);
+ &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 ($homeserver eq $perlvar{'lonHostID'}) {
@@ -3662,8 +3627,7 @@ sub modify_student_enrollment {
$gene = $tmp{'generation'} if (!defined($gene) || $gene eq '');
$uid = $tmp{'id'} if (!defined($uid) || $uid eq '');
}
- my $fullname = &Apache::loncoursedata::ProcessFullName($last,$gene,
- $first,$middle);
+ my $fullname = &format_name($first,$middle,$last,$gene,'lastname');
my $reply=cput('classlist',
{"$uname:$udom" =>
join(':',$end,$start,$uid,$usec,$fullname,$type,$locktype) },
@@ -3680,6 +3644,25 @@ sub modify_student_enrollment {
return &assignrole($udom,$uname,$uurl,'st',$end,$start);
}
+sub format_name {
+ my ($firstname,$middlename,$lastname,$generation,$first)=@_;
+ my $name;
+ if ($first ne 'lastname') {
+ $name=$firstname.' '.$middlename.' '.$lastname.' '.$generation;
+ } else {
+ if ($lastname=~/\S/) {
+ $name.= $lastname.' '.$generation.', '.$firstname.' '.$middlename;
+ $name=~s/\s+,/,/;
+ } else {
+ $name.= $firstname.' '.$middlename.' '.$generation;
+ }
+ }
+ $name=~s/^\s+//;
+ $name=~s/\s+$//;
+ $name=~s/\s+/ /g;
+ return $name;
+}
+
# ------------------------------------------------- Write to course preferences
sub writecoursepref {
@@ -3798,6 +3781,72 @@ sub diskusage {
return $listing;
}
+# ------------------------------------------------------------- Mark as Read Only
+
+sub mark_as_readonly {
+ my ($domain,$user,$files,$what) = @_;
+ my %current_permissions = &Apache::lonnet::dump('file_permissions',$domain,$user);
+ foreach my $file (@{$files}) {
+ push(@{$current_permissions{$file}},$what);
+ }
+ &Apache::lonnet::put('file_permissions',\%current_permissions,$domain,$user);
+ return;
+}
+
+#--------------------------------------------------------------Get Marked as Read Only
+
+sub get_marked_as_readonly {
+ my ($domain,$user,$what) = @_;
+ my %current_permissions = &Apache::lonnet::dump('file_permissions',$domain,$user);
+ my @readonly_files;
+ while (my ($file_name,$value) = each(%current_permissions)) {
+ &logthis("found $file_name");
+ if (ref($value) eq "ARRAY"){
+ &logthis("found array");
+ foreach my $stored_what (@{$value}) {
+ if ($stored_what eq $what) {
+ push(@readonly_files, $file_name);
+ &logthis("defined pushed $file_name");
+ } elsif (!defined($what)) {
+ push(@readonly_files, $file_name);
+ &logthis("undef pushed $file_name");
+ }
+ }
+ }
+ }
+ return @readonly_files;
+}
+
+# ------------------------------------------------------------ Unmark as Read Only
+
+sub unmark_as_readonly {
+ # unmarks all files locked by $what
+ # for portfolio submissions, $what contains $crsid and $symb
+ my ($domain,$user,$what) = @_;
+ my %current_permissions = &Apache::lonnet::dump('file_permissions',$domain,$user);
+ my @readonly_files = &Apache::lonnet::get_marked_as_readonly($domain,$user,$what);
+ foreach my $file(@readonly_files){
+ my $current_locks = $current_permissions{$file};
+ my @new_locks;
+ my @del_keys;
+ if (ref($current_locks) eq "ARRAY"){
+ foreach my $locker (@{$current_locks}) {
+ unless ($locker eq $what) {
+ push(@new_locks, $what);
+ }
+ }
+ if (@new_locks > 0) {
+ $current_permissions{$file} = \@new_locks;
+ } else {
+ push(@del_keys, $file);
+ &Apache::lonnet::del('file_permissions',\@del_keys, $domain, $user);
+ delete $current_permissions{$file};
+ }
+ }
+ }
+ &Apache::lonnet::put('file_permissions',\%current_permissions,$domain,$user);
+ return;
+}
# ------------------------------------------------------------ Directory lister
@@ -3907,6 +3956,9 @@ sub GetFileTimestamp {
sub directcondval {
my $number=shift;
+ if (!defined($ENV{'user.state.'.$ENV{'request.course.id'}})) {
+ &Apache::lonuserstate::evalstate();
+ }
if ($ENV{'user.state.'.$ENV{'request.course.id'}}) {
return substr($ENV{'user.state.'.$ENV{'request.course.id'}},$number,1);
} else {
@@ -4151,7 +4203,7 @@ sub EXT {
$section=$ENV{'request.course.sec'};
} else {
if (! defined($usection)) {
- $section=&usection($udom,$uname,$courseid);
+ $section=&getsection($udom,$uname,$courseid);
} else {
$section = $usection;
}
@@ -4301,7 +4353,6 @@ sub add_prefix_and_part {
# ---------------------------------------------------------------- Get metadata
-my %metaentry;
sub metadata {
my ($uri,$what,$liburi,$prefix,$depthcount)=@_;
$uri=&declutter($uri);
@@ -4321,29 +4372,28 @@ sub metadata {
# Everything is cached by the main uri, libraries are never directly cached
#
if (!defined($liburi)) {
- my ($result,$cached)=&is_cached_new($metacache,'meta',$uri);
+ my ($result,$cached)=&is_cached(\%metacache,$uri,'meta');
if (defined($cached)) { return $result->{':'.$what}; }
}
{
#
# Is this a recursive call for a library?
#
-# if (! exists($metacache{$uri})) {
-# $metacache{$uri}={};
-# }
+ if (! exists($metacache{$uri})) {
+ $metacache{$uri}={};
+ }
if ($liburi) {
$liburi=&declutter($liburi);
$filename=$liburi;
} else {
- &devalidate_cache_new($metacache,'meta',$uri);
- undef(%metaentry);
+ &devalidate_cache(\%metacache,$uri,'meta');
}
my %metathesekeys=();
unless ($filename=~/\.meta$/) { $filename.='.meta'; }
my $metastring;
if ($uri !~ m|^uploaded/|) {
my $file=&filelocation('',&clutter($filename));
- #push(@{$metaentry{$uri.'.file'}},$file);
+ push(@{$metacache{$uri.'.file'}},$file);
$metastring=&getfile($file);
}
my $parser=HTML::LCParser->new(\$metastring);
@@ -4360,10 +4410,10 @@ sub metadata {
if (defined($token->[2]->{'id'})) {
$keyroot.='_'.$token->[2]->{'id'};
}
- if ($metaentry{':packages'}) {
- $metaentry{':packages'}.=','.$package.$keyroot;
+ if ($metacache{$uri}->{':packages'}) {
+ $metacache{$uri}->{':packages'}.=','.$package.$keyroot;
} else {
- $metaentry{':packages'}=$package.$keyroot;
+ $metacache{$uri}->{':packages'}=$package.$keyroot;
}
foreach (keys %packagetab) {
my $part=$keyroot;
@@ -4385,14 +4435,14 @@ sub metadata {
if ($subp eq 'display') {
$value.=' [Part: '.$part.']';
}
- $metaentry{':'.$unikey.'.part'}=$part;
+ $metacache{$uri}->{':'.$unikey.'.part'}=$part;
$metathesekeys{$unikey}=1;
- unless (defined($metaentry{':'.$unikey.'.'.$subp})) {
- $metaentry{':'.$unikey.'.'.$subp}=$value;
+ unless (defined($metacache{$uri}->{':'.$unikey.'.'.$subp})) {
+ $metacache{$uri}->{':'.$unikey.'.'.$subp}=$value;
}
- if (defined($metaentry{':'.$unikey.'.default'})) {
- $metaentry{':'.$unikey}=
- $metaentry{':'.$unikey.'.default'};
+ if (defined($metacache{$uri}->{':'.$unikey.'.default'})) {
+ $metacache{$uri}->{':'.$unikey}=
+ $metacache{$uri}->{':'.$unikey.'.default'};
}
}
}
@@ -4425,7 +4475,7 @@ sub metadata {
foreach (sort(split(/\,/,&metadata($uri,'keys',
$location,$unikey,
$depthcount+1)))) {
- $metaentry{':'.$_}=$metaentry{':'.$_};
+ $metacache{$uri}->{':'.$_}=$metacache{$uri}->{':'.$_};
$metathesekeys{$_}=1;
}
}
@@ -4436,18 +4486,18 @@ sub metadata {
}
$metathesekeys{$unikey}=1;
foreach (@{$token->[3]}) {
- $metaentry{':'.$unikey.'.'.$_}=$token->[2]->{$_};
+ $metacache{$uri}->{':'.$unikey.'.'.$_}=$token->[2]->{$_};
}
my $internaltext=&HTML::Entities::decode($parser->get_text('/'.$entry));
- my $default=$metaentry{':'.$unikey.'.default'};
+ my $default=$metacache{$uri}->{':'.$unikey.'.default'};
if ( $internaltext =~ /^\s*$/ && $default !~ /^\s*$/) {
# only ws inside the tag, and not in default, so use default
# as value
- $metaentry{':'.$unikey}=$default;
+ $metacache{$uri}->{':'.$unikey}=$default;
} else {
# either something interesting inside the tag or default
# uninteresting
- $metaentry{':'.$unikey}=$internaltext;
+ $metacache{$uri}->{':'.$unikey}=$internaltext;
}
# end of not-a-package not-a-library import
}
@@ -4464,7 +4514,7 @@ sub metadata {
&metadata_create_package_def($uri,$key,'extension_'.$extension,
\%metathesekeys);
}
- if (!exists($metaentry{':packages'})) {
+ if (!exists($metacache{$uri}->{':packages'})) {
foreach my $key (sort(keys(%packagetab))) {
#no specific packages well let's get default then
if ($key!~/^default&/) { next; }
@@ -4473,31 +4523,31 @@ sub metadata {
}
}
# are there custom rights to evaluate
- if ($metaentry{':copyright'} eq 'custom') {
+ if ($metacache{$uri}->{':copyright'} eq 'custom') {
#
# Importing a rights file here
#
unless ($depthcount) {
- my $location=$metaentry{':customdistributionfile'};
+ my $location=$metacache{$uri}->{':customdistributionfile'};
my $dir=$filename;
$dir=~s|[^/]*$||;
$location=&filelocation($dir,$location);
foreach (sort(split(/\,/,&metadata($uri,'keys',
$location,'_rights',
$depthcount+1)))) {
- #$metaentry{':'.$_}=$metacache{$uri}->{':'.$_};
+ $metacache{$uri}->{':'.$_}=$metacache{$uri}->{':'.$_};
$metathesekeys{$_}=1;
}
}
}
- $metaentry{':keys'}=join(',',keys %metathesekeys);
- &metadata_generate_part0(\%metathesekeys,\%metaentry,$uri);
- $metaentry{':allpossiblekeys'}=join(',',keys %metathesekeys);
- &do_cache_new($metacache,'meta',$uri,\%metaentry);
+ $metacache{$uri}->{':keys'}=join(',',keys %metathesekeys);
+ &metadata_generate_part0(\%metathesekeys,$metacache{$uri},$uri);
+ $metacache{$uri}->{':allpossiblekeys'}=join(',',keys %metathesekeys);
+ &do_cache(\%metacache,$uri,$metacache{$uri},'meta');
# this is the end of "was not already recently cached
}
- return $metaentry{':'.$what};
+ return $metacache{$uri}->{':'.$what};
}
sub metadata_create_package_def {
@@ -4505,22 +4555,22 @@ sub metadata_create_package_def {
my ($pack,$name,$subp)=split(/\&/,$key);
if ($subp eq 'default') { next; }
- if (defined($metaentry{':packages'})) {
- $metaentry{':packages'}.=','.$package;
+ if (defined($metacache{$uri}->{':packages'})) {
+ $metacache{$uri}->{':packages'}.=','.$package;
} else {
- $metaentry{':packages'}=$package;
+ $metacache{$uri}->{':packages'}=$package;
}
my $value=$packagetab{$key};
my $unikey;
$unikey='parameter_0_'.$name;
- $metaentry{':'.$unikey.'.part'}=0;
+ $metacache{$uri}->{':'.$unikey.'.part'}=0;
$$metathesekeys{$unikey}=1;
- unless (defined($metaentry{':'.$unikey.'.'.$subp})) {
- $metaentry{':'.$unikey.'.'.$subp}=$value;
+ unless (defined($metacache{$uri}->{':'.$unikey.'.'.$subp})) {
+ $metacache{$uri}->{':'.$unikey.'.'.$subp}=$value;
}
- if (defined($metaentry{':'.$unikey.'.default'})) {
- $metaentry{':'.$unikey}=
- $metaentry{':'.$unikey.'.default'};
+ if (defined($metacache{$uri}->{':'.$unikey.'.default'})) {
+ $metacache{$uri}->{':'.$unikey}=
+ $metacache{$uri}->{':'.$unikey.'.default'};
}
}
@@ -4808,6 +4858,7 @@ sub numval {
$txt=~tr/U-Z/0-5/;
$txt=~tr/u-z/0-5/;
$txt=~s/\D//g;
+ if ($_64bit) { if ($txt > 2**32) { return -1; } }
return int($txt);
}
@@ -4823,6 +4874,7 @@ sub numval2 {
my @txts=split(/(\d\d\d\d\d\d\d\d\d)/,$txt);
my $total;
foreach my $val (@txts) { $total+=$val; }
+ if ($_64bit) { if ($total > 2**32) { return -1; } }
return int($total);
}
@@ -4839,10 +4891,16 @@ sub get_rand_alg {
return &latest_rnd_algorithm_id();
}
+sub validCODE {
+ my ($CODE)=@_;
+ if (defined($CODE) && $CODE ne '' && $CODE =~ /^\w+$/) { return 1; }
+ return 0;
+}
+
sub getCODE {
- if (defined($ENV{'form.CODE'})) { return $ENV{'form.CODE'}; }
+ if (&validCODE($ENV{'form.CODE'})) { return $ENV{'form.CODE'}; }
if (defined($Apache::lonhomework::parsing_a_problem) &&
- defined($Apache::lonhomework::history{'resource.CODE'})) {
+ &validCODE($Apache::lonhomework::history{'resource.CODE'})) {
return $Apache::lonhomework::history{'resource.CODE'};
}
return undef;
@@ -4884,6 +4942,7 @@ sub rndseed_32bit {
my $num=$symbseed+$nameseed+$domainseed+$courseseed+$namechck+$symbchck;
#&Apache::lonxml::debug("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck");
#&Apache::lonxml::debug("rndseed :$num:$symb");
+ if ($_64bit) { $num=(($num<<32)>>32); }
return $num;
}
}
@@ -4904,6 +4963,8 @@ sub rndseed_64bit {
my $num2=$nameseed+$domainseed+$courseseed;
#&Apache::lonxml::debug("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck");
#&Apache::lonxml::debug("rndseed :$num:$symb");
+ if ($_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); }
+ if ($_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); }
return "$num1,$num2";
}
}
@@ -4947,7 +5008,9 @@ sub rndseed_64bit3 {
my $num1=$symbchck+$symbseed+$namechck;
my $num2=$nameseed+$domainseed+$courseseed;
#&Apache::lonxml::debug("$symbseed:$nameseed;$domainseed|$courseseed;$namechck:$symbchck");
- #&Apache::lonxml::debug("rndseed :$num:$symb");
+ #&Apache::lonxml::debug("rndseed :$num1:$num2:$_64bit");
+ if ($_64bit) { $num1=(($num1<<32)>>32); $num2=(($num2<<32)>>32); }
+
return "$num1:$num2";
}
}
@@ -4965,6 +5028,8 @@ sub rndseed_CODE_64bit {
my $num2=$CODEseed+$courseseed+$symbchck;
#&Apache::lonxml::debug("$symbseed:$CODEchck|$CODEseed:$courseseed:$symbchck");
#&Apache::lonxml::debug("rndseed :$num1:$num2:$symb");
+ if ($_64bit) { $num1=(($num1<<32)>>32); }
+ if ($_64bit) { $num2=(($num2<<32)>>32); }
return "$num1:$num2";
}
}
@@ -5129,13 +5194,15 @@ sub repcopy_userfile {
sub tokenwrapper {
my $uri=shift;
- $uri=~s/^http\:\/\/([^\/]+)//;
- $uri=~s/^\///;
+ $uri=~s|^http\://([^/]+)||;
+ $uri=~s|^/||;
$ENV{'user.environment'}=~/\/([^\/]+)\.id/;
my $token=$1;
- if ($uri=~/^uploaded\/([^\/]+)\/([^\/]+)\/([^\/]+)(\?\.*)*$/) {
- &appenv('userfile.'.$1.'/'.$2.'/'.$3 => $ENV{'request.course.id'});
- return 'http://'.$hostname{ &homeserver($2,$1)}.'/'.$uri.
+ my (undef,$udom,$uname,$file)=split('/',$uri,4);
+ if ($udom && $uname && $file) {
+ $file=~s|(\?\.*)*$||;
+ &appenv("userfile.$udom/$uname/$file" => $ENV{'request.course.id'});
+ return 'http://'.$hostname{ &homeserver($uname,$udom)}.'/'.$uri.
(($uri=~/\?/)?'&':'?').'token='.$token.
'&tokenissued='.$perlvar{'lonHostID'};
} else {
@@ -5268,6 +5335,15 @@ sub clutter {
return $thisfn;
}
+sub freeze_escape {
+ my ($value)=@_;
+ if (ref($value)) {
+ $value=&nfreeze($value);
+ return '__FROZEN__'.&escape($value);
+ }
+ return &escape($value);
+}
+
# -------------------------------------------------------- Escape Special Chars
sub escape {
@@ -5284,6 +5360,16 @@ sub unescape {
return $str;
}
+sub thaw_unescape {
+ my ($value)=@_;
+ if ($value =~ /^__FROZEN__/) {
+ substr($value,0,10,undef);
+ $value=&unescape($value);
+ return &thaw($value);
+ }
+ return &unescape($value);
+}
+
sub mod_perl_version {
if (defined($perlvar{'MODPERL2'})) {
return 2;
@@ -5303,13 +5389,13 @@ sub goodbye {
#not converted to using infrastruture and probably shouldn't be
&logthis(sprintf("%-20s is %s",'%badServerCache',scalar(%badServerCache)));
#converted
-# &logthis(sprintf("%-20s is %s",'%metacache',scalar(%metacache)));
+ &logthis(sprintf("%-20s is %s",'%metacache',scalar(%metacache)));
&logthis(sprintf("%-20s is %s",'%homecache',scalar(%homecache)));
&logthis(sprintf("%-20s is %s",'%titlecache',scalar(%titlecache)));
&logthis(sprintf("%-20s is %s",'%courseresdatacache',scalar(%courseresdatacache)));
#1.1 only
&logthis(sprintf("%-20s is %s",'%userresdatacache',scalar(%userresdatacache)));
- &logthis(sprintf("%-20s is %s",'%usectioncache',scalar(%usectioncache)));
+ &logthis(sprintf("%-20s is %s",'%getsectioncache',scalar(%getsectioncache)));
&logthis(sprintf("%-20s is %s",'%courseresversioncache',scalar(%courseresversioncache)));
&logthis(sprintf("%-20s is %s",'%resversioncache',scalar(%resversioncache)));
&flushcourselogs();
@@ -5456,7 +5542,7 @@ BEGIN {
}
-$metacache=new Cache::Memcached({'servers'=>['127.0.0.1:11211']});
+%metacache=();
$processmarker='_'.time.'_'.$perlvar{'lonHostID'};
$dumpcount=0;
@@ -5464,6 +5550,12 @@ $dumpcount=0;
&logtouch();
&logthis('INFO: Read configuration');
$readit=1;
+ {
+ use integer;
+ my $test=(2**32)+1;
+ if ($test != 0) { $_64bit=1; }
+ &logthis(" Detected 64bit platform ($_64bit)");
+ }
}
}
@@ -5691,8 +5783,8 @@ X
B: get user privileges
=item *
-X
-B: finds the section of student in the
+X
+B: finds the section of student in the
course $cname, return section name/number or '' for "not in course"
and '-1' for "no section"