--- loncom/lonnet/perl/lonnet.pm	2011/10/19 16:36:02	1.1056.4.33
+++ loncom/lonnet/perl/lonnet.pm	2010/09/30 14:08:51	1.1087
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # TCP networking package
 #
-# $Id: lonnet.pm,v 1.1056.4.33 2011/10/19 16:36:02 raeburn Exp $
+# $Id: lonnet.pm,v 1.1087 2010/09/30 14:08:51 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -76,8 +76,7 @@ use HTTP::Date;
 use Image::Magick;
 
 use vars qw(%perlvar %spareid %pr %prp $memcache %packagetab $tmpdir
-            $_64bit %env %protocol %loncaparevs %serverhomeIDs %needsrelease
-            %managerstab);
+            $_64bit %env %protocol %loncaparevs %serverhomeIDs %needsrelease);
 
 my (%badServerCache, $memcache, %courselogs, %accesshash, %domainrolehash,
     %userrolehash, $processmarker, $dumpcount, %coursedombuf,
@@ -96,7 +95,6 @@ use Math::Random;
 use File::MMagic;
 use LONCAPA qw(:DEFAULT :match);
 use LONCAPA::Configuration;
-use File::Copy;
 
 my $readit;
 my $max_connection_retries = 10;     # Or some such value.
@@ -197,29 +195,6 @@ sub get_server_timezone {
     }
 }
 
