[LON-CAPA-cvs] cvs: loncom / lond

foxr lon-capa-cvs@mail.lon-capa.org
Tue, 30 Dec 2003 11:28:16 -0000


foxr		Tue Dec 30 06:28:16 2003 EDT

  Modified files:              
    /loncom	lond 
  Log:
  Debug editing support for configuration files.
  
  
Index: loncom/lond
diff -u loncom/lond:1.168 loncom/lond:1.169
--- loncom/lond:1.168	Mon Dec 22 07:01:54 2003
+++ loncom/lond	Tue Dec 30 06:28:16 2003
@@ -2,7 +2,7 @@
 # The LearningOnline Network
 # lond "LON Daemon" Server (port "LOND" 5663)
 #
-# $Id: lond,v 1.168 2003/12/22 12:01:54 foxr Exp $
+# $Id: lond,v 1.169 2003/12/30 11:28:16 foxr Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -46,13 +46,14 @@
 use lib '/home/httpd/lib/perl/';
 use localauth;
 use File::Copy;
+use LONCAPA::ConfigFileEdit;
 
 my $DEBUG = 0;		       # Non zero to enable debug log entries.
 
 my $status='';
 my $lastlog='';
 
-my $VERSION='$Revision: 1.168 $'; #' stupid emacs
+my $VERSION='$Revision: 1.169 $'; #' stupid emacs
 my $remoteVERSION;
 my $currenthostid;
 my $currentdomainid;
@@ -349,7 +350,31 @@
 
     return 1;
 }
+#
+#   ConfigFileFromSelector: converts a configuration file selector
+#                 (one of host or domain at this point) into a 
+#                 configuration file pathname.
+#
+#  Parameters:
+#      selector  - Configuration file selector.
+#  Returns:
+#      Full path to the file or undef if the selector is invalid.
+#
+sub ConfigFileFromSelector {
+    my $selector   = shift;
+    my $tablefile;
+
+    my $tabledir = $perlvar{'lonTabDir'}.'/';
+    if ($selector eq "hosts") {
+	$tablefile = $tabledir."hosts.tab";
+    } elsif ($selector eq "domain") {
+	$tablefile = $tabledir."domain.tab";
+    } else {
+	return undef;
+    }
+    return $tablefile;
 
+}
 #
 #   PushFile:  Called to do an administrative push of a file.
 #              - Ensure the file being pushed is one we support.
@@ -379,12 +404,9 @@
     # part of some elaborate spoof that managed somehow to authenticate.
     #
 
-    my $tablefile = $perlvar{'lonTabDir'}.'/'; # need to precede with dir.
-    if ($filename eq "host") {
-	$tablefile .= "hosts.tab";
-    } elsif ($filename eq "domain") {
-	$tablefile .= "domain.tab";
-    } else {
+
+    my $tablefile = ConfigFileFromSelector($filename);
+    if(! (defined $tablefile)) {
 	return "refused";
     }
     #
@@ -508,7 +530,7 @@
 	} else {
 	    return 1;		# Valid syntax.
 	}
-    } elsif (($command eq "append") || ($command eq "replace")) {
+    } elsif ($command eq "replace") {
 	#
 	#   key and newline:
 	#
@@ -517,12 +539,125 @@
 	} else {
 	    return 1;
 	}
+    } elsif ($command eq "append") {
+	if (($key ne "") && ($newline eq "")) {
+	    return 1;
+	} else {
+	    return 0;
+	}
     } else {
 	return 0;		# Invalid command.
     }
     return 0;			# Should not get here!!!
 }
