--- loncom/lonnet/perl/lonnet.pm	2000/12/06 20:32:52	1.77
+++ loncom/lonnet/perl/lonnet.pm	2000/12/14 21:44:06	1.81
@@ -81,7 +81,7 @@
 # 10/06,10/09,10/10,10/11,10/14,10/20,10/23,10/25,10/26,10/27,10/28,10/29, 
 # 10/30,10/31,
 # 11/2,11/14,11/15,11/16,11/20,11/21,11/22,11/25,11/27,
-# 12/02 Gerd Kortemeyer
+# 12/02,12/12,12/13,12/14 Gerd Kortemeyer
 
 package Apache::lonnet;
 
@@ -901,6 +901,7 @@ sub allowed {
 # Course: uri itself is a course
     my $courseuri=$uri;
     $courseuri=~s/\_(\d)/\/$1/;
+
     if ($ENV{'user.priv.'.$ENV{'request.role'}.'./'.$courseuri}
        =~/$priv\&([^\:]*)/) {
        $thisallowed.=$1;
@@ -1166,27 +1167,137 @@ sub assignrole {
     my $mrole;
     $url=declutter($url);
     if ($role =~ /^cr\//) {
-        unless ($url=~/\.course$/) { return 'invalid'; }
-	unless (allowed('ccr',$url)) { return 'refused'; }
+	unless (&allowed('ccr',$url)) { return 'refused'; }
         $mrole='cr';
     } else {
-        unless (($url=~/\.course$/) || ($url=~/\/$/)) { return 'invalid'; }
-        unless (allowed('c'+$role)) { return 'refused'; }
+        unless (&allowed('c'.$role,$url)) { return 'refused'; }
         $mrole=$role;
     }
     my $command="encrypt:rolesput:$ENV{'user.domain'}:$ENV{'user.name'}:".
                 "$udom:$uname:$url".'_'."$mrole=$role";
-    if ($end) { $command.='_$end'; }
+    if ($end) { $command.='_'.$end; }
     if ($start) {
 	if ($end) { 
-           $command.='_$start'; 
+           $command.='_'.$start; 
         } else {
-           $command.='_0_$start';
+           $command.='_0_'.$start;
         }
     }
     return &reply($command,&homeserver($uname,$udom));
 }
 
+# --------------------------------------------------------------- Modify a user
+
+
+sub modifyuser {
+    my ($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene)=@_;
+    &logthis('Call to modify user '.$udom.', '.$uname.', '.$uid.', '.
+             $umode.', '.$first.', '.$middle.', '.
+	     $last.', '.$gene.' by '.
+             $ENV{'user.name'}.' at '.$ENV{'user.domain'});  
+    my $uhome=&homeserver($uname,$udom);
+# ----------------------------------------------------------------- Create User
+    if (($uhome eq 'no_host') && ($umode) && ($upass)) {
+        my $unhome='';
+	if ($ENV{'course.'.$ENV{'request.course.id'}.'.domain'} eq $udom) {
+	    $unhome=$ENV{'course.'.$ENV{'request.course.id'}.'.home'};
+        } else {
+            my $tryserver;
+            my $loadm=10000000;
+            foreach $tryserver (keys %libserv) {
+	       if ($hostdom{$tryserver} eq $udom) {
+                  my $answer=reply('load',$tryserver);
+                  if (($answer=~/\d+/) && ($answer<$loadm)) {
+		      $loadm=$answer;
+                      $unhome=$tryserver;
+                  }
+	       }
+	    }
+        }
+        if (($unhome eq '') || ($unhome eq 'no_host')) {
+	    return 'error: find home';
+        }
+        my $reply=&reply('encrypt:makeuser:'.$udom.':'.$uname.':'.$umode.':'.
+                         &escape($upass),$unhome);
+	unless ($reply eq 'ok') {
+            return 'error: '.$reply;
+        }   
+        $uhome=&homeserver($uname,$udom);
+        if (($uhome eq '') || ($uhome eq 'no_host') || ($uhome ne $unhome)) {
+	    return 'error: verify home';
+        }
+    }
+# ---------------------------------------------------------------------- Add ID
+    if ($uid) {
+       $uid=~tr/A-Z/a-z/;
+       my %uidhash=&idrget($udom,$uname);
+       if (($uidhash{$uname}) && ($uidhash{$uname}!~/error\:/)) {
+	  unless ($uid eq $uidhash{$uname}) {
+	      return 'error: mismatch '.$uidhash{$uname}.' versus '.$uid;
+          }
+       } else {
+	  &idput($udom,($uname => $uid));
+       }
+    }
+# -------------------------------------------------------------- Add names, etc
+    my $names=&reply('get:'.$udom.':'.$uname.
+                     ':environment:firstname&middlename&lastname&generation',
+                     $uhome);
+    my ($efirst,$emiddle,$elast,$egene)=split(/\&/,$names);
+    if ($first)  { $efirst  = &escape($first); }
+    if ($middle) { $emiddle = &escape($middle); }
+    if ($last)   { $elast   = &escape($last); }
+    if ($gene)   { $egene   = &escape($gene); }
+    my $reply=&reply('put:'.$udom.':'.$uname.
+           ':environment:firstname='.$efirst.
+                      '&middlename='.$emiddle.
+                        '&lastname='.$elast.
+                      '&generation='.$egene,$uhome);
+    if ($reply ne 'ok') {
+	return 'error: '.$reply;
+    }
+    &logthis('Success modifying user '.$udom.', '.$uname.', '.$uid.', '.
+             $umode.', '.$first.', '.$middle.', '.
+	     $last.', '.$gene.' by '.
+             $ENV{'user.name'}.' at '.$ENV{'user.domain'});
+    return 'ok'; 
+}
+
+# -------------------------------------------------------------- Modify student
+
+sub modifystudent {
+    my ($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene,$usec,
+        $end,$start)=@_;
+    my $cid='';
+    unless ($cid=$ENV{'request.course.id'}) {
+	return 'not_in_class';
+    }
+# --------------------------------------------------------------- Make the user
+    my $reply=&modifyuser
+	($udom,$uname,$uid,$umode,$upass,$first,$middle,$last,$gene);
+    unless ($reply eq 'ok') { return $reply; }
+    my $uhome=&homeserver($uname,$udom);
+    if (($uhome eq '') || ($uhome eq 'no_host')) { 
+	return 'error: no such user';
+    }
+# -------------------------------------------------- Add student to course list
+    my $reply=critical('put:'.$ENV{'course.'.$cid.'.domain'}.':'.
+	              $ENV{'course.'.$cid.'.num'}.':classlist:'.
+                      &escape($uname.':'.$udom).'='.
+                      &escape($end.':'.$start),
+	              $ENV{'course.'.$cid.'.home'});
+    unless (($reply eq 'ok') || ($reply eq 'delayed')) {
+	return 'error: '.$reply;
+    }
+# ---------------------------------------------------- Add student role to user
+    my $uurl=$cid;
+    $uurl=~s/\_/\//g;
+    if ($usec) {
+	$uurl.='/'.$usec;
+    }
+    return &assignrole($udom,$uname,$uurl,'st',$end,$start);
+}
+
 # ---------------------------------------------------------- Assign Custom Role
 
 sub assigncustomrole {
@@ -1426,26 +1537,14 @@ sub EXT {
         my $reply=&reply('get:'.
               $ENV{'course.'.$ENV{'request.course.id'}.$section.'.domain'}.':'.
               $ENV{'course.'.$ENV{'request.course.id'}.$section.'.num'}.
-              ':resourcedata:'.
- escape($seclevelr).':'.escape($seclevelm).':'.escape($seclevel).':'.
- escape($courselevelr).':'.escape($courselevelm).':'.escape($courselevel),
+	      ':resourcedata:'.
+   &escape($seclevelr).'&'.&escape($seclevelm).'&'.&escape($seclevel).'&'.
+   &escape($courselevelr).'&'.&escape($courselevelm).'&'.&escape($courselevel),
 		   $ENV{'course.'.$ENV{'request.course.id'}.$section.'.home'});
       if ($reply!~/^error\:/) {
-        map {
-           my ($name,$value)=split(/\=/,$_);
-           $resourcedata{unescape($name)}=unescape($value);  
-        } split(/\&/,$reply);
-
-       if ($resourcedata{$seclevelr}) { return $resourcedata{$seclevelr}; }
-       if ($resourcedata{$seclevelm}) { return $resourcedata{$seclevelm}; }  
-       if ($resourcedata{$seclevel}) { return $resourcedata{$seclevel}; }
-
-       if ($resourcedata{$courselevelr}) { 
-          return $resourcedata{$courselevelr}; }
-       if ($resourcedata{$courselevelm}) { 
-          return $resourcedata{$courselevelm}; }
-       if ($resourcedata{$courselevel}) { return $resourcedata{$courselevel}; }
-
+	  map {
+	      if ($_) { return &unescape($_); }
+          } split(/\&/,$reply);
       }
 
 # ------------------------------------------------------ third, check map parms
@@ -1461,8 +1560,12 @@ sub EXT {
      
 # --------------------------------------------- last, look in resource metadata
 
+      $spacequalifierrest=~s/\./\_/;
       my $metadata=&metadata($ENV{'request.filename'},$spacequalifierrest);
       if ($metadata) { return $metadata; }
+      $metadata=&metadata($ENV{'request.filename'},
+                                         'parameter_'.$spacequalifierrest);
+      if ($metadata) { return $metadata; }
 
 # ---------------------------------------------------- Any other user namespace
     } elsif ($realm eq 'environment') {
@@ -1481,6 +1584,7 @@ sub EXT {
 
 sub metadata {
     my ($uri,$what)=@_;
+
     $uri=&declutter($uri);
     my $filename=$uri;
     $uri=~s/\.meta$//;
@@ -1507,7 +1611,11 @@ sub metadata {
               map {
 		  $metacache{$uri.':'.$unikey.'.'.$_}=$token->[2]->{$_};
               } @{$token->[3]};
-              $metacache{$uri.':'.$unikey}=$parser->get_text('/'.$entry);
+              unless (
+                 $metacache{$uri.':'.$unikey}=$parser->get_text('/'.$entry)
+		      ) { $metacache{$uri.':'.$unikey}=
+			      $metacache{$uri.':'.$unikey.'.default'};
+		      }
           }
        }
     }