-sub get_server_distarch {
-    my ($lonhost,$ignore_cache) = @_;
-    if (defined($lonhost)) {
-        if (!defined(&hostname($lonhost))) {
-            return;
-        }
-        my $cachetime = 12*3600;
-        if (!$ignore_cache) {
-            my ($distarch,$cached)=&is_cached_new('serverdistarch',$lonhost);
-            if (defined($cached)) {
-                return $distarch;
-            }
-        }
-        my $rep = &reply('serverdistarch',$lonhost);
-        unless ($rep eq 'unknown_command' || $rep eq 'no_such_host' ||
-                $rep eq 'con_lost' || $rep eq 'rejected' || $rep eq 'refused' ||
-                $rep eq '') {
-            return &do_cache_new('serverdistarch',$lonhost,$rep,$cachetime);
-        }
-    }
-    return;
-}
-
 sub get_server_loncaparev {
     my ($dom,$lonhost,$ignore_cache,$caller) = @_;
     if (defined($lonhost)) {
@@ -288,7 +263,7 @@ sub get_server_homeID {
     }
     my $cachetime = 12*3600;
     my $serverhomeID;
-    if ($caller eq 'loncron') {
+    if ($caller eq 'loncron') { 
         my @machine_ids = &machine_ids($hostname);
         foreach my $id (@machine_ids) {
             my $response = &reply('serverhomeID',$id);
@@ -749,30 +724,6 @@ sub userload {
     return $userloadpercent;
 }
 
-# ------------------------------------------ Fight off request when overloaded
-
-sub overloaderror {
-    my ($r,$checkserver)=@_;
-    unless ($checkserver) { $checkserver=$perlvar{'lonHostID'}; }
-    my $loadavg;
-    if ($checkserver eq $perlvar{'lonHostID'}) {
-       open(my $loadfile,'/proc/loadavg');
-       $loadavg=<$loadfile>;
-       $loadavg =~ s/\s.*//g;
-       $loadavg = 100*$loadavg/$perlvar{'lonLoadLim'};
-       close($loadfile);
-    } else {
-       $loadavg=&reply('load',$checkserver);
-    }
-    my $overload=$loadavg-100;
-    if ($overload>0) {
-	$r->err_headers_out->{'Retry-After'}=$overload;
-        $r->log_error('Overload of '.$overload.' on '.$checkserver);
-        return 413;
-    }    
-    return '';
-}
-
 # ------------------------------ Find server with least workload from spare.tab
 
 sub spareserver {
@@ -790,8 +741,8 @@ sub spareserver {
     }
     foreach my $try_server (@{ $spareid{'primary'} }) {
         if ($uint_dom) {
-            next unless (&spare_can_host($udom,$uint_dom,$remotesessions,
-                                         $try_server));
+             next unless (&spare_can_host($udom,$uint_dom,$remotesessions,
+                                          $try_server));
         }
 	($spare_server, $lowest_load) =
 	    &compare_server_load($try_server, $spare_server, $lowest_load);
@@ -832,7 +783,7 @@ sub compare_server_load {
     my $userloadans = &reply('userload',$try_server);
 
     if ($loadans !~ /\d/ && $userloadans !~ /\d/) {
-        return ($spare_server, $lowest_load); #didn't get a number from the server
+	return; #didn't get a number from the server
     }
 
     my $load;
@@ -878,36 +829,20 @@ sub has_user_session {
 # --------- determine least loaded server in a user's domain which allows login
 
 sub choose_server {
-    my ($udom,$checkloginvia) = @_;
+    my ($udom) = @_;
     my %domconfhash = &Apache::loncommon::get_domainconf($udom);
     my %servers = &get_servers($udom);
     my $lowest_load = 30000;
-    my ($login_host,$hostname,$portal_path);
+    my ($login_host,$hostname);
     foreach my $lonhost (keys(%servers)) {
-        my $loginvia;
-        if ($checkloginvia) {
-            $loginvia = $domconfhash{$udom.'.login.loginvia_'.$lonhost};
-            if ($loginvia) {
-                my ($server,$path) = split(/:/,$loginvia);
-                ($login_host, $lowest_load) =
-                    &compare_server_load($lonhost, $login_host, $lowest_load);
-                if ($login_host eq $server) {
-                    $portal_path = $path;
-                }
-            } else {
-                ($login_host, $lowest_load) =
-                    &compare_server_load($lonhost, $login_host, $lowest_load);
-                if ($login_host eq $lonhost) {
-                    $portal_path = '';
-                }
-            }
-        } else {
+        my $loginvia = $domconfhash{$udom.'.login.loginvia_'.$lonhost};
+        if ($loginvia eq '') {
             ($login_host, $lowest_load) =
-                &compare_server_load($lonhost, $login_host, $lowest_load);
+            &compare_server_load($lonhost, $login_host, $lowest_load);
         }
     }
     if ($login_host ne '') {
-        $hostname = &hostname($login_host);
+        $hostname = $servers{$login_host};
     }
     return ($login_host,$hostname);
 }
@@ -1050,19 +985,15 @@ sub can_host_session {
     }
     if ($canhost) {
         if (ref($hostedsessions) eq 'HASH') {
-            my $uprimary_id = &Apache::lonnet::domain($udom,'primary');
-            my $uint_dom = &Apache::lonnet::internet_dom($uprimary_id);
             if (ref($hostedsessions->{'excludedomain'}) eq 'ARRAY') {
-                if (($uint_dom ne '') && 
-                    (grep(/^\Q$uint_dom\E$/,@{$hostedsessions->{'excludedomain'}}))) {
+                if (grep(/^\Q$udom\E$/,@{$hostedsessions->{'excludedomain'}})) {
                     $canhost = 0;
                 } else {
                     $canhost = 1;
                 }
             }
             if (ref($hostedsessions->{'includedomain'}) eq 'ARRAY') {
-                if (($uint_dom ne '') && 
-                    (grep(/^\Q$uint_dom\E$/,@{$hostedsessions->{'includedomain'}}))) {
+                if (grep(/^\Q$udom\E$/,@{$hostedsessions->{'includedomain'}})) {
                     $canhost = 1;
                 } else {
                     $canhost = 0;
@@ -2244,8 +2175,6 @@ sub allowuploaded {
 #        path to file, source of file, instruction to parse file for objects,
 #        ref to hash for embedded objects,
 #        ref to hash for codebase of java objects.
-#        reference to scalar to accommodate mime type determined
-#          from File::MMagic if $parser = parse.
 #
 # output: url to file (if action was uploaddoc), 
 #         ok if successful, or diagnostic message otherwise (if action was propagate or copy)
@@ -2272,8 +2201,7 @@ sub allowuploaded {
 #
 
 sub process_coursefile {
-    my ($action,$docuname,$docudom,$file,$source,$parser,$allfiles,$codebase,
-        $mimetype)=@_;
+    my ($action,$docuname,$docudom,$file,$source,$parser,$allfiles,$codebase)=@_;
     my $fetchresult;
     my $home=&homeserver($docuname,$docudom);
     if ($action eq 'propagate') {
@@ -2301,16 +2229,13 @@ sub process_coursefile {
             close($fh);
             if ($parser eq 'parse') {
                 my $mm = new File::MMagic;
-                my $type = $mm->checktype_filename($filepath.'/'.$fname);
-                if ($type eq 'text/html') {
+                my $mime_type = $mm->checktype_filename($filepath.'/'.$fname);
+                if ($mime_type eq 'text/html') {
                     my $parse_result = &extract_embedded_items($filepath.'/'.$fname,$allfiles,$codebase);
                     unless ($parse_result eq 'ok') {
                         &logthis('Failed to parse '.$filepath.'/'.$fname.' for embedded media: '.$parse_result);
                     }
                 }
-                if (ref($mimetype)) {
-                    $$mimetype = $type;
-                }
             }
             $fetchresult= &reply('fetchuserfile:'.$docudom.'/'.$docuname.'/'.$file,
                                  $home);
@@ -2426,13 +2351,9 @@ sub resizeImage {
 
 # --------------- Take an uploaded file and put it into the userfiles directory
 # 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, 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 
+#                    the desired filenam is in $env{"form.$formname.filename"}
+#        $coursedoc - if true up to the current course
+#                     if false
 #        $subdir - directory in userfile to store the file into
 #        $parser - instruction to parse file for objects ($parser = parse)    
 #        $allfiles - reference to hash for embedded objects
@@ -2443,60 +2364,37 @@ sub resizeImage {
 #        $thumbheight - height (pixels) of thumbnail to make for uploaded image
 #        $resizewidth - width (pixels) to which to resize uploaded image
 #        $resizeheight - height (pixels) to which to resize uploaded image
-#        $mimetype - reference to scalar to accommodate mime type determined
-#                    from File::MMagic if $parser = parse.
 # 
 # output: url of file in userspace, or error: <message> 
 #             or /adm/notfound.html if failure to upload occurse
 
 sub userfileupload {
-    my ($formname,$context,$subdir,$parser,$allfiles,$codebase,$destuname,
-        $destudom,$thumbwidth,$thumbheight,$resizewidth,$resizeheight,$mimetype)=@_;
+    my ($formname,$coursedoc,$subdir,$parser,$allfiles,$codebase,$destuname,
+        $destudom,$thumbwidth,$thumbheight,$resizewidth,$resizeheight)=@_;
     if (!defined($subdir)) { $subdir='unknown'; }
     my $fname=$env{'form.'.$formname.'.filename'};
     $fname=&clean_filename($fname);
-    # See if there is anything left
+# See if there is anything left
     unless ($fname) { return 'error: no uploaded file'; }
-    # 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')) ||
-         ($context eq 'existingfile') || ($context eq 'canceloverwrite')) {
+    chop($env{'form.'.$formname});
+    if (($formname eq 'screenshot') && ($subdir eq 'helprequests')) { #files uploaded to help request form are handled differently
         my $now = time;
-        my $filepath;
-        if (($formname eq 'screenshot') && ($subdir eq 'helprequests')) {
-             $filepath = 'tmp/helprequests/'.$now;
-        } elsif (($formname eq 'coursecreatorxml') && ($subdir eq 'batchupload')) {
-             $filepath = 'tmp/addcourse/'.$destudom.'/web/'.$env{'user.name'}.
-                         '_'.$env{'user.domain'}.'/pending';
-        } elsif (($context eq 'existingfile') || ($context eq 'canceloverwrite')) {
-            my ($docuname,$docudom);
-            if ($destudom) {
-                $docudom = $destudom;
-            } else {
-                $docudom = $env{'user.domain'};
-            }
-            if ($destuname) {
-                $docuname = $destuname;
-            } else {
-                $docuname = $env{'user.name'};
-            }
-            if (exists($env{'form.group'})) {
-                $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
-                $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
-            }
-            $filepath = 'tmp/overwrites/'.$docudom.'/'.$docuname.'/'.$subdir;
-            if ($context eq 'canceloverwrite') {
-                my $tempfile =  $perlvar{'lonDaemons'}.'/'.$filepath.'/'.$fname;
-                if (-e  $tempfile) {
-                    my @info = stat($tempfile);
-                    if ($info[9] eq $env{'form.timestamp'}) {
-                        unlink($tempfile);
-                    }
-                }
-                return;
+        my $filepath = 'tmp/helprequests/'.$now;
+        my @parts=split(/\//,$filepath);
+        my $fullpath = $perlvar{'lonDaemons'};
+        for (my $i=0;$i<@parts;$i++) {
+            $fullpath .= '/'.$parts[$i];
+            if ((-e $fullpath)!=1) {
+                mkdir($fullpath,0777);
             }
         }
-        # Create the directory if not present
+        open(my $fh,'>'.$fullpath.'/'.$fname);
+        print $fh $env{'form.'.$formname};
+        close($fh);
+        return $fullpath.'/'.$fname;
+    } elsif (($formname eq 'coursecreatorxml') && ($subdir eq 'batchupload')) { #files uploaded to create course page are handled differently
+        my $filepath = 'tmp/addcourse/'.$destudom.'/web/'.$env{'user.name'}.
+                       '_'.$env{'user.domain'}.'/pending';
         my @parts=split(/\//,$filepath);
         my $fullpath = $perlvar{'lonDaemons'};
         for (my $i=0;$i<@parts;$i++) {
@@ -2508,31 +2406,27 @@ sub userfileupload {
         open(my $fh,'>'.$fullpath.'/'.$fname);
         print $fh $env{'form.'.$formname};
         close($fh);
-        if ($context eq 'existingfile') {
-            my @info = stat($fullpath.'/'.$fname);
-            return ($fullpath.'/'.$fname,$info[9]);
-        } else {
-            return $fullpath.'/'.$fname;
-        }
+        return $fullpath.'/'.$fname;
     }
     if ($subdir eq 'scantron') {
         $fname = 'scantron_orig_'.$fname;
-    } else {
+    } else {   
+# Create the directory if not present
         $fname="$subdir/$fname";
     }
-    if ($context eq 'coursedoc') {
+    if ($coursedoc) {
 	my $docuname=$env{'course.'.$env{'request.course.id'}.'.num'};
 	my $docudom=$env{'course.'.$env{'request.course.id'}.'.domain'};
         if ($env{'form.folder'} =~ m/^(default|supplemental)/) {
             return &finishuserfileupload($docuname,$docudom,
 					 $formname,$fname,$parser,$allfiles,
 					 $codebase,$thumbwidth,$thumbheight,
-                                         $resizewidth,$resizeheight,$context,$mimetype);
+                                         $resizewidth,$resizeheight);
         } else {
             $fname=$env{'form.folder'}.'/'.$fname;
             return &process_coursefile('uploaddoc',$docuname,$docudom,
 				       $fname,$formname,$parser,
-				       $allfiles,$codebase,$mimetype);
+				       $allfiles,$codebase);
         }
     } elsif (defined($destuname)) {
         my $docuname=$destuname;
@@ -2540,7 +2434,8 @@ sub userfileupload {
 	return &finishuserfileupload($docuname,$docudom,$formname,$fname,
 				     $parser,$allfiles,$codebase,
                                      $thumbwidth,$thumbheight,
-                                     $resizewidth,$resizeheight,$context,$mimetype);
+                                     $resizewidth,$resizeheight);
+        
     } else {
         my $docuname=$env{'user.name'};
         my $docudom=$env{'user.domain'};
@@ -2551,13 +2446,13 @@ sub userfileupload {
 	return &finishuserfileupload($docuname,$docudom,$formname,$fname,
 				     $parser,$allfiles,$codebase,
                                      $thumbwidth,$thumbheight,
-                                     $resizewidth,$resizeheight,$context,$mimetype);
+                                     $resizewidth,$resizeheight);
     }
 }
 
 sub finishuserfileupload {
     my ($docuname,$docudom,$formname,$fname,$parser,$allfiles,$codebase,
-        $thumbwidth,$thumbheight,$resizewidth,$resizeheight,$context,$mimetype) = @_;
+        $thumbwidth,$thumbheight,$resizewidth,$resizeheight) = @_;
     my $path=$docudom.'/'.$docuname.'/';
     my $filepath=$perlvar{'lonDocRoot'};
   
@@ -2583,23 +2478,7 @@ sub finishuserfileupload {
 	    print STDERR ('Failed to create '.$filepath.'/'.$file."\n");
 	    return '/adm/notfound.html';
 	}
-        if ($context eq 'overwrite') {
-            my $source =  $perlvar{'lonDaemons'}.'/tmp/overwrites/'.$docudom.'/'.$docuname.'/'.$fname;
-            my $target = $filepath.'/'.$file;
-            if (-e $source) {
-                my @info = stat($source);
-                if ($info[9] eq $env{'form.timestamp'}) {
-                    unless (&File::Copy::move($source,$target)) {
-                        &logthis('Failed to overwrite '.$filepath.'/'.$file);
-                        return "Moving from $source failed";
-                    }
-                } else {
-                    return "Temporary file: $source had unexpected date/time for last modification";
-                }
-            } else {
-                return "Temporary file: $source missing";
-            }
-	} elsif (!print FH ($env{'form.'.$formname})) {
+	if (!print FH ($env{'form.'.$formname})) {
 	    &logthis('Failed to write to '.$filepath.'/'.$file);
 	    print STDERR ('Failed to write to '.$filepath.'/'.$file."\n");
 	    return '/adm/notfound.html';
@@ -2615,8 +2494,8 @@ sub finishuserfileupload {
     }
     if ($parser eq 'parse') {
         my $mm = new File::MMagic;
-        my $type = $mm->checktype_filename($filepath.'/'.$file);
-        if ($type eq 'text/html') {
+        my $mime_type = $mm->checktype_filename($filepath.'/'.$file);
+        if ($mime_type eq 'text/html') {
             my $parse_result = &extract_embedded_items($filepath.'/'.$file,
                                                        $allfiles,$codebase);
             unless ($parse_result eq 'ok') {
@@ -2624,9 +2503,6 @@ sub finishuserfileupload {
 	   	         ' for embedded media: '.$parse_result); 
             }
         }
-        if (ref($mimetype)) {
-            $$mimetype = $type;
-        }
     }
     if (($thumbwidth =~ /^\d+$/) && ($thumbheight =~ /^\d+$/)) {
         my $input = $filepath.'/'.$file;
@@ -3160,7 +3036,7 @@ sub get_my_roles {
     unless (defined($uname)) { $uname=$env{'user.name'}; }
     unless (defined($udom)) { $udom=$env{'user.domain'}; }
     my (%dumphash,%nothide);
-    if ($context eq 'userroles') { 
+    if ($context eq 'userroles') {
         my $extra = &freeze_escape({'skipcheck' => 1});
         %dumphash = &dump('roles',$udom,$uname,'.',undef,$extra);
     } else {
@@ -3490,7 +3366,7 @@ sub get_domain_roles {
     return %personnel;
 }
 
-# ----------------------------------------------------------- Check out an item
+# ----------------------------------------------------------- Interval timing 
 
 sub get_first_access {
     my ($type,$argsymb)=@_;
@@ -3526,91 +3402,6 @@ sub set_first_access {
     return 'already_set';
 }
 
-sub checkout {
-    my ($symb,$tuname,$tudom,$tcrsid)=@_;
-    my $now=time;
-    my $lonhost=$perlvar{'lonHostID'};
-    my $infostr=&escape(
-                 'CHECKOUTTOKEN&'.
-                 $tuname.'&'.
-                 $tudom.'&'.
-                 $tcrsid.'&'.
-                 $symb.'&'.
-		 $now.'&'.$ENV{'REMOTE_ADDR'});
-    my $token=&reply('tmpput:'.$infostr,$lonhost);
-    if ($token=~/^error\:/) { 
-        &logthis("<font color=\"blue\">WARNING: ".
-                "Checkout tmpput failed ".$tudom.' - '.$tuname.' - '.$symb.
-                 "</font>");
-        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' => $ENV{'REMOTE_ADDR'});
-
-    unless (&cstore(\%infohash,$symb,$tcrsid,$tudom,$tuname) eq 'ok') {
-       return '';
-    } else {
-        &logthis("<font color=\"blue\">WARNING: ".
-                "Checkout cstore failed ".$tudom.' - '.$tuname.' - '.$symb.
-                 "</font>");
-    }    
-
-    if (&log($tudom,$tuname,&homeserver($tuname,$tudom),
-                         &escape('Checkout '.$infostr.' - '.
-                                                 $token)) ne 'ok') {
-	return '';
-    } else {
-        &logthis("<font color=\"blue\">WARNING: ".
-                "Checkout log failed ".$tudom.' - '.$tuname.' - '.$symb.
-                 "</font>");
-    }
-    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 ($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' => $ENV{'REMOTE_ADDR'});
-
-    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 {
@@ -3715,7 +3506,7 @@ sub hashref2str {
       $result.='=';
       #print("Got a ref of ".(ref($key))." skipping.");
     } else {
-        if (defined($key)) {$result.=&escape($key).'=';} else { last; }
+	if ($key) {$result.=&escape($key).'=';} else { last; }
     }
 
     if(ref($hashref->{$key}) eq 'ARRAY') {
@@ -4355,7 +4146,7 @@ sub set_userprivs {
     my $adv=0;
     my %grouproles = ();
     if (keys(%{$allgroups}) > 0) {
-        my @groupkeys;
+        my @groupkeys; 
         foreach my $role (keys(%{$allroles})) {
             push(@groupkeys,$role);
         }
@@ -4431,7 +4222,7 @@ sub role_status {
                             my %userroles = (
                                 'user.role.'.$$role.'.'.$$where => $$tstart.'.'.$$tend
                             );
-                            @rolecodes = ('cm');
+                            @rolecodes = ('cm'); 
                             my $spec=$$role.'.'.$$where;
                             my ($tdummy,$tdomain,$trest)=split(/\//,$$where);
                             if ($$role =~ /^cr\//) {
@@ -4448,7 +4239,7 @@ sub role_status {
                                 my %course_roles = &get_my_roles($env{'user.name'},$env{'user.domain'},'userroles',['active'],['cc','co','in','ta','ep','ad','st','cr'],[$tdomain],1);
                                 if (keys(%course_roles) > 0) {
                                     my ($tnum) = ($trest =~ /^($match_courseid)/);
-                                    if ($tdomain ne '' && $tnum ne '') {
+                                    if ($tdomain ne '' && $tnum ne '') { 
                                         foreach my $key (keys(%course_roles)) {
                                             if ($key =~ /^\Q$tnum\E:\Q$tdomain\E:([^:]+):?([^:]*)/) {
                                                 my $crsrole = $1;
@@ -4496,22 +4287,22 @@ sub role_status {
 }
 
 sub check_adhoc_privs {
-    my ($cdom,$cnum,$then,$refresh,$now,$checkrole,$caller) = @_;
+    my ($cdom,$cnum,$then,$refresh,$now,$checkrole) = @_;
     my $cckey = 'user.role.'.$checkrole.'./'.$cdom.'/'.$cnum;
     if ($env{$cckey}) {
         my ($role,$where,$trolecode,$tstart,$tend,$tremark,$tstatus,$tpstart,$tpend);
         &role_status($cckey,$then,$refresh,$now,\$role,\$where,\$trolecode,\$tstatus,\$tstart,\$tend);
         unless (($tstatus eq 'is') || ($tstatus eq 'will_not')) {
-            &set_adhoc_privileges($cdom,$cnum,$checkrole,$caller);
+            &set_adhoc_privileges($cdom,$cnum,$checkrole);
         }
     } else {
-        &set_adhoc_privileges($cdom,$cnum,$checkrole,$caller);
+        &set_adhoc_privileges($cdom,$cnum,$checkrole);
     }
 }
 
 sub set_adhoc_privileges {
 # role can be cc or ca
-    my ($dcdom,$pickedcourse,$role,$caller) = @_;
+    my ($dcdom,$pickedcourse,$role) = @_;
     my $area = '/'.$dcdom.'/'.$pickedcourse;
     my $spec = $role.'.'.$area;
     my %userroles = &set_arearole($role,$area,'','',$env{'user.domain'},
@@ -4521,16 +4312,14 @@ sub set_adhoc_privileges {
     my ($author,$adv)= &set_userprivs(\%userroles,\%ccrole);
     &appenv(\%userroles,[$role,'cm']);
     &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'  => ''
-                 }
-               );
-        my $tadv=0;
-        if (&allowed('adv') eq 'F') { $tadv=1; }
-        &appenv({'request.role.adv'    => $tadv});
-    }
+    &appenv( {'request.role'        => $spec,
+              'request.role.domain' => $dcdom,
+              'request.course.sec'  => ''
+             }
+           );
+    my $tadv=0;
+    if (&allowed('adv') eq 'F') { $tadv=1; }
+    &appenv({'request.role.adv'    => $tadv});
 }
 
 # --------------------------------------------------------------- get interface
@@ -5133,7 +4922,7 @@ sub is_portfolio_file {
 }
 
 sub usertools_access {
-    my ($uname,$udom,$tool,$action,$context,$userenvref,$domdefref,$is_advref) = @_;
+    my ($uname,$udom,$tool,$action,$context,$userenvref,$domdefref,$is_advref)=@_;
     my ($access,%tools);
     if ($context eq '') {
         $context = 'tools';
@@ -5280,7 +5069,7 @@ sub is_advanced_user {
     my ($udom,$uname) = @_;
     if ($udom ne '' && $uname ne '') {
         if (($udom eq $env{'user.domain'}) && ($uname eq $env{'user.name'})) {
-            return $env{'user.adv'};
+            return $env{'user.adv'};  
         }
     }
     my %roleshash = &get_my_roles($uname,$udom,'userroles',undef,undef,undef,1);
@@ -5798,7 +5587,7 @@ sub allowed {
        my $unamedom=$env{'user.name'}.':'.$env{'user.domain'};
        if ($env{'course.'.$env{'request.course.id'}.'.'.$priv.'.roles.denied'}
 	   =~/\Q$rolecode\E/) {
-           if (($priv ne 'pch') && ($priv ne 'plc')) {
+	   if ($priv ne 'pch') { 
 	       &logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}.':'.
 			'Denied by role: '.$priv.' for '.$uri.' as '.$rolecode.' in '.
 			$env{'request.course.id'});
@@ -5808,7 +5597,7 @@ sub allowed {
 
        if ($env{'course.'.$env{'request.course.id'}.'.'.$priv.'.users.denied'}
 	   =~/\Q$unamedom\E/) {
-           if (($priv ne 'pch') && ($priv ne 'plc')) {
+	   if ($priv ne 'pch') { 
 	       &logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}.
 			'Denied by user: '.$priv.' for '.$uri.' as '.$unamedom.' in '.
 			$env{'request.course.id'});
@@ -5822,7 +5611,7 @@ sub allowed {
    if ($thisallowed=~/R/) {
        my $rolecode=(split(/\./,$env{'request.role'}))[0];
        if (&metadata($uri,'roledeny')=~/\Q$rolecode\E/) {
-           if (($priv ne 'pch') && ($priv ne 'plc')) {
+	   if ($priv ne 'pch') { 
 	       &logthis($env{'user.domain'}.':'.$env{'user.name'}.':'.$env{'user.home'}.':'.
 			'Denied by role: '.$priv.' for '.$uri.' as '.$rolecode);
 	   }
@@ -6175,9 +5964,9 @@ sub auto_get_sections {
 }
 
 sub auto_new_course {
-    my ($cnum,$cdom,$inst_course_id,$owner,$coowners) = @_;
+    my ($cnum,$cdom,$inst_course_id,$owner) = @_;
     my $homeserver = &homeserver($cnum,$cdom);
-    my $response=&unescape(&reply('autonewcourse:'.$inst_course_id.':'.&escape($owner).':'.$cdom.':'.&escape($coowners),$homeserver));
+    my $response=&unescape(&reply('autonewcourse:'.$inst_course_id.':'.$owner.':'.$cdom,$homeserver));
     return $response;
 }
 
@@ -6749,13 +6538,6 @@ sub assignrole {
                     return 'refused';
                 }
             }
-        } elsif ($role eq 'au') {
-            if ($url ne '/'.$udom.'/') {
-                &logthis('Attempt by '.$env{'user.name'}.':'.$env{'user.domain'}.
-                         ' to assign author role for '.$uname.':'.$udom.
-                         ' in domain: '.$url.' refused (wrong domain).');
-                return 'refused';
-            }
         }
         $mrole=$role;
     }
@@ -6930,7 +6712,7 @@ sub modifyuser {
     }
     &logthis('Call to modify user '.$udom.', '.$uname.', '.$uid.', '.
              $umode.', '.$first.', '.$middle.', '.
-             $last.', '.$gene.'(forceid: '.$forceid.'; candelete: '.$showcandelete.')'.
+	     $last.', '.$gene.'(forceid: '.$forceid.'; candelete: '.$showcandelete.')'.
              (defined($desiredhome) ? ' desiredhome = '.$desiredhome :
                                      ' desiredhome not specified'). 
              ' by '.$env{'user.name'}.' at '.$env{'user.domain'}.
@@ -7076,7 +6858,7 @@ sub modifyuser {
         return 'ok';
     }
     my $reply = &put('environment', \%names, $udom,$uname);
-    if ($reply ne 'ok') {
+    if ($reply ne 'ok') { 
         return 'error: '.$reply;
     }
     if ($names{'permanentemail'} ne $oldnames{'permanentemail'}) {
@@ -7401,8 +7183,8 @@ sub store_userdata {
                     $namevalue.=&escape($key).'='.&freeze_escape($$storehash{$key}).'&';
                 }
                 $namevalue=~s/\&$//;
-                $result =  &reply("store:$udom:$uname:$namespace:$datakey:".
-                                  $namevalue,$uhome);
+                $result =  &reply("store:$env{'user.domain'}:$env{'user.name'}:".
+                                  "$namespace:$datakey:$namevalue",$uhome);
             }
         } else {
             $result = 'error: data to store was not a hash reference'; 
@@ -7455,10 +7237,10 @@ sub diskusage {
 }
 
 sub is_locked {
-    my ($file_name, $domain, $user, $which) = @_;
+    my ($file_name, $domain, $user) = @_;
     my @check;
     my $is_locked;
-    push(@check,$file_name);
+    push @check, $file_name;
     my %locked = &get('file_permissions',\@check,
 		      $env{'user.domain'},$env{'user.name'});
     my ($tmp)=keys(%locked);
@@ -7467,19 +7249,14 @@ sub is_locked {
     if (ref($locked{$file_name}) eq 'ARRAY') {
         $is_locked = 'false';
         foreach my $entry (@{$locked{$file_name}}) {
-           if (ref($entry) eq 'ARRAY') {
+           if (ref($entry) eq 'ARRAY') { 
                $is_locked = 'true';
-               if (ref($which) eq 'ARRAY') {
-                   push(@{$which},$entry);
-               } else {
-                   last;
-               }
+               last;
            }
        }
     } else {
         $is_locked = 'false';
     }
-    return $is_locked;
 }
 
 sub declutter_portfile {
@@ -8622,6 +8399,7 @@ sub add_prefix_and_part {
 # ---------------------------------------------------------------- Get metadata
 
 my %metaentry;
+my %importedpartids;
 sub metadata {
     my ($uri,$what,$liburi,$prefix,$depthcount)=@_;
     $uri=&declutter($uri);
@@ -8629,7 +8407,7 @@ sub metadata {
     if (($uri eq '') || 
 	(($uri =~ m|^/*adm/|) && 
 	     ($uri !~ m|^adm/includes|) && ($uri !~ m|/bulletinboard$|)) ||
-        ($uri =~ m|/$|) || ($uri =~ m|/.meta$|) || ($uri =~ m{^/*uploaded/.+\.sequence$})) {
+        ($uri =~ m|/$|) || ($uri =~ m|/.meta$|) ) {
 	return undef;
     }
     if (($uri =~ /^~/ || $uri =~ m{home/$match_username/public_html/}) 
@@ -8648,6 +8426,10 @@ sub metadata {
 	if (defined($cached)) { return $result->{':'.$what}; }
     }
     {
+# Imported parts would go here
+        my %importedids=();
+        my @origfileimportpartids=();
+        my $importedparts=0;
 #
 # Is this a recursive call for a library?
 #
@@ -8671,8 +8453,7 @@ sub metadata {
 		&Apache::lonnet::ssi_body($which,
 					  ('grade_target' => 'meta'));
 	    $cachetime = 1; # only want this cached in the child not long term
-	} elsif (($uri !~ m -^(editupload)/-) && 
-                 ($uri !~ m{^/*uploaded/$match_domain/$match_courseid/docs/})) {
+	} elsif ($uri !~ m -^(editupload)/-) {
 	    my $file=&filelocation('',&clutter($filename));
 	    #push(@{$metaentry{$uri.'.file'}},$file);
 	    $metastring=&getfile($file);
@@ -8732,27 +8513,55 @@ sub metadata {
 # This is not a package - some other kind of start tag
 #
 		    my $entry=$token->[1];
-		    my $unikey;
-		    if ($entry eq 'import') {
-			$unikey='';
-		    } else {
-			$unikey=$entry;
-		    }
-		    $unikey.=&add_prefix_and_part($prefix,$token->[2]->{'part'});
-
-		    if (defined($token->[2]->{'id'})) { 
-			$unikey.='_'.$token->[2]->{'id'}; 
-		    }
+		    my $unikey='';
 
 		    if ($entry eq 'import') {
 #
 # Importing a library here
 #
+                        my $location=$parser->get_text('/import');
+                        my $dir=$filename;
+                        $dir=~s|[^/]*$||;
+                        $location=&filelocation($dir,$location);
+                       
+                        my $importmode=$token->[2]->{'importmode'};
+                        if ($importmode eq 'problem') {
+# Import as problem/response
+                           $unikey=&add_prefix_and_part($prefix,$token->[2]->{'part'});
+                        } elsif ($importmode eq 'part') {
+# Import as part(s)
+                           $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 ($#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
+                           my $impfile=&getfile($location);
+                           my @impfilepartids=($impfile=~/<part[^>]*id\s*=\s*[\"\']([^\"\']+)[\"\'][^>]*>/gs);
+                           if ($#impfilepartids>=0) {
+# This problem had parts
+                               $importedpartids{$token->[2]->{'id'}}=join(',',@impfilepartids);
+                           } else {
+# Importing by turning a single problem into a problem part
+# It gets the import-tags ID as part-ID
+                               $unikey=&add_prefix_and_part($prefix,$token->[2]->{'id'});
+                               $importedpartids{$token->[2]->{'id'}}=$token->[2]->{'id'};
+                           }
+                        } else {
+# Normal import
+                           $unikey=&add_prefix_and_part($prefix,$token->[2]->{'part'});
+                           if (defined($token->[2]->{'id'})) {
+                              $unikey.='_'.$token->[2]->{'id'};
+                           }
+                        }
+
 			if ($depthcount<20) {
-			    my $location=$parser->get_text('/import');
-			    my $dir=$filename;
-			    $dir=~s|[^/]*$||;
-			    $location=&filelocation($dir,$location);
 			    my $metadata = 
 				&metadata($uri,'keys', $location,$unikey,
 					  $depthcount+1);
@@ -8760,8 +8569,16 @@ sub metadata {
 				$metaentry{':'.$meta}=$metaentry{':'.$meta};
 				$metathesekeys{$meta}=1;
 			    }
-			}
-		    } else { 
+			
+                        }
+		    } else {
+#
+# Not importing, some other kind of non-package, non-library start tag
+# 
+                        $unikey=$entry.&add_prefix_and_part($prefix,$token->[2]->{'part'});
+                        if (defined($token->[2]->{'id'})) {
+                            $unikey.='_'.$token->[2]->{'id'};
+                        }
 			if (defined($token->[2]->{'name'})) { 
 			    $unikey.='_'.$token->[2]->{'name'}; 
 			}
@@ -8835,6 +8652,22 @@ sub metadata {
 	    grep { ! $seen{$_} ++ } (split(',',$metaentry{':packages'}));
 	$metaentry{':packages'} = join(',',@uniq_packages);
 
+        if ($importedparts) {
+# We had imported parts and need to rebuild partorder
+           $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);
@@ -9020,8 +8853,7 @@ sub symbverify {
         }
         my $ids=$bighash{'ids_'.&clutter($thisurl)};
         unless ($ids) { 
-           my $idkey = 'ids_'.($thisurl =~ m{^/}? '' : '/').$thisurl;
-           $ids=$bighash{$idkey};
+           $ids=$bighash{'ids_/'.$thisurl};
         }
         if ($ids) {
 # ------------------------------------------------------------------- Has ID(s)
@@ -9034,8 +8866,7 @@ sub symbverify {
   &symbclean(&declutter($bighash{'map_id_'.$mapid}).'___'.$resid.'___'.$thisfn)
    eq $symb) { 
 		   if (($env{'request.role.adv'}) ||
-		       ($bighash{'encrypted_'.$id} eq $env{'request.enc'}) ||
-		       ($thisurl eq '/adm/navmaps')) {
+		       $bighash{'encrypted_'.$id} eq $env{'request.enc'}) {
 		       $okay=1; 
 		   }
 	       }
@@ -10030,7 +9861,6 @@ sub get_dns {
     while (%alldns) {
 	my ($dns) = keys(%alldns);
 	my $ua=new LWP::UserAgent;
-        $ua->timeout(30);
 	my $request=new HTTP::Request('GET',"$alldns{$dns}://$dns$url");
 	my $response=$ua->request($request);
         delete($alldns{$dns});
@@ -10115,19 +9945,13 @@ sub get_dns {
     my $loaded;
     my %name_to_host;
     my %internetdom;
-    my %LC_dns_serv;
 
     sub parse_hosts_tab {
 	my ($file) = @_;
 	foreach my $configline (@$file) {
 	    next if ($configline =~ /^(\#|\s*$ )/x);
-            chomp($configline);
-            if ($configline =~ /^\^/) {
-                if ($configline =~ /^\^([\w.\-]+)/) {
-                    $LC_dns_serv{$1} = 1;
-                }
-                next;
-            }
+	    next if ($configline =~ /^\^/);
+	    chomp($configline);
 	    my ($id,$domain,$role,$name,$protocol,$intdom)=split(/:/,$configline);
 	    $name=~s/\s//g;
 	    if ($id && $domain && $role && $name) {
@@ -10209,7 +10033,7 @@ sub get_dns {
     }
 
     sub unique_library {
-        #2x reverse removes all hostnames that appear more than once
+	#2x reverse removes all hostnames that appear more than once
         my %unique = reverse &all_library();
         return reverse %unique;
     }
@@ -10239,7 +10063,7 @@ sub get_dns {
 
     sub get_unique_servers {
         my %unique = reverse &get_servers(@_);
-        return reverse %unique;
+	return reverse %unique;
     }
 
     sub host_domain {
@@ -10263,14 +10087,6 @@ sub get_dns {
         my ($lonid) = @_;
         return $internetdom{$lonid};
     }
-
-    sub is_LC_dns {
-        &load_hosts_tab() if (!$loaded);
-
-        my ($hostname) = @_;
-        return exists($LC_dns_serv{$hostname});
-    }
-
 }
 
 { 
@@ -10546,22 +10362,6 @@ BEGIN {
     }
 }
 
-# ---------------------------------------------------------- Read managers table
-{
-    if (-e "$perlvar{'lonTabDir'}/managers.tab") {
-        if (open(my $config,"<$perlvar{'lonTabDir'}/managers.tab")) {
-            while (my $configline=<$config>) {
-                chomp($configline);
-                next if ($configline =~ /^\#/);
-                if (($configline =~ /^[\w\-]+$/) || ($configline =~ /^[\w\-]+\:[\w\-]+$/)) {
-                    $managerstab{$configline} = 1;
-                }
-            }
-            close($config);
-        }
-    }
-}
-
 # ------------- set up temporary directory
 {
     $tmpdir = $perlvar{'lonDaemons'}.'/tmp/';
@@ -10799,7 +10599,7 @@ $checkdefauth is optional (value is 1 if
    authenticate user using default authentication method, and allow
    account creation if username does not have account in the domain).
 $clientcancheckhost is optional (value is 1 if checking whether the
-   server can host will occur on the client side in lonauth.pm).
+   server can host will occur on the client side in lonauth.pm).   
 
 =item *
 X<homeserver()>
@@ -11455,11 +11255,11 @@ splitting on '&', supports elements that
 
 =head2 Logging Routines
 
+=over 4
+
 These routines allow one to make log messages in the lonnet.log and
 lonnet.perm logfiles.
 
-=over 4
-
 =item *
 
 logtouch() : make sure the logfile, lonnet.log, exists
@@ -11548,10 +11348,8 @@ userfileupload(): main rotine for puttin
            filename, and the contents of the file to create/modifed exist
            the filename is in $env{'form.'.$formname.'.filename'} and the
            contents of the file is located in $env{'form.'.$formname}
- context - if coursedoc, store the file in the course of the active role
-             of the current user;
-           if 'existingfile': store in 'overwrites' in /home/httpd/perl/tmp
-           if 'canceloverwrite': delete file in tmp/overwrites directory
+ coursedoc - if true, store the file in the course of the active role
+             of the current user
  subdir - required - subdirectory to put the file in under ../userfiles/
          if undefined, it will be placed in "unknown"
 
@@ -11573,29 +11371,16 @@ returns: the new clean filename
 
 =item *
 
-finishuserfileupload(): routine that creates and sends the file to
+finishuserfileupload(): routine that creaes and sends the file to
 userspace, probably shouldn't be called directly
 
   docuname: username or courseid of destination for the file
   docudom: domain of user/course of destination for the file
   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.
-  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
-  thumbheight: height (pixels) of thumbnail to be created for uploaded image
-  resizewidth: width to be used to resize image using resizeImage from ImageMagick
-  resizeheight: height to be used to resize image using resizeImage from ImageMagick
-  context: if 'overwrite', will move the uploaded file from its temporary location to
-            userfiles to facilitate overwriting a previously uploaded file with same name.
-  mimetype: reference to scalar to accommodate mime type determined
-            from File::MMagic if $parser = parse.
+  fname: filename (inculding subdirectories) for the file
 
  returns either the url of the uploaded file (/uploaded/....) if successful
- and /adm/notfound.html if unsuccessful (or an error message if context 
- was 'overwrite').
-
+ and /adm/notfound.html if unsuccessful
 
 =item *