--- loncom/lond	2006/02/02 10:32:31	1.305.2.2
+++ loncom/lond	2006/02/21 18:43:37	1.321
@@ -2,7 +2,7 @@
 # The LearningOnline Network
 # lond "LON Daemon" Server (port "LOND" 5663)
 #
-# $Id: lond,v 1.305.2.2 2006/02/02 10:32:31 albertel Exp $
+# $Id: lond,v 1.321 2006/02/21 18:43:37 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -61,7 +61,7 @@ my $status='';
 my $lastlog='';
 my $lond_max_wait_time = 13;
 
-my $VERSION='$Revision: 1.305.2.2 $'; #' stupid emacs
+my $VERSION='$Revision: 1.321 $'; #' stupid emacs
 my $remoteVERSION;
 my $currenthostid="default";
 my $currentdomainid;
@@ -89,6 +89,7 @@ my $ConnectionType;
 
 my %hostid;			# ID's for hosts in cluster by ip.
 my %hostdom;			# LonCAPA domain for hosts in cluster.
+my %hostname;			# DNSname -> ID's mapping.
 my %hostip;			# IPs for hosts in cluster.
 my %hostdns;			# ID's of hosts looked up by DNS name.
 
@@ -2975,22 +2976,39 @@ sub dump_with_regexp {
 
     my $userinput = "$cmd:$tail";
 
-    my ($udom,$uname,$namespace,$regexp)=split(/:/,$tail);
+    my ($udom,$uname,$namespace,$regexp,$range)=split(/:/,$tail);
     if (defined($regexp)) {
 	$regexp=&unescape($regexp);
     } else {
 	$regexp='.';
     }
+    my ($start,$end);
+    if (defined($range)) {
+	if ($range =~/^(\d+)\-(\d+)$/) {
+	    ($start,$end) = ($1,$2);
+	} elsif ($range =~/^(\d+)$/) {
+	    ($start,$end) = (0,$1);
+	} else {
+	    undef($range);
+	}
+    }
     my $hashref = &tie_user_hash($udom, $uname, $namespace,
 				 &GDBM_READER());
     if ($hashref) {
         my $qresult='';
+	my $count=0;
 	while (my ($key,$value) = each(%$hashref)) {
 	    if ($regexp eq '.') {
+		$count++;
+		if (defined($range) && $count >= $end)   { last; }
+		if (defined($range) && $count <  $start) { next; }
 		$qresult.=$key.'='.$value.'&';
 	    } else {
 		my $unescapeKey = &unescape($key);
 		if (eval('$unescapeKey=~/$regexp/')) {
+		    $count++;
+		    if (defined($range) && $count >= $end)   { last; }
+		    if (defined($range) && $count <  $start) { next; }
 		    $qresult.="$key=$value&";
 		}
 	    }
@@ -4318,6 +4336,83 @@ sub get_institutional_code_format_handle
 &register_handler("autoinstcodeformat",
 		  \&get_institutional_code_format_handler,0,1,0);
 
+# Get domain specific conditions for import of student photographs to a course
+#
+# Retrieves information from photo_permission subroutine in localenroll.
+# Returns outcome (ok) if no processing errors, and whether course owner is 
+# required to accept conditions of use (yes/no).
+#
+#    
+sub photo_permission_handler {
+    my ($cmd, $tail, $client)   = @_;
+    my $userinput               = "$cmd:$tail";
+    my $cdom = $tail;
+    my ($perm_reqd,$conditions);
+    my $outcome;
+    eval {
+	local($SIG{__DIE__})='DEFAULT';
+	$outcome = &localenroll::photo_permission($cdom,\$perm_reqd,
+						  \$conditions);
+    };
+    if (!$@) {
+	&Reply($client, &escape($outcome.':'.$perm_reqd.':'. $conditions)."\n",
+	       $userinput);
+    } else {
+	&Failure($client,"unknown_cmd\n",$userinput);
+    }
+    return 1;
+}
+&register_handler("autophotopermission",\&photo_permission_handler,0,1,0);
+
+#
+# Checks if student photo is available for a user in the domain, in the user's
+# directory (in /userfiles/internal/studentphoto.jpg).
+# Uses localstudentphoto:fetch() to ensure there is an up to date copy of
+# the student's photo.   
+
+sub photo_check_handler {
+    my ($cmd, $tail, $client)   = @_;
+    my $userinput               = "$cmd:$tail";
+    my ($udom,$uname,$pid) = split(/:/,$tail);
+    $udom = &unescape($udom);
+    $uname = &unescape($uname);
+    $pid = &unescape($pid);
+    my $path=&propath($udom,$uname).'/userfiles/internal/';
+    if (!-e $path) {
+        &mkpath($path);
+    }
+    my $response;
+    my $result = &localstudentphoto::fetch($udom,$uname,$pid,\$response);
+    $result .= ':'.$response;
+    &Reply($client, &escape($result)."\n",$userinput);
+    return 1;
+}
+&register_handler("autophotocheck",\&photo_check_handler,0,1,0);
+
+#
+# Retrieve information from localenroll about whether to provide a button     
+# for users who have enbled import of student photos to initiate an 
+# update of photo files for registered students. Also include 
+# comment to display alongside button.  
+
+sub photo_choice_handler {
+    my ($cmd, $tail, $client) = @_;
+    my $userinput             = "$cmd:$tail";
+    my $cdom                  = &unescape($tail);
+    my ($update,$comment);
+    eval {
+	local($SIG{__DIE__})='DEFAULT';
+	($update,$comment)    = &localenroll::manager_photo_update($cdom);
+    };
+    if (!$@) {
+	&Reply($client,&escape($update).':'.&escape($comment)."\n",$userinput);
+    } else {
+	&Failure($client,"unknown_cmd\n",$userinput);
+    }
+    return 1;
+}
+&register_handler("autophotochoice",\&photo_choice_handler,0,1,0);
+
 #
 # Gets a student's photo to exist (in the correct image type) in the user's 
 # directory.
@@ -4330,24 +4425,36 @@ sub get_institutional_code_format_handle
 #    $client  - The socket open on the client.
 # Returns:
 #    1 - continue processing.
+
 sub student_photo_handler {
     my ($cmd, $tail, $client) = @_;
-    my ($domain,$uname,$type) = split(/:/, $tail);
+    my ($domain,$uname,$ext,$type) = split(/:/, $tail);
 
-    my $path=&propath($domain,$uname).
-	'/userfiles/internal/studentphoto.'.$type;
-    if (-e $path) {
+    my $path=&propath($domain,$uname). '/userfiles/internal/';
+    my $filename = 'studentphoto.'.$ext;
+    if ($type eq 'thumbnail') {
+        $filename = 'studentphoto_tn.'.$ext;
+    }
+    if (-e $path.$filename) {
 	&Reply($client,"ok\n","$cmd:$tail");
 	return 1;
     }
     &mkpath($path);
-    my $file=&localstudentphoto::fetch($domain,$uname);
+    my $file;
+    if ($type eq 'thumbnail') {
+	eval {
+	    local($SIG{__DIE__})='DEFAULT';
+	    $file=&localstudentphoto::fetch_thumbnail($domain,$uname);
+	};
+    } else {
+        $file=&localstudentphoto::fetch($domain,$uname);
+    }
     if (!$file) {
 	&Failure($client,"unavailable\n","$cmd:$tail");
 	return 1;
     }
-    if (!-e $path) { &convert_photo($file,$path); }
-    if (-e $path) {
+    if (!-e $path.$filename) { &convert_photo($file,$path.$filename); }
+    if (-e $path.$filename) {
 	&Reply($client,"ok\n","$cmd:$tail");
 	return 1;
     }
@@ -4762,6 +4869,7 @@ sub ReadHostTable {
 	    }
 	    $hostid{$ip}=$id;         # LonCAPA name of host by IP.
 	    $hostdom{$id}=$domain;    # LonCAPA domain name of host. 
+	    $hostname{$id}=$name;     # LonCAPA name -> DNS name
 	    $hostip{$id}=$ip;         # IP address of host.
 	    $hostdns{$name} = $id;    # LonCAPA name of host by DNS.
 
@@ -5012,12 +5120,12 @@ sub reconlonc {
 
 sub subreply {
     my ($cmd,$server)=@_;
-    my $peerfile="$perlvar{'lonSockDir'}/$server";
+    my $peerfile="$perlvar{'lonSockDir'}/".$hostname{$server};
     my $sclient=IO::Socket::UNIX->new(Peer    =>"$peerfile",
                                       Type    => SOCK_STREAM,
                                       Timeout => 10)
        or return "con_lost";
-    print $sclient "$cmd\n";
+    print $sclient "sethost:$server:$cmd\n";
     my $answer=<$sclient>;
     chomp($answer);
     if (!$answer) { $answer="con_lost"; }
@@ -5033,7 +5141,7 @@ sub reply {
 	$answer=subreply("ping",$server);
         if ($answer ne $server) {
 	    &logthis("sub reply: answer != server answer is $answer, server is $server");
-           &reconlonc("$perlvar{'lonSockDir'}/$server");
+           &reconlonc("$perlvar{'lonSockDir'}/".$hostname{$server});
         }
         $answer=subreply($cmd,$server);
     }
@@ -5060,7 +5168,7 @@ sub sub_sql_reply {
                                       Type    => SOCK_STREAM,
                                       Timeout => 10)
        or return "con_lost";
-    print $sclient "$cmd\n";
+    print $sclient "$cmd:$currentdomainid\n";
     my $answer=<$sclient>;
     chomp($answer);
     if (!$answer) { $answer="con_lost"; }
@@ -5339,7 +5447,7 @@ sub make_new_child {
 		    # no need to try to do recon's to myself
 		    next;
 		}
-		&reconlonc("$perlvar{'lonSockDir'}/$id");
+		&reconlonc("$perlvar{'lonSockDir'}/".$hostname{$id});
 	    }
 	    &logthis("<font color='green'>Established connection: $clientname</font>");
 	    &status('Will listen to '.$clientname);
@@ -5395,8 +5503,11 @@ sub is_author {
 
     #  Author role should show up as a key /domain/_au
 
-    my $key   = "/$domain/_au";
-    my $value = $hashref->{$key};
+    my $key    = "/$domain/_au";
+    my $value;
+    if (defined($hashref)) {
+	$value = $hashref->{$key};
+    }
 
     if(defined($value)) {
 	&Debug("$user @ $domain is an author");