--- loncom/lonnet/perl/lonnet.pm	2007/09/29 04:03:51	1.914
+++ loncom/lonnet/perl/lonnet.pm	2007/11/20 17:54:40	1.928
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # TCP networking package
 #
-# $Id: lonnet.pm,v 1.914 2007/09/29 04:03:51 albertel Exp $
+# $Id: lonnet.pm,v 1.928 2007/11/20 17:54:40 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -320,7 +320,10 @@ sub convert_and_load_session_env {
     my ($lonidsdir,$handle)=@_;
     my @profile;
     {
-	open(my $idf,"$lonidsdir/$handle.id");
+	my $opened = open(my $idf,'+<',"$lonidsdir/$handle.id");
+	if (!$opened) {
+	    return 0;
+	}
 	flock($idf,LOCK_SH);
 	@profile=<$idf>;
 	close($idf);
@@ -359,7 +362,10 @@ sub transfer_profile_to_env {
 
     my $convert;
     {
-    	open(my $idf,"$lonidsdir/$handle.id");
+    	my $opened = open(my $idf,'+<',"$lonidsdir/$handle.id");
+	if (!$opened) {
+	    return;
+	}
 	flock($idf,LOCK_SH);
 	if (tie(my %disk_env,'GDBM_File',"$lonidsdir/$handle.id",
 		&GDBM_READER(),0640)) {
@@ -391,6 +397,34 @@ sub transfer_profile_to_env {
     }
 }
 
+# ---------------------------------------------------- Check for valid session 
+sub check_for_valid_session {
+    my ($r) = @_;
+    my %cookies=CGI::Cookie->parse($r->header_in('Cookie'));
+    my $lonid=$cookies{'lonID'};
+    return undef if (!$lonid);
+
+    my $handle=&LONCAPA::clean_handle($lonid->value);
+    my $lonidsdir=$r->dir_config('lonIDsDir');
+    return undef if (!-e "$lonidsdir/$handle.id");
+
+    my $opened = open(my $idf,'+<',"$lonidsdir/$handle.id");
+    return undef if (!$opened);
+
+    flock($idf,LOCK_SH);
+    my %disk_env;
+    if (!tie(%disk_env,'GDBM_File',"$lonidsdir/$handle.id",
+	    &GDBM_READER(),0640)) {
+	return undef;	
+    }
+
+    if (!defined($disk_env{'user.name'})
+	|| !defined($disk_env{'user.domain'})) {
+	return undef;
+    }
+    return $handle;
+}
+
 sub timed_flock {
     my ($file,$lock_type) = @_;
     my $failed=0;
@@ -425,8 +459,9 @@ sub appenv {
             $env{$key}=$newenv{$key};
         }
     }
-    open(my $env_file,$env{'user.environment'});
-    if (&timed_flock($env_file,LOCK_EX)
+    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)) {
@@ -446,16 +481,17 @@ sub delenv {
                 "Attempt to delete from environment ".$delthis);
         return 'error';
     }
-    open(my $env_file,$env{'user.environment'});
-    if (&timed_flock($env_file,LOCK_EX)
+    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)) {
 	foreach my $key (keys(%disk_env)) {
 	    if ($key=~/^$delthis/) { 
-                delete($env{$key});
-                delete($disk_env{$key});
-            }
+		delete($env{$key});
+		delete($disk_env{$key});
+	    }
 	}
 	untie(%disk_env);
     }
@@ -477,7 +513,6 @@ sub get_env_multiple {
 }
 
 # ------------------------------------------ Find out current server userload
