--- loncom/lonnet/perl/lonnet.pm 2004/09/20 20:14:14 1.523.2.5 +++ loncom/lonnet/perl/lonnet.pm 2004/08/25 16:03:17 1.532 @@ -1,7 +1,7 @@ # The LearningOnline Network # TCP networking package # -# $Id: lonnet.pm,v 1.523.2.5 2004/09/20 20:14:14 albertel Exp $ +# $Id: lonnet.pm,v 1.532 2004/08/25 16:03:17 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -50,7 +50,7 @@ use Fcntl qw(:flock); use Apache::loncoursedata; use Apache::lonlocal; use Storable qw(lock_store lock_nstore lock_retrieve freeze thaw); -use Time::HiRes qw( gettimeofday tv_interval ); +use Time::HiRes(); my $readit; =pod @@ -826,12 +826,10 @@ my $disk_caching_disabled=1; sub devalidate_cache { my ($cache,$id,$name) = @_; delete $$cache{$id.'.time'}; - delete $$cache{$id.'.file'}; delete $$cache{$id}; - if (1 || $disk_caching_disabled) { return; } + if ($disk_caching_disabled) { return; } my $filename=$perlvar{'lonDaemons'}.'/tmp/lonnet_internal_cache_'.$name.".db"; - if (!-e $filename) { return; } - open(DB,">$filename.lock"); + open(DB,"$filename.lock"); flock(DB,LOCK_EX); my %hash; if (tie(%hash,'GDBM_File',$filename,&GDBM_WRCREAT(),0640)) { @@ -858,32 +856,16 @@ sub is_cached { my ($cache,$id,$name,$time) = @_; if (!$time) { $time=300; } if (!exists($$cache{$id.'.time'})) { - &load_cache_item($cache,$name,$id,$time); + &load_cache_item($cache,$name,$id); } if (!exists($$cache{$id.'.time'})) { # &logthis("Didn't find $id"); return (undef,undef); } else { if (time-($$cache{$id.'.time'})>$time) { - if (exists($$cache{$id.'.file'})) { - foreach my $filename (@{ $$cache{$id.'.file'} }) { - my $mtime=(stat($filename))[9]; - #+1 is to take care of edge effects - if ($mtime && (($mtime+1) < ($$cache{$id.'.time'}))) { -# &logthis("Upping $mtime - ".$$cache{$id.'.time'}. -# "$id because of $filename"); - } else { - &logthis("Devalidating $filename $id - ".(time-($$cache{$id.'.time'}))); - &devalidate_cache($cache,$id,$name); - return (undef,undef); - } - } - $$cache{$id.'.time'}=time; - } else { -# &logthis("Devalidating $id - ".time-($$cache{$id.'.time'})); - &devalidate_cache($cache,$id,$name); - return (undef,undef); - } +# &logthis("Devalidating $id - ".time-($$cache{$id.'.time'})); + &devalidate_cache($cache,$id,$name); + return (undef,undef); } } return ($$cache{$id},1); @@ -899,69 +881,44 @@ sub do_cache { $$cache{$id}; } -my %do_save_item; -my %do_save; sub save_cache_item { my ($cache,$name,$id)=@_; if ($disk_caching_disabled) { return; } - $do_save{$name}=$cache; - if (!exists($do_save_item{$name})) { $do_save_item{$name}={} } - $do_save_item{$name}->{$id}=1; - return; -} - -sub save_cache { - if ($disk_caching_disabled) { return; } - my ($cache,$name,$id); - foreach $name (keys(%do_save)) { - $cache=$do_save{$name}; - - my $starttime=&Time::HiRes::time(); - &logthis("Saving :$name:"); - my %hash; - my $filename=$perlvar{'lonDaemons'}.'/tmp/lonnet_internal_cache_'.$name.".db"; - open(DB,">$filename.lock"); - flock(DB,LOCK_EX); - if (tie(%hash,'GDBM_File',$filename,&GDBM_WRCREAT(),0640)) { - foreach $id (keys(%{ $do_save_item{$name} })) { - eval <<'EVALBLOCK'; - $hash{$id.'.time'}=$$cache{$id.'.time'}; - $hash{$id}=freeze({'item'=>$$cache{$id}}); - if (exists($$cache{$id.'.file'})) { - $hash{$id.'.file'}=freeze({'item'=>$$cache{$id.'.file'}}); - } + my $starttime=&Time::HiRes::time(); +# &logthis("Saving :$name:$id"); + my %hash; + my $filename=$perlvar{'lonDaemons'}.'/tmp/lonnet_internal_cache_'.$name.".db"; + open(DB,"$filename.lock"); + flock(DB,LOCK_EX); + if (tie(%hash,'GDBM_File',$filename,&GDBM_WRCREAT(),0640)) { + eval <<'EVALBLOCK'; + $hash{$id.'.time'}=$$cache{$id.'.time'}; + $hash{$id}=freeze({'item'=>$$cache{$id}}); EVALBLOCK - if ($@) { - &logthis("save_cache blew up :$@:$name"); - unlink($filename); - last; - } - } - } else { - if (-e $filename) { - &logthis("Unable to tie hash (save cache): $name ($!)"); - unlink($filename); - } + if ($@) { + &logthis("save_cache blew up :$@:$name"); + unlink($filename); + } + } else { + if (-e $filename) { + &logthis("Unable to tie hash (save cache item): $name ($!)"); + unlink($filename); } - untie(%hash); - flock(DB,LOCK_UN); - close(DB); - &logthis("save_cache $name took ".(&Time::HiRes::time()-$starttime)); } - undef(%do_save); - undef(%do_save_item); - + untie(%hash); + flock(DB,LOCK_UN); + close(DB); +# &logthis("save_cache_item $name took ".(&Time::HiRes::time()-$starttime)); } sub load_cache_item { - my ($cache,$name,$id,$time)=@_; + my ($cache,$name,$id)=@_; if ($disk_caching_disabled) { return; } my $starttime=&Time::HiRes::time(); # &logthis("Before Loading $name for $id size is ".scalar(%$cache)); my %hash; my $filename=$perlvar{'lonDaemons'}.'/tmp/lonnet_internal_cache_'.$name.".db"; - if (!-e $filename) { return; } - open(DB,">$filename.lock"); + open(DB,"$filename.lock"); flock(DB,LOCK_SH); if (tie(%hash,'GDBM_File',$filename,&GDBM_READER(),0640)) { eval <<'EVALBLOCK'; @@ -978,17 +935,9 @@ sub load_cache_item { } # &logthis("Initial load: $count"); } else { - if (($$cache{$id.'.time'}+$time) < time) { - $$cache{$id.'.time'}=$hash{$id.'.time'}; - { - my $hashref=thaw($hash{$id}); - $$cache{$id}=$hashref->{'item'}; - } - if (exists($hash{$id.'.file'})) { - my $hashref=thaw($hash{$id.'.file'}); - $$cache{$id.'.file'}=$hashref->{'item'}; - } - } + my $hashref=thaw($hash{$id}); + $$cache{$id}=$hashref->{'item'}; + $$cache{$id.'.time'}=$hash{$id.'.time'}; } EVALBLOCK if ($@) { @@ -1184,10 +1133,10 @@ sub ssi_body { my ($filelink,%form)=@_; my $output=($filelink=~/^http\:/?&externalssi($filelink): &ssi($filelink,%form)); - $output=~s/^.*?\
]*\>//si; - $output=~s/(.*)\<\/body\s*\>.*?$/$1/si; $output=~ s/\/\/ BEGIN LON\-CAPA Internal.+\/\/ END LON\-CAPA Internal\s//gs; + $output=~s/^.*?\]*\>//si; + $output=~s/(.*)\<\/body\s*\>.*?$/$1/si; return $output; } @@ -1320,10 +1269,8 @@ sub process_coursefile { # input: name of form element, coursedoc=1 means this is for the course # output: url of file in userspace -sub userfileupload { - my ($formname,$coursedoc,$subdir)=@_; - if (!defined($subdir)) { $subdir='unknown'; } - my $fname=$ENV{'form.'.$formname.'.filename'}; +sub clean_filename { + my ($fname)=@_; # Replace Windows backslashes by forward slashes $fname=~s/\\/\//g; # Get rid of everything but the actual filename @@ -1332,6 +1279,14 @@ sub userfileupload { $fname=~s/\s+/\_/g; # Replace all other weird characters by nothing $fname=~s/[^\w\.\-]//g; + return $fname; +} + +sub userfileupload { + my ($formname,$coursedoc,$subdir)=@_; + if (!defined($subdir)) { $subdir='unknown'; } + my $fname=$ENV{'form.'.$formname.'.filename'}; + $fname=&clean_filename($fname); # See if there is anything left unless ($fname) { return 'error: no uploaded file'; } chop($ENV{'form.'.$formname}); @@ -1425,6 +1380,19 @@ sub removeuserfile { return &reply("removeuserfile:$docudom/$docuname/$fname",$home); } +sub mkdiruserfile { + my ($docuname,$docudom,$dir)=@_; + my $home=&homeserver($docuname,$docudom); + return &reply("mkdiruserfile:".&escape("$docudom/$docuname/$dir"),$home); +} + +sub renameuserfile { + my ($docuname,$docudom,$old,$new)=@_; + my $home=&homeserver($docuname,$docudom); + return &reply("renameuserfile:$docudom:$docuname:".&escape("$old").':'. + &escape("$new"),$home); +} + # ------------------------------------------------------------------------- Log sub log { @@ -2644,6 +2612,30 @@ sub put { return &reply("put:$udomain:$uname:$namespace:$items",$uhome); } +# ---------------------------------------------------------- putstore interface + +sub putstore { + my ($namespace,$storehash,$udomain,$uname)=@_; + if (!$udomain) { $udomain=$ENV{'user.domain'}; } + if (!$uname) { $uname=$ENV{'user.name'}; } + my $uhome=&homeserver($uname,$udomain); + my $items=''; + my %allitems = (); + foreach (keys %$storehash) { + if ($_ =~ m/^([^\:]+):([^\:]+):([^\:]+)$/) { + my $key = $1.':keys:'.$2; + $allitems{$key} .= $3.':'; + } + $items.=$_.'='.&escape($$storehash{$_}).'&'; + } + foreach (keys %allitems) { + $allitems{$_} =~ s/\:$//; + $items.= $_.'='.$allitems{$_}.'&'; + } + $items=~s/\&$//; + return &reply("put:$udomain:$uname:$namespace:$items",$uhome); +} + # ------------------------------------------------------ critical put interface sub cput { @@ -2726,8 +2718,8 @@ sub allowed { if (defined($ENV{'allowed.'.$priv})) { return $ENV{'allowed.'.$priv}; } # Free bre access to adm and meta resources - - if ((($uri=~/^adm\//) || ($uri=~/\.meta$/)) && ($priv eq 'bre')) { + if (((($uri=~/^adm\//) && ($uri !~ m|/bulletinboard$|)) + || ($uri=~/\.meta$/)) && ($priv eq 'bre')) { return 'F'; } @@ -3146,9 +3138,14 @@ sub fetch_enrollment_query { $cmd = &escape($cmd); my $query = 'fetchenrollment'; my $queryid=&reply("querysend:".$query.':'.$dom.':'.$ENV{'user.name'}.':'.$cmd,$homeserver); - unless ($queryid=~/^\Q$host\E\_/) { return 'error: '.$queryid; } + unless ($queryid=~/^\Q$host\E\_/) { + &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); - unless ( ($reply =~/^timeout/) || ($reply =~/^error/) ) { + if ( ($reply =~/^timeout/) || ($reply =~/^error/) ) { + &logthis('fetch_enrollment_query error: '.$reply.' for '.$dom.' '.$ENV{'user.name'}.' for '.$queryid.' context: '.$context.' '.$cnum); + } else { my @responses = split/:/,$reply; if ($homeserver eq $perlvar{'lonHostID'}) { foreach (@responses) { @@ -3165,10 +3162,14 @@ sub fetch_enrollment_query { my $filename = $dom.'_'.$key.'_'.$_.'_classlist.xml'; my $destname = $pathname.'/'.$filename; my $xml_classlist = &reply("autoretrieve:".$filename,$homeserver); - unless ($xml_classlist =~ /^error/) { + if ($xml_classlist =~ /^error/) { + &logthis('fetch_enrollment_query - autoretrieve error: '.$xml_classlist.' for '.$filename.' from server: '.$homeserver.' '.$context.' '.$cnum); + } else { if ( open(FILE,">$destname") ) { print FILE &unescape($xml_classlist); close(FILE); + } else { + &logthis('fetch_enrollment_query - error opening classlist file '.$destname.' '.$context.' '.$cnum); } } } @@ -4047,14 +4048,11 @@ sub EXT { my $section; if (defined($courseid) && $courseid eq $ENV{'request.course.id'}) { - if (!$symbparm) { $symbparm=&symbread(); } - } - if ($symbparm && defined($courseid) && - $courseid eq $ENV{'request.course.id'}) { #print '