+#
+#   ApplyEdit - Applies an edit command to a line in a configuration 
+#               file.  It is the caller's responsiblity to validate the
+#               edit line.
+#   Parameters:
+#      $directive - A single edit directive to apply.  
+#                   Edit directives are of the form:
+#                  append|newline      - Appends a new line to the file.
+#                  replace|key|newline - Replaces the line with key value 'key'
+#                  delete|key          - Deletes the line with key value 'key'.
+#      $editor   - A config file editor object that contains the
+#                  file being edited.
+#
+sub ApplyEdit {
+    my $directive   = shift;
+    my $editor      = shift;
+
+    # Break the directive down into its command and its parameters
+    # (at most two at this point.  The meaning of the parameters, if in fact
+    #  they exist depends on the command).
+
+    my ($command, $p1, $p2) = split(/\|/, $directive);
+
+    if($command eq "append") {
+	$editor->Append($p1);	          # p1 - key p2 null.
+    } elsif ($command eq "replace") {
+	$editor->ReplaceLine($p1, $p2);   # p1 - key p2 = newline.
+    } elsif ($command eq "delete") {
+	$editor->DeleteLine($p1);         # p1 - key p2 null.
+    } else {			          # Should not get here!!!
+	die "Invalid command given to ApplyEdit $command"
+    }
+}
+#
+# AdjustOurHost:
+#           Adjusts a host file stored in a configuration file editor object
+#           for the true IP address of this host. This is necessary for hosts
+#           that live behind a firewall.
+#           Those hosts have a publicly distributed IP of the firewall, but
+#           internally must use their actual IP.  We assume that a given
+#           host only has a single IP interface for now.
+# Formal Parameters:
+#     editor   - The configuration file editor to adjust.  This
+#                editor is assumed to contain a hosts.tab file.
+# Strategy:
+#    - Figure out our hostname.
+#    - Lookup the entry for this host.
+#    - Modify the line to contain our IP
+#    - Do a replace for this host.
+sub AdjustOurHost {
+    my $editor        = shift;
+
+    # figure out who I am.
+
+    my $myHostName    = $perlvar{'lonHostID'}; # LonCAPA hostname.
+
+    #  Get my host file entry.
+
+    my $ConfigLine    = $editor->Find($myHostName);
+    if(! (defined $ConfigLine)) {
+	die "AdjustOurHost - no entry for me in hosts file $myHostName";
+    }
+    # figure out my IP:
+    #   Use the config line to get my hostname.
+    #   Use gethostbyname to translate that into an IP address.
+    #
+    my ($id,$domain,$role,$name,$ip,$maxcon,$idleto,$mincon) = split(/:/,$ConfigLine);
+    my $BinaryIp = gethostbyname($name);
+    my $ip       = inet_ntoa($ip);
+    #
+    #  Reassemble the config line from the elements in the list.
+    #  Note that if the loncnew items were not present before, they will
+    #  be now even if they would be empty
+    #
+    my $newConfigLine = $id;
+    foreach my $item ($domain, $role, $name, $ip, $maxcon, $idleto, $mincon) {
+	$newConfigLine .= ":".$item;
+    }
+    #  Replace the line:
+
+    $editor->ReplaceLine($id, $newConfigLine);
+    
+}
+#
+#   ReplaceConfigFile:
+#              Replaces a configuration file with the contents of a
+#              configuration file editor object.
+#              This is done by:
+#              - Copying the target file to <filename>.old
+#              - Writing the new file to <filename>.tmp
+#              - Moving <filename.tmp>  -> <filename>
+#              This laborious process ensures that the system is never without
+#              a configuration file that's at least valid (even if the contents
+#              may be dated).
+#   Parameters:
+#        filename   - Name of the file to modify... this is a full path.
+#        editor     - Editor containing the file.
+#
+sub ReplaceConfigFile {
+    my $filename  = shift;
+    my $editor    = shift;
 
+    CopyFile ($filename, $filename.".old");
+
+    my $contents  = $editor->Get(); # Get the contents of the file.
+
+    InstallFile($filename, $contents);
+}
 #   
 #
 #   Called to edit a configuration table  file
@@ -560,7 +695,27 @@
     }
 
     #   Execute the edit operation.
+    #   - Create a config file editor for the appropriate file and 
+    #   - execute each command in the script:
+    #
+    my $configfile = ConfigFileFromSelector($filetype);
+    if (!(defined $configfile)) {
+	return "refused\n";
+    }
+    my $editor = ConfigFileEdit->new($configfile);
 
+    for (my $i = 0; $i < $linecount; $i++) {
+	ApplyEdit($scriptlines[$i], $editor);
+    }
+    # If the file is the host file, ensure that our host is
+    # adjusted to have our ip:
+    #
+    if($filetype eq "host") {
+	AdjustOurHost($editor);
+    }
+    #  Finally replace the current file with our file.
+    #
+    ReplaceConfigFile($configfile, $editor);
 
     return "ok\n";
 }