-# there is a copy in lond
 sub userload {
     my $numusers=0;
     {
@@ -485,7 +520,8 @@ sub userload {
 	my $filename;
 	my $curtime=time;
 	while ($filename=readdir(LONIDS)) {
-	    if ($filename eq '.' || $filename eq '..') {next;}
+	    next if ($filename eq '.' || $filename eq '..');
+	    next if ($filename =~ /publicuser_\d+\.id/);
 	    my ($mtime)=(stat($perlvar{'lonIDsDir'}.'/'.$filename))[9];
 	    if ($curtime-$mtime < 1800) { $numusers++; }
 	}
@@ -1011,7 +1047,7 @@ sub get_instuser {
 }
 
 sub inst_rulecheck {
-    my ($udom,$uname,$rules) = @_;
+    my ($udom,$uname,$id,$item,$rules) = @_;
     my %returnhash;
     if ($udom ne '') {
         if (ref($rules) eq 'ARRAY') {
@@ -1019,9 +1055,16 @@ sub inst_rulecheck {
             my $rulestr = join(':',@{$rules});
             my $homeserver=&domain($udom,'primary');
             if (($homeserver ne '') && ($homeserver ne 'no_host')) {
-                my $response=&unescape(&reply('instrulecheck:'.&escape($udom).':'.
-                                              &escape($uname).':'.$rulestr,
+                my $response;
+                if ($item eq 'username') {                
+                    $response=&unescape(&reply('instrulecheck:'.&escape($udom).
+                                              ':'.&escape($uname).':'.$rulestr,
                                               $homeserver));
+                } elsif ($item eq 'id') {
+                    $response=&unescape(&reply('instidrulecheck:'.&escape($udom).
+                                              ':'.&escape($id).':'.$rulestr,
+                                              $homeserver));
+                }
                 if ($response ne 'refused') {
                     my @pairs=split(/\&/,$response);
                     foreach my $item (@pairs) {
@@ -1038,14 +1081,21 @@ sub inst_rulecheck {
 }
 
 sub inst_userrules {
-    my ($udom) = @_;
+    my ($udom,$check) = @_;
     my (%ruleshash,@ruleorder);
     if ($udom ne '') {
         my $homeserver=&domain($udom,'primary');
         if (($homeserver ne '') && ($homeserver ne 'no_host')) {
-            my $response=&reply('instuserrules:'.&escape($udom),
+            my $response;
+            if ($check eq 'id') {
+                $response=&reply('instidrules:'.&escape($udom),
+                                 $homeserver);
+            } else {
+                $response=&reply('instuserrules:'.&escape($udom),
                                  $homeserver);
+            }
             if (($response ne 'refused') && ($response ne 'error') && 
+                ($response ne 'unknown_cmd') && 
                 ($response ne 'no_such_host')) {
                 my ($hashitems,$orderitems) = split(/:/,$response);
                 my @pairs=split(/\&/,$hashitems);
@@ -1347,13 +1397,15 @@ sub do_cache_new {
 	$memcache->disconnect_all();
     }
     # need to make a copy of $value
-    #&make_room($id,$value,$debug);
+    &make_room($id,$value,$debug);
     return $value;
 }
 
 sub make_room {
     my ($id,$value,$debug)=@_;
-    $remembered{$id}=$value;
+
+    $remembered{$id}= (ref($value)) ? &Storable::dclone($value)
+                                    : $value;
     if ($to_remember<0) { return; }
     $accessed{$id}=[&gettimeofday()];
     if (scalar(keys(%remembered)) <= $to_remember) { return; }
@@ -2134,7 +2186,7 @@ sub flushcourselogs {
 # times and course titles for all courseids
 #
     my %courseidbuffer=();
-    foreach my $crsid (keys %courselogs) {
+    foreach my $crsid (keys(%courselogs)) {
         if (&reply('log:'.$coursedombuf{$crsid}.':'.$coursenumbuf{$crsid}.':'.
 		          &escape($courselogs{$crsid}),
 		          $coursehombuf{$crsid}) eq 'ok') {
@@ -2147,23 +2199,21 @@ sub flushcourselogs {
                delete $courselogs{$crsid};
             }
         }
-        if ($courseidbuffer{$coursehombuf{$crsid}}) {
-           $courseidbuffer{$coursehombuf{$crsid}}.='&'.
-			 &escape($crsid).'='.&escape($coursedescrbuf{$crsid}).
-                         ':'.&escape($courseinstcodebuf{$crsid}).':'.&escape($courseownerbuf{$crsid}).':'.&escape($coursetypebuf{$crsid});
-        } else {
-           $courseidbuffer{$coursehombuf{$crsid}}=
-			 &escape($crsid).'='.&escape($coursedescrbuf{$crsid}).
-                         ':'.&escape($courseinstcodebuf{$crsid}).':'.&escape($courseownerbuf{$crsid}).':'.&escape($coursetypebuf{$crsid});
-        }
+        $courseidbuffer{$coursehombuf{$crsid}}{$crsid} = {
+            'description' => &escape($coursedescrbuf{$crsid}),
+            'inst_code'    => &escape($courseinstcodebuf{$crsid}),
+            'type'        => &escape($coursetypebuf{$crsid}),
+            'owner'       => &escape($courseownerbuf{$crsid}),
+        };
     }
 #
 # Write course id database (reverse lookup) to homeserver of courses 
 # Is used in pickcourse
 #
     foreach my $crs_home (keys(%courseidbuffer)) {
-        &courseidput(&host_domain($crs_home),$courseidbuffer{$crs_home},
-		     $crs_home);
+        my $response = &courseidput(&host_domain($crs_home),
+                                    $courseidbuffer{$crs_home},
+                                    $crs_home,'timeonly');
     }
 #
 # File accesses
@@ -2427,7 +2477,13 @@ sub get_my_roles {
         }
         if (ref($roles) eq 'ARRAY') {
             if (!grep(/^\Q$role\E$/,@{$roles})) {
-                next;
+                if ($role =~ /^cr\//) {
+                    if (!grep(/^cr$/,@{$roles})) {
+                        next;
+                    }
+                } else {
+                    next;
+                }
             }
         }
 	$returnhash{$username.':'.$domain.':'.$role}=$tstart.':'.$tend;
@@ -2469,31 +2525,77 @@ sub getannounce {
 #
 
 sub courseidput {
-    my ($domain,$what,$coursehome)=@_;
-    return &reply('courseidput:'.$domain.':'.$what,$coursehome);
+    my ($domain,$storehash,$coursehome,$caller) = @_;
+    my $outcome;
+    if ($caller eq 'timeonly') {
+        my $cids = '';
+        foreach my $item (keys(%$storehash)) {
+            $cids.=&escape($item).'&';
+        }
+        $cids=~s/\&$//;
+        $outcome = &reply('courseidputhash:'.$domain.':'.$caller.':'.$cids,
+                          $coursehome);       
+    } else {
+        my $items = '';
+        foreach my $item (keys(%$storehash)) {
+            $items.= &escape($item).'='.
+                     &freeze_escape($$storehash{$item}).'&';
+        }
+        $items=~s/\&$//;
+        $outcome = &reply('courseidputhash:'.$domain.':'.$caller.':'.$items,
+                          $coursehome);
+    }
+    if ($outcome eq 'unknown_cmd') {
+        my $what;
+        foreach my $cid (keys(%$storehash)) {
+            $what .= &escape($cid).'=';
+            foreach my $item ('description','inst_code','owner','type') {
+                $what .= &escape($storehash->{$item}).':';
+            }
+            $what =~ s/\:$/&/;
+        }
+        $what =~ s/\&$//;  
+        return &reply('courseidput:'.$domain.':'.$what,$coursehome);
+    } else {
+        return $outcome;
+    }
 }
 
 sub courseiddump {
-    my ($domfilter,$descfilter,$sincefilter,$instcodefilter,$ownerfilter,$coursefilter,$hostidflag,$hostidref,$typefilter,$regexp_ok)=@_;
-    my %returnhash=();
-    unless ($domfilter) { $domfilter=''; }
+    my ($domfilter,$descfilter,$sincefilter,$instcodefilter,$ownerfilter,
+        $coursefilter,$hostidflag,$hostidref,$typefilter,$regexp_ok)=@_;
+    my $as_hash = 1;
+    my %returnhash;
+    if (!$domfilter) { $domfilter=''; }
     my %libserv = &all_library();
     foreach my $tryserver (keys(%libserv)) {
         if ( (  $hostidflag == 1 
 	        && grep(/^\Q$tryserver\E$/,@{$hostidref}) ) 
 	     || (!defined($hostidflag)) ) {
 
-	    if ($domfilter eq ''
-		|| (&host_domain($tryserver) eq $domfilter)) {
-	        foreach my $line (
-                 split(/\&/,&reply('courseiddump:'.&host_domain($tryserver).':'.
-			       $sincefilter.':'.&escape($descfilter).':'.
-                               &escape($instcodefilter).':'.&escape($ownerfilter).':'.&escape($coursefilter).':'.&escape($typefilter).':'.&escape($regexp_ok),
-                               $tryserver))) {
-		    my ($key,$value)=split(/\=/,$line,2);
-                    if (($key) && ($value)) {
-		        $returnhash{&unescape($key)}=$value;
-                    }
+	    if (($domfilter eq '') ||
+		(&host_domain($tryserver) eq $domfilter)) {
+                my $rep = 
+                  &reply('courseiddump:'.&host_domain($tryserver).':'.
+                         $sincefilter.':'.&escape($descfilter).':'.
+                         &escape($instcodefilter).':'.&escape($ownerfilter).
+                         ':'.&escape($coursefilter).':'.&escape($typefilter).
+                         ':'.&escape($regexp_ok).':'.$as_hash,$tryserver);
+                my @pairs=split(/\&/,$rep);
+                foreach my $item (@pairs) {
+                    my ($key,$value)=split(/\=/,$item,2);
+                    $key = &unescape($key);
+                    next if ($key =~ /^error: 2 /);
+                    my $result = &thaw_unescape($value);
+                    if (ref($result) eq 'HASH') {
+                        $returnhash{$key}=$result;
+                    } else {
+                        my @responses = split(/:/,$value);
+                        my @items = ('description','inst_code','owner','type');
+                        for (my $i=0; $i<@responses; $i++) {
+                            $returnhash{$key}{$items[$i]} = &unescape($responses[$i]);
+                        }
+                    } 
                 }
             }
         }
@@ -2539,7 +2641,10 @@ sub get_domain_roles {
     if (undef($enddate) || $enddate eq '') {
         $enddate = '.';
     }
-    my $rolelist = join(':',@{$roles});
+    my $rolelist;
+    if (ref($roles) eq 'ARRAY') {
+        $rolelist = join(':',@{$roles});
+    }
     my %personnel = ();
 
     my %servers = &get_servers($dom,'library');
@@ -2565,7 +2670,9 @@ sub get_first_access {
     my ($symb,$courseid,$udom,$uname)=&whichuser();
     if ($argsymb) { $symb=$argsymb; }
     my ($map,$id,$res)=&decode_symb($symb);
-    if ($type eq 'map') {
+    if ($type eq 'course') {
+	$res='course';
+    } elsif ($type eq 'map') {
 	$res=&symbread($map);
     } else {
 	$res=$symb;
@@ -2578,7 +2685,9 @@ sub set_first_access {
     my ($type)=@_;
     my ($symb,$courseid,$udom,$uname)=&whichuser();
     my ($map,$id,$res)=&decode_symb($symb);
-    if ($type eq 'map') {
+    if ($type eq 'course') {
+	$res='course';
+    } elsif ($type eq 'map') {
 	$res=&symbread($map);
     } else {
 	$res=$symb;
@@ -4939,10 +5048,16 @@ sub auto_instcode_defaults {
 } 
 
 sub auto_validate_class_sec {
-    my ($cdom,$cnum,$owner,$inst_class) = @_;
+    my ($cdom,$cnum,$owners,$inst_class) = @_;
     my $homeserver = &homeserver($cnum,$cdom);
+    my $ownerlist;
+    if (ref($owners) eq 'ARRAY') {
+        $ownerlist = join(',',@{$owners});
+    } else {
+        $ownerlist = $owners;
+    }
     my $response=&reply('autovalidateclass_sec:'.$inst_class.':'.
-                        &escape($owner).':'.$cdom,$homeserver);
+                        &escape($ownerlist).':'.$cdom,$homeserver);
     return $response;
 }
 
@@ -5471,10 +5586,15 @@ sub createcourse {
     }
 # ----------------------------------------------------------------- Course made
 # log existence
-    &courseidput($udom,&escape($udom.'_'.$uname).'='.&escape($description).
-                 ':'.&escape($inst_code).':'.&escape($course_owner).':'.
-                  &escape($crstype),$uhome);
-    &flushcourselogs();
+    my $newcourse = {
+                    $udom.'_'.$uname => {
+                                     description => $description,
+                                     inst_code   => $inst_code,
+                                     owner       => $course_owner,
+                                     type        => $crstype,
+                                                },
+                    };
+    &courseidput($udom,$newcourse,$uhome,'notime');
 # set toplevel url
     my $topurl=$url;
     unless ($nonstandard) {
@@ -5504,7 +5624,7 @@ ENDINITMAP
 sub is_course {
     my ($cdom,$cnum) = @_;
     my %courses = &courseiddump($cdom,'.',1,'.','.',$cnum,undef,
-				undef,'.');
+				undef,'.',undef,1);
     if (exists($courses{$cdom.'_'.$cnum})) {
         return 1;
     }
@@ -6276,8 +6396,8 @@ sub resdata {
     }
     if (!ref($result)) { return $result; }    
     foreach my $item (@which) {
-	if (defined($result->{$item})) {
-	    return $result->{$item};
+	if (defined($result->{$item->[0]})) {
+	    return [$result->{$item->[0]},$item->[1]];
 	}
     }
     return undef;
@@ -6489,8 +6609,9 @@ sub EXT {
 # ----------------------------------------------------------- first, check user
 
 	    my $userreply=&resdata($uname,$udom,'user',
-				       ($courselevelr,$courselevelm,
-					$courselevel));
+				       ([$courselevelr,'resource'],
+					[$courselevelm,'map'     ],
+					[$courselevel, 'course'  ]));
 	    if (defined($userreply)) { return $userreply; }
 
 # ------------------------------------------------ second, check some of course
@@ -6498,15 +6619,17 @@ sub EXT {
             if (@groups > 0) {
                 $coursereply = &check_group_parms($courseid,\@groups,$symbparm,
                                        $mapparm,$spacequalifierrest);
-                if (defined($coursereply)) { return $coursereply; }
+                if (defined($coursereply)) { return &get_reply($coursereply); }
             }
 
 	    $coursereply=&resdata($env{'course.'.$courseid.'.num'},
-				     $env{'course.'.$courseid.'.domain'},
-				     'course',
-				     ($seclevelr,$seclevelm,$seclevel,
-				      $courselevelr));
-	    if (defined($coursereply)) { return $coursereply; }
+				  $env{'course.'.$courseid.'.domain'},
+				  'course',
+				  ([$seclevelr,   'resource'],
+				   [$seclevelm,   'map'     ],
+				   [$seclevel,    'course'  ],
+				   [$courselevelr,'resource']));
+	    if (defined($coursereply)) { return &get_reply($coursereply); }
 
 # ------------------------------------------------------ third, check map parms
 	    my %parmhash=();
@@ -6517,7 +6640,7 @@ sub EXT {
 		$thisparm=$parmhash{$symbparm};
 		untie(%parmhash);
 	    }
-	    if ($thisparm) { return $thisparm; }
+	    if ($thisparm) { return &get_reply([$thisparm,'resource']); }
 	}
 # ------------------------------------------ fourth, look in resource metadata
 
@@ -6530,18 +6653,19 @@ sub EXT {
 	    $filename=$env{'request.filename'};
 	}
 	my $metadata=&metadata($filename,$spacequalifierrest);
-	if (defined($metadata)) { return $metadata; }
+	if (defined($metadata)) { return &get_reply([$metadata,'resource']); }
 	$metadata=&metadata($filename,'parameter_'.$spacequalifierrest);
-	if (defined($metadata)) { return $metadata; }
+	if (defined($metadata)) { return &get_reply([$metadata,'resource']); }
 
-# ---------------------------------------------- fourth, look in rest pf course
+# ---------------------------------------------- fourth, look in rest of course
 	if ($symbparm && defined($courseid) && 
 	    $courseid eq $env{'request.course.id'}) {
 	    my $coursereply=&resdata($env{'course.'.$courseid.'.num'},
 				     $env{'course.'.$courseid.'.domain'},
 				     'course',
-				     ($courselevelm,$courselevel));
-	    if (defined($coursereply)) { return $coursereply; }
+				     ([$courselevelm,'map'   ],
+				      [$courselevel, 'course']));
+	    if (defined($coursereply)) { return &get_reply($coursereply); }
 	}
 # ------------------------------------------------------------------ Cascade up
 	unless ($space eq '0') {
@@ -6549,14 +6673,13 @@ sub EXT {
 	    my $id=pop(@parts);
 	    my $part=join('_',@parts);
 	    if ($part eq '') { $part='0'; }
-	    my $partgeneral=&EXT('resource.'.$part.'.'.$qualifierrest,
+	    my @partgeneral=&EXT('resource.'.$part.'.'.$qualifierrest,
 				 $symbparm,$udom,$uname,$section,1);
-	    if (defined($partgeneral)) { return $partgeneral; }
+	    if (@partgeneral) { return &get_reply(\@partgeneral); }
 	}
 	if ($recurse) { return undef; }
 	my $pack_def=&packages_tab_default($filename,$varname);
-	if (defined($pack_def)) { return $pack_def; }
-
+	if (defined($pack_def)) { return &get_reply([$pack_def,'resource']); }
 # ---------------------------------------------------- Any other user namespace
     } elsif ($realm eq 'environment') {
 # ----------------------------------------------------------------- environment
@@ -6584,15 +6707,23 @@ sub EXT {
     return '';
 }
 
+sub get_reply {
+    my ($reply_value) = @_;
+    if (wantarray) {
+	return @$reply_value;
+    }
+    return $reply_value->[0];
+}
+
 sub check_group_parms {
     my ($courseid,$groups,$symbparm,$mapparm,$what) = @_;
     my @groupitems = ();
     my $resultitem;
-    my @levels = ($symbparm,$mapparm,$what);
+    my @levels = ([$symbparm,'resource'],[$mapparm,'map'],[$what,'course']);
     foreach my $group (@{$groups}) {
         foreach my $level (@levels) {
-             my $item = $courseid.'.['.$group.'].'.$level;
-             push(@groupitems,$item);
+             my $item = $courseid.'.['.$group.'].'.$level->[0];
+             push(@groupitems,[$item,$level->[1]]);
         }
     }
     my $coursereply = &resdata($env{'course.'.$courseid.'.num'},
@@ -6685,8 +6816,11 @@ sub metadata {
     if (($uri eq '') || 
 	(($uri =~ m|^/*adm/|) && 
 	     ($uri !~ m|^adm/includes|) && ($uri !~ m|/bulletinboard$|)) ||
-        ($uri =~ m|/$|) || ($uri =~ m|/.meta$|) || ($uri =~ /^~/) ||
-	($uri =~ m|home/$match_username/public_html/|)) {
+        ($uri =~ m|/$|) || ($uri =~ m|/.meta$|) ) {
+	return undef;
+    }
+    if (($uri =~ /^~/ || $uri =~ m{home/$match_username/public_html/}) 
+	&& &Apache::lonxml::get_state('target') =~ /^(|meta)$/) {
 	return undef;
     }
     my $filename=$uri;
@@ -6707,6 +6841,7 @@ sub metadata {
 #	if (! exists($metacache{$uri})) {
 #	    $metacache{$uri}={};
 #	}
+	my $cachetime = 60*60;
         if ($liburi) {
 	    $liburi=&declutter($liburi);
             $filename=$liburi;
@@ -6717,7 +6852,12 @@ sub metadata {
         my %metathesekeys=();
         unless ($filename=~/\.meta$/) { $filename.='.meta'; }
 	my $metastring;
-	if ($uri !~ m -^(editupload)/-) {
+	if ($uri =~ /^~/ || $uri =~ m{home/$match_username/public_html/}) {
+	    $metastring = 
+		&Apache::lonnet::ssi_body(&hreflocation('','/'.$uri),
+					  ('grade_target' => 'meta'));
+	    $cachetime = 1; # only want this cached in the child not long term
+	} elsif ($uri !~ m -^(editupload)/-) {
 	    my $file=&filelocation('',&clutter($filename));
 	    #push(@{$metaentry{$uri.'.file'}},$file);
 	    $metastring=&getfile($file);
@@ -6884,7 +7024,7 @@ sub metadata {
 	$metaentry{':keys'} = join(',',keys(%metathesekeys));
 	&metadata_generate_part0(\%metathesekeys,\%metaentry,$uri);
 	$metaentry{':allpossiblekeys'}=join(',',keys %metathesekeys);
-	&do_cache_new('meta',$uri,\%metaentry,60*60);
+	&do_cache_new('meta',$uri,\%metaentry,$cachetime);
 # this is the end of "was not already recently cached
     }
     return $metaentry{':'.$what};