--- loncom/lond	2006/02/09 20:48:40	1.318.2.3
+++ loncom/lond	2006/03/04 04:27:38	1.318.2.6
@@ -2,7 +2,7 @@
 # The LearningOnline Network
 # lond "LON Daemon" Server (port "LOND" 5663)
 #
-# $Id: lond,v 1.318.2.3 2006/02/09 20:48:40 albertel Exp $
+# $Id: lond,v 1.318.2.6 2006/03/04 04:27:38 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.318.2.3 $'; #' stupid emacs
+my $VERSION='$Revision: 1.318.2.6 $'; #' stupid emacs
 my $remoteVERSION;
 my $currenthostid="default";
 my $currentdomainid;
@@ -2915,16 +2915,15 @@ sub dump_profile_database {
 	while (my ($key,$value) = each(%$hashref)) {
 	    my ($v,$symb,$param) = split(/:/,$key);
 	    next if ($v eq 'version' || $symb eq 'keys');
-	    if (!defined($param)) {
-		foreach my $pair (split(/\&/,$value)) {
-		    my ($param,$value)=split(/=/,$pair);
-		    next if (exists($data{$symb}) && 
-			     exists($data{$symb}->{$param}) &&
-			     $data{$symb}->{'v.'.$param} > $v);
-		    $data{$symb}->{$param}=$value;
-		    $data{$symb}->{'v.'.$param}=$v;
-		}
+	    # making old style store  entries '$ver:$symb:$key = $value'
+	    # look like new             '$ver:compressed:$symb = "$key=$value"'
+	    if ($symb eq 'compressed') {
+		$symb = $param;
 	    } else {
+		$value = $param.'='.$value;
+	    }
+	    foreach my $pair (split(/\&/,$value)) {
+		my ($param,$value)=split(/=/,$pair);
 		next if (exists($data{$symb}) && 
 			 exists($data{$symb}->{$param}) &&
 			 $data{$symb}->{'v.'.$param} > $v);
@@ -3082,7 +3081,7 @@ sub store_handler {
 		my ($key)=split(/=/,$pair);
 		$allkeys.=$key.':';
 	    }
-	    $hashref->{"$version:$rid"}=$what."\&timestamp=$now";
+	    $hashref->{"$version:compressed:$rid"}=$what."\&timestamp=$now";
 	    $allkeys.='timestamp';
 	    $hashref->{"$version:keys:$rid"}=$allkeys;
 	    if (&untie_user_hash($hashref)) {
@@ -3103,6 +3102,75 @@ sub store_handler {
 }
 &register_handler("store", \&store_handler, 0, 1, 0);
 
+sub putstore_handler {
+    my ($cmd, $tail, $client) = @_;
+ 
+    my $userinput = "$cmd:$tail";
+
+    my ($udom,$uname,$namespace,$rid,$v,$what) =split(/:/,$tail);
+    if ($namespace ne 'roles') {
+
+	chomp($what);
+	my $hashref  = &tie_user_hash($udom, $uname, $namespace,
+				       &GDBM_WRCREAT(), "C",
+				       "$rid:$what");
+	if ($hashref) {
+	    my $now = time;
+	    my %data = &hash_extract($what);
+	    my @allkeys;
+	    if (exists($hashref->{"$v:compressed:$rid"})) {
+		my %current = &hash_extract($hashref->{"$v:compressed:$rid"});
+		while (my($key,$value) = each(%data)) {
+		    push(@allkeys,$key);
+		    $current{$key} = $value;
+		}
+		$hashref->{"$v:compressed:$rid"}= &hash_to_str(\%current);
+	    } else {
+		while (my($key,$value) = each(%data)) {
+		    push(@allkeys,$key);
+		    $hashref->{"$v:$rid:$key"} = $value;
+		}
+	    }
+	    my $allkeys = join(':',@allkeys);
+	    $hashref->{"$v:keys:$rid"}=$allkeys;
+
+	    if (&untie_user_hash($hashref)) {
+		&Reply($client, "ok\n", $userinput);
+	    } else {
+		&Failure($client, "error: ".($!+0)." untie(GDBM) Failed ".
+			"while attempting store\n", $userinput);
+	    }
+	} else {
+	    &Failure( $client, "error: ".($!+0)." tie(GDBM) Failed ".
+		     "while attempting store\n", $userinput);
+	}
+    } else {
+	&Failure($client, "refused\n", $userinput);
+    }
+
+    return 1;
+}
+&register_handler("putstore", \&putstore_handler, 0, 1, 0);
+
+sub hash_extract {
+    my ($str)=@_;
+    my %hash;
+    foreach my $pair (split(/\&/,$str)) {
+	my ($key,$value)=split(/=/,$pair);
+	$hash{$key}=$value;
+    }
+    return (%hash);
+}
+sub hash_to_str {
+    my ($hash_ref)=@_;
+    my $str;
+    foreach my $key (keys(%$hash_ref)) {
+	$str.=$key.'='.$hash_ref->{$key}.'&';
+    }
+    $str=~s/\&$//;
+    return $str;
+}
+
 #
 #  Dump out all versions of a resource that has key=value pairs associated
 # with it for each version.  These resources are built up via the store
@@ -3148,9 +3216,8 @@ sub restore_handler {
 	    my @keys=split(/:/,$vkeys);
 	    my $key;
 	    $qresult.="$scope:keys=$vkeys&";
-	    if (exists($hashref->{"$scope:$rid"})) {
-		my $what=$hashref->{"$scope:$rid"};
-		foreach my $pair (split(/\&/,$hashref->{"$scope:$rid"})) {
+	    if (exists($hashref->{"$scope:compressed:$rid"})) {
+		foreach my $pair (split(/\&/,$hashref->{"$scope:compressed:$rid"})) {
 		    my ($key,$value)=split(/=/,$pair);
 		    $qresult.="$scope:".$pair."&";
 		}