--- loncom/build/Attic/parse.pl	2000/12/08 20:28:57	1.4
+++ loncom/build/Attic/parse.pl	2000/12/12 17:05:36	1.14
@@ -12,17 +12,30 @@ my ($file,$mode)=@ARGV;
 open IN,"<$file";
 my @lines=<IN>;
 close IN;
-my $info=join('',@lines);
-my $info2=$info; # value to allow for meta data group retrieval
+my $info1=join('',@lines);
+my $info2=$info1; # value to allow for meta data group retrieval
 
 # ------------------------------------------------------- Make default settings
 my $distribution="redhat6.2";
 my $date=`date +'%B %e, %Y'`; chop $date;
 my $buildhost=`hostname`; chop $buildhost;
+# file category mappings
+my %fcm=(
+	 'conf' => 'configurable',
+	 'graphic file' => 'graphicfile',
+	 'handler' => 'handler',
+	 'interface file' => 'interfacefile',
+	 'symbolic link' => 'link',
+	 'root script' => 'rootscript',
+	 'script' => 'script',
+	 'setuid script' => 'setuid',
+	 'static conf' => 'static',
+	 'system file' => 'systemfile',
+	 );
 
 # ---------------------------------------------------- Parse the marked up data
 my %info; # big data storage object
-while ($info=~/\<loncapa\s+(.*?)\>/isg) {
+while ($info1=~/\<loncapa\s+(.*?)\>/isg) {
     my $keystring=$1;
     # In the parsing of LON-CAPA tags, remove boundary white-space,
     # and handle quotation commands.
@@ -31,7 +44,6 @@ while ($info=~/\<loncapa\s+(.*?)\>/isg)
  				   $value=~s/"$//;
                                    (uc($key),$value);}
              split(/\s+(?=\w+\s*\=)/,$keystring);
-
     # Handle the different types of commands
     if (uc($hash{'TYPE'}) eq "OWNERSHIP") {
         $info{$hash{'TYPE'}}{$hash{'CATEGORY'}}{'CHMOD'}=$hash{'CHMOD'};
@@ -52,19 +64,19 @@ while ($info=~/\<loncapa\s+(.*?)\>/isg)
                                $hash{'DESCRIPTION'} if $hash{'DESCRIPTION'};
     }
     elsif (uc($hash{'TYPE'}) eq "LOCATION") {
-        $info{$hash{'TYPE'}}{$hash{'DIST'}}{$hash{'TARGET'}}{'CATEGORY'}=
-                                                       $hash{'CATEGORY'};
-        $info{$hash{'TYPE'}}{$hash{'DIST'}}{$hash{'TARGET'}}{'SOURCE'}=
-                                                        $hash{'SOURCE'};
+        $info{$hash{'TYPE'}}{$hash{'DIST'}}{$hash{'TARGET'}}{'CATEGORY'}=                               $hash{'CATEGORY'};
+        $info{$hash{'TYPE'}}{$hash{'DIST'}}{$hash{'TARGET'}}{'LINKTO'}=                               $hash{'LINKTO'};
+        $info{$hash{'TYPE'}}{$hash{'DIST'}}{$hash{'TARGET'}}{'SOURCE'}=                                               $hash{'SOURCE'};
         # get surrounding metagroup information
         my $ckeystring=$keystring; $ckeystring=~s/(SOURCE\=\"[^"]*)\*/$1\\\*/g;
+        $ckeystring=~s/(TARGET\=\"[^"]*)\*/$1\\\*/g;
         $info2=~/.*\<(?:metagroup|metasupergroup)\>(.*?)\<loncapa\s+$ckeystring\>(.*?)\<\/(?:metagroup|metasupergroup)\>/is;
 	my $data=$1.$2;
         my @meta=('description','build','dependencies','files','note');
         foreach my $m (@meta) {
 	    if ($data=~/\<($m)\>(.*?)\<\/$m\>/sgi) {
 		my ($key,$value)=($1,$2);
-		$info{$hash{'TYPE'}}{$hash{'DIST'}}{$hash{'TARGET'}}{$key}=
+		$info{$hash{'TYPE'}}{$hash{'DIST'}}{$hash{'TARGET'}}{uc($key)}=
 		                                                    $value;
 	    }
         }
@@ -74,8 +86,9 @@ while ($info=~/\<loncapa\s+(.*?)\>/isg)
     }
 }
 
-if ($mode eq "ALL" || $mode eq "HTML") {
-    my $a;
+my $a;
+my @directories;
+if ($mode eq "HTML") {
     $a=&begin_description_page;
     print $a;
     $a=&make_rpm_description_block;
@@ -83,13 +96,579 @@ if ($mode eq "ALL" || $mode eq "HTML") {
     @directories=&determine_directory_structure;
     $a=&make_directory_structure_description_block(\@directories);
     print $a;
+    $a=&make_file_type_ownership_and_permissions_description_block;
+    print $a;
     $a=&make_directory_and_file_structure_description_block(\@directories);
     print $a;
     $a=&end_description_page;
     print $a;
 }
+elsif ($mode eq "SPEC") {
+    my $out=$info{'RPM'}{'Name'} . '-' . $info{'RPM'}{'Version'} . '.spec';
+    open OUT,">$out";
+    $a=&make_rpm_spec_block;
+    print OUT $a;
+    $a=&make_rpm_build_block;
+    print OUT $a;
+    @directories=&determine_directory_structure;
+    $a=&make_directory_structure_spec_block(\@directories);
+    print OUT $a;
+    $a=&make_directory_and_file_structure_spec_block(\@directories);
+    print OUT $a;
+    $a=&end_spec_page;
+    print OUT $a;
+    close OUT;
+}
+elsif ($mode eq "LCMakefile") {
+    @directories=&determine_directory_structure;
+    $a=&make_directory_LCMakefile_segment(\@directories);
+    print $a;
+    $a=&make_files_LCMakefile_segment(\@directories);
+    print $a;
+    $a=&make_links_LCMakefile_segment(\@directories);
+    print $a;
+}
+elsif ($mode eq "BinaryRoot") {
+    mkdir "BinaryRoot",0755;
+    open OUT,">Makefile.BinaryRoot";
+    @directories=&determine_directory_structure;
+    $a=&make_directory_binaryroot_segment(\@directories);
+    print OUT $a;
+    $a=&make_files_binaryroot_segment(\@directories);
+    print OUT $a;
+    $a=&make_links_binaryroot_segment(\@directories);
+    print OUT $a;
+    close OUT;
+    print `make -f Makefile.BinaryRoot TARGET='BinaryRoot' SOURCE='../..' directories`;
+    print `make -f Makefile.BinaryRoot TARGET='BinaryRoot' SOURCE='../..' files`;
+    print `make -f Makefile.BinaryRoot TARGET='BinaryRoot' SOURCE='../..' links`;
+    open OUT,">base_file_list.txt";
+    $a=&make_file_list(\@directories);
+    print OUT $a;
+    close OUT;
+    
+}
+elsif ($mode eq "status") {
+}
+elsif ($mode eq "update") {
+}
+elsif ($mode eq "install") {
+    @directories=&determine_directory_structure;
+    $a=&make_directory_install_segment(\@directories);
+    print $a;
+    $a=&make_files_install_segment(\@directories);
+    print $a;
+    $a=&make_links_install_segment(\@directories);
+    print $a;
+}
+
+# ------------------------------------------------------ a list of file targets
+sub make_file_list {
+    my ($dirs)=@_;
+    my $description;
+    my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
+    foreach my $d (@$dirs) {
+	# set other values
+	my $dirdescription=$info{'DIRECTORY'}{$distribution}{$d}{'DESCRIPTION'};
+	$dirdescription="(" . $dirdescription . ")" if $dirdescription;
+	# find files that are contained in this directory
+	my @files;
+	my @filesfull;
+	foreach my $f (@allfiles) {
+	    if ($f=~/^$d\/([^\/]+)$/) {
+		push @files,$1;
+		push @filesfull,$f;
+	    }
+	}
+	# render starting HTML formatting elements
+	if (@files) {
+        }
+	my $pwd=`pwd`; chop $pwd;
+	if (@files) {
+            foreach my $i (0..$#files) {
+		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
+		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
+		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
+		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
+		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
+		my $source=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'};
+		my $rot="/".$filesfull[$i];
+		if ($rot=~/\*/) {
+		    $rot=~s/[^\/]+$// if $rot=~/\*/;
+		    my $listing=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'FILES'};
+		    chop $listing;
+		    my @list=split(/\s+/,$listing);
+		    my $rot2;
+		    foreach my $l (@list) {
+			$l=~s/^\s*//; $l=~s/\s*$//;
+			$rot2.="BinaryRoot$rot$l\n" if length($l);
+		    }
+		    chop $rot2;
+		    $rot=$rot2;
+		}
+		else {
+		    $rot="BinaryRoot$rot";
+		}
+		if ($category eq "conf") {
+		    $rot.=" # config";
+		}
+		$description.=<<END;
+$rot
+END
+	    }
+	}
+    }
+    $description.=<<END;
+
+END
+    return $description;
+}
+
+# --------------------------------- Commands to make BinaryRoot directories
+sub make_directory_binaryroot_segment {
+    my ($dirs)=@_;
+    my $description=<<END;
+directories:
+END
+    foreach my $d (@$dirs) {
+	my $category=$info{'DIRECTORY'}{$distribution}{$d}{'CATEGORY'};
+	my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
+	my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
+	my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
+	my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
+	my $own=$devchown; $own=~s/\:/\,/;
+	$description.=<<END;
+\tinstall -m $devchmod -d \$(TARGET)/$d
+END
+    }
+    $description.=<<END;
+
+END
+    return $description;
+}
+
+# --------------------------------------- Commands to make BinaryRoot files
+sub make_files_binaryroot_segment {
+    my ($dirs)=@_;
+    my $description=<<END;
+files:
+END
+    my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
+    foreach my $d (@$dirs) {
+	# set other values
+	my $dirdescription=$info{'DIRECTORY'}{$distribution}{$d}{'DESCRIPTION'};
+	$dirdescription="(" . $dirdescription . ")" if $dirdescription;
+	# find files that are contained in this directory
+	my @files;
+	my @filesfull;
+	foreach my $f (@allfiles) {
+	    if ($f=~/^$d\/([^\/]+)$/) {
+		push @files,$1;
+		push @filesfull,$f;
+	    }
+	}
+	# render starting HTML formatting elements
+	if (@files) {
+	    $description.=<<END;
+\t# $d $dirdescription
+END
+        }
+	if (@files) {
+            foreach my $i (0..$#files) {
+		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
+		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
+		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
+		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
+		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
+		my $source=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'};
+		my $rot=$filesfull[$i];
+		$rot=~s/[^\/]+$/\./ if $rot=~/\*/;
+		$description.=<<END if $category ne 'symbolic link';
+\tinstall -m $devchmod \$(SOURCE)/$source \$(TARGET)/$rot
+END
+	    }
+	}
+    }
+    $description.=<<END;
+
+END
+    return $description;
+}
+
+# ------------------------------ Commands to make BinaryRoot symbolic links
+sub make_links_binaryroot_segment {
+    my ($dirs)=@_;
+    my $description=<<END;
+links:
+END
+    my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
+    foreach my $d (@$dirs) {
+	# find files that are contained in this directory
+	my @files;
+	my @filesfull;
+	foreach my $f (@allfiles) {
+	    if ($f=~/^$d\/([^\/]+)$/) {
+		push @files,$1;
+		push @filesfull,$f;
+	    }
+	}
+	# render starting HTML formatting elements
+	if (@files) {
+            foreach my $i (0..$#files) {
+		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
+		my $linkto=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'LINKTO'};
+		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
+		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
+		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
+		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
+		$description.=<<END if $category eq 'symbolic link';
+\tln -s /$linkto \$(TARGET)/$filesfull[$i]
+END
+	    }
+	}
+    }
+    $description.=<<END;
+
+END
+    return $description;
+}
+
+# ------ Installation commands for a Makefile used only by a rpm -ba invocation
+sub make_directory_LCMakefile_segment {
+    my ($dirs)=@_;
+    my $description=<<END;
+directories:
+END
+    foreach my $d (@$dirs) {
+	my $category=$info{'DIRECTORY'}{$distribution}{$d}{'CATEGORY'};
+	my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
+	my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
+	my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
+	my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
+	my $own=$devchown; $own=~s/\:/\,/;
+	$description.=<<END;
+\tinstall -m $devchmod -d \$(SOURCE)/$d \$(ROOT)/$d
+END
+    }
+    $description.=<<END;
+
+END
+    return $description;
+}
+
+# ------ Installation commands for a Makefile used only by a rpm -ba invocation
+sub make_files_LCMakefile_segment {
+    my ($dirs)=@_;
+    my $description=<<END;
+files:
+END
+    my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
+    foreach my $d (@$dirs) {
+	# set other values
+	my $dirdescription=$info{'DIRECTORY'}{$distribution}{$d}{'DESCRIPTION'};
+	$dirdescription="(" . $dirdescription . ")" if $dirdescription;
+	# find files that are contained in this directory
+	my @files;
+	my @filesfull;
+	foreach my $f (@allfiles) {
+	    if ($f=~/^$d\/([^\/]+)$/) {
+		push @files,$1;
+		push @filesfull,$f;
+	    }
+	}
+	# render starting HTML formatting elements
+	if (@files) {
+	    $description.=<<END;
+\t# $d $dirdescription
+END
+        }
+	if (@files) {
+            foreach my $i (0..$#files) {
+		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
+		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
+		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
+		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
+		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
+		my $rot=$filesfull[$i];
+		$rot=~s/[^\/]+$/\./ if $rot=~/\*/;
+		$description.=<<END if $category ne 'symbolic link';
+\tinstall -m $devchmod \$(SOURCE)/$filesfull[$i] \$(ROOT)/$rot
+END
+	    }
+	}
+    }
+    $description.=<<END;
+
+END
+    return $description;
+}
+
+# ------ Installation commands for a Makefile used only by a rpm -ba invocation
+sub make_links_LCMakefile_segment {
+    my ($dirs)=@_;
+    my $description=<<END;
+links:
+END
+    my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
+    foreach my $d (@$dirs) {
+	# find files that are contained in this directory
+	my @files;
+	my @filesfull;
+	foreach my $f (@allfiles) {
+	    if ($f=~/^$d\/([^\/]+)$/) {
+		push @files,$1;
+		push @filesfull,$f;
+	    }
+	}
+	# render starting HTML formatting elements
+	if (@files) {
+            foreach my $i (0..$#files) {
+		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
+		my $linkto=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'LINKTO'};
+		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
+		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
+		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
+		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
+		$description.=<<END if $category eq 'symbolic link';
+\tln -s /$linkto \$(ROOT)/$filesfull[$i]
+END
+	    }
+	}
+    }
+    $description.=<<END;
+
+END
+    return $description;
+}
+
+# --------------------------------- Installation commands to install directories
+sub make_directory_install_segment {
+    my ($dirs)=@_;
+    my $description=<<END;
+directories:
+END
+    foreach my $d (@$dirs) {
+	my $category=$info{'DIRECTORY'}{$distribution}{$d}{'CATEGORY'};
+	my $source=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'};
+	my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
+	my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
+	my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
+	my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
+	my $own=$devchown; $own=~s/\:/\,/;
+	$description.=<<END;
+\tinstall -m $devchmod -d \$(TARGET)/$d
+END
+    }
+    $description.=<<END;
+
+END
+    return $description;
+}
+
+# --------------------------------------- Installation commands to install files
+sub make_files_install_segment {
+    my ($dirs)=@_;
+    my $description=<<END;
+files:
+END
+    my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
+    foreach my $d (@$dirs) {
+	# set other values
+	my $dirdescription=$info{'DIRECTORY'}{$distribution}{$d}{'DESCRIPTION'};
+	$dirdescription="(" . $dirdescription . ")" if $dirdescription;
+	# find files that are contained in this directory
+	my @files;
+	my @filesfull;
+	foreach my $f (@allfiles) {
+	    if ($f=~/^$d\/([^\/]+)$/) {
+		push @files,$1;
+		push @filesfull,$f;
+	    }
+	}
+	# render starting HTML formatting elements
+	if (@files) {
+	    $description.=<<END;
+\t# $d $dirdescription
+END
+        }
+	if (@files) {
+            foreach my $i (0..$#files) {
+		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
+		my $source=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'};
+		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
+		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
+		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
+		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
+		my $rot=$filesfull[$i];
+		$rot=~s/[^\/]+$/\./ if $rot=~/\*/;
+		$description.=<<END if $category ne 'symbolic link';
+\tinstall -m $devchmod \$(SOURCE)/$source \$(TARGET)/$rot
+END
+	    }
+	}
+    }
+    $description.=<<END;
+
+END
+    return $description;
+}
 
-# ------------------------------------------------- Begin description page
+# ------------------------------ Installation commands to install symbolic links
+sub make_links_install_segment {
+    my ($dirs)=@_;
+    my $description=<<END;
+links:
+END
+    my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
+    foreach my $d (@$dirs) {
+	# find files that are contained in this directory
+	my @files;
+	my @filesfull;
+	foreach my $f (@allfiles) {
+	    if ($f=~/^$d\/([^\/]+)$/) {
+		push @files,$1;
+		push @filesfull,$f;
+	    }
+	}
+	# render starting HTML formatting elements
+	if (@files) {
+            foreach my $i (0..$#files) {
+		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
+		my $linkto=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'LINKTO'};
+		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
+		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
+		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
+		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
+		$description.=<<END if $category eq 'symbolic link';
+\tln -s /$linkto \$(TARGET)/$filesfull[$i]
+END
+	    }
+	}
+    }
+    $description.=<<END;
+
+END
+    return $description;
+}
+
+# --------------------------------------------------------- Make RPM .spec block
+sub make_rpm_spec_block {
+    my $pwd=`pwd`; chop $pwd;
+    my $buildroot="$pwd/LON-CAPA-BuildRoot";
+    my $source=$info{'RPM'}{'Name'} . "-" . $info{'RPM'}{'Version'} . '.tar.gz';
+    my $description=<<END;
+Summary: $info{'RPM'}{'Summary'}
+Name: $info{'RPM'}{'Name'}
+Version: $info{'RPM'}{'Version'}
+Release: $info{'RPM'}{'Release'}
+Vendor: $info{'RPM'}{'Vendor'} 
+BuildRoot: $buildroot
+Copyright: $info{'RPM'}{'Copyright'}
+Group: $info{'RPM'}{'Group'}
+Source: $source
+AutoReqProv: $info{'RPM'}{'AutoReqProv'}
+\%description
+$info{'RPM'}{'description'}
+
+END
+    return $description;
+}
+
+# --------------------------------------------------- Make RPM build .spec block
+sub make_rpm_build_block {
+    my $pwd=`pwd`; chop $pwd;
+    my $buildroot="$pwd/LON-CAPA-BuildRoot";
+    my $sourceroot="$pwd/LON-CAPA-SourceRoot";
+    my $description=<<END;
+
+\%prep
+\%setup
+
+\%build
+rm -Rf "$buildroot"
+
+\%install
+make -f LCMakefile ROOT="\$RPM_BUILD_ROOT" SOURCE="$sourceroot" directories
+make -f LCMakefile ROOT="\$RPM_BUILD_ROOT" SOURCE="$sourceroot" files
+make -f LCMakefile ROOT="\$RPM_BUILD_ROOT" SOURCE="$sourceroot" links
+
+\%pre
+$info{'RPM'}{'pre'}
+
+\%post
+\%postun
+
+\%files
+# \%doc README COPYING ChangeLog LICENSE
+END
+    return $description;
+}
+
+# ------------------------------------- Make directory structure RPM .spec block
+sub make_directory_structure_spec_block {
+    my ($dirs)=@_;
+    foreach my $d (@$dirs) {
+	my $category=$info{'DIRECTORY'}{$distribution}{$d}{'CATEGORY'};
+	my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
+	my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
+	my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
+	my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
+	my $own=$devchown; $own=~s/\:/\,/;
+	$description.=<<END;
+\%dir \%attr($devchmod,$own) /$d
+END
+    }
+    return $description;
+}
+
+# ---------------------------- Make directory and file structure RPM .spec block
+sub make_directory_and_file_structure_spec_block {
+    my ($dirs)=@_;
+    my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
+    foreach my $d (@$dirs) {
+	# set other values
+	my $dirdescription=$info{'DIRECTORY'}{$distribution}{$d}{'DESCRIPTION'};
+	$dirdescription="(" . $dirdescription . ")" if $dirdescription;
+	# find files that are contained in this directory
+	my @files;
+	my @filesfull;
+	foreach my $f (@allfiles) {
+	    if ($f=~/^$d\/([^\/]+)$/) {
+		push @files,$1;
+		push @filesfull,$f;
+	    }
+	}
+	# render starting HTML formatting elements
+	if (@files) {
+	    $description.=<<END;
+# $d $dirdescription
+END
+        }
+	if (@files) {
+            foreach my $i (0..$#files) {
+		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
+		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
+		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
+		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
+		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
+		my $own=$devchown; $own=~s/\:/\,/;
+		my $config="";
+		$config="\%config " if $category eq 'conf';
+		$devchmod='-' if $category eq 'symbolic link';
+		$description.=<<END;
+$config\%attr($devchmod,$own) /$filesfull[$i]
+END
+	    }
+	}
+    }
+    return $description;
+}
+
+# ----------------------------------------------------------- End RPM .spec page
+sub end_spec_page {
+}
+
+# ------------------------------------------------------- Begin description page
 sub begin_description_page {
     my $description=<<END;
 <HTML>
@@ -105,6 +684,7 @@ sub begin_description_page {
 <LI>About this file
 <LI>Software Package Description
 <LI>Directory Structure
+<LI>File Type Ownership and Permissions
 <LI>File and Directory Structure
 </UL>
 <FONT SIZE=+2>About this file</FONT>
@@ -122,7 +702,7 @@ END
 sub end_description_page {
     my $description=<<END;
 <HR>
-<FONT SIZE=-2>LON-CAPA Software Development Team</FONT>
+<FONT SIZE=-1>LON-CAPA Software Development Team</FONT>
 </BODY>
 </HTML>
 END
@@ -146,7 +726,6 @@ Group       : $info{'RPM'}{'Group'}
 License     : $info{'RPM'}{'Copyright'}
 Summary     : $info{'RPM'}{'Summary'}
 Description : 
-<PRE>
 $info{'RPM'}{'description'}
 </PRE>
 </TD></TR>
@@ -169,13 +748,27 @@ sub make_directory_structure_description
     my $description=<<END;
 <FONT SIZE=+2>Directory Structure Description, $date</FONT>
 <P>
+The directory structure description below shows only those
+directories which either contain LON-CAPA specific files
+or normally do not exist on a RedHat Linux system (and
+must be generated to allow proper placement of files
+during LON-CAPA run-time operation).
+</P>
+<P>
 <TABLE BORDER=1 CELLPADDING=3 CELLSPACING=0>
 END
     my $maxcount=0;
+    my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
+    my %diraccount; # hash to track which directories are accounted for
+    foreach my $file (@allfiles) {
+	$file=~/^(.*)\/([^\/]+)$/;
+	$diraccount{$1}=1;
+    }
     foreach my $d (@$dirs) {
         my (@matches)=($d=~/\//g);
 	my $count=scalar(@matches);
 	$maxcount=$count if $count>$maxcount;
+	delete $diraccount{$d};
     }
     $description.=<<END;
 <TR>
@@ -184,6 +777,13 @@ END
 <TH ALIGN=LEFT BGCOLOR=#FFFFFF><FONT COLOR=#FF0000>Development<BR>Permissions</FONT></TH>
 END
     $description.="<TH ALIGN=LEFT BGCOLOR=#FFFFFF COLSPAN=".($maxcount+1).">Directory Path</TH>\n";
+    if (keys %diraccount) {
+	$description.= "<TR><TD ALIGN=LEFT BGCOLOR=#FFFFFF COLSPAN=".($maxcount+4)."><I><PRE>Directories that are unaccounted for: \n";
+	foreach my $d (keys %diraccount) {
+	    $description.="$d\n";
+	}
+	$description.="</PRE></I></TH></TR>\n";
+    }
     foreach my $d (@$dirs) {
 	my $dtable=$d;
 	$dtable=~s/\//\<\/TD\>\<TD\>/g;
@@ -210,17 +810,65 @@ END
     return $description;
 }
 
+# ------------------- Make file type ownership and permissions description block
+sub make_file_type_ownership_and_permissions_description_block {
+    my $description=<<END;
+<FONT SIZE=+2>File Type Ownership and Permissions Descriptions, $date</FONT>
+<P>
+This table shows what permissions and ownership settings correspond
+to each kind of file type.
+</P>
+<P>
+<TABLE BORDER=1 CELLPADDING=5 WIDTH=60%>
+<TR>
+<TH ALIGN=LEFT BGCOLOR=#FFFFFF>Icon</TH>
+<TH ALIGN=LEFT BGCOLOR=#FFFFFF>Type</TH>
+<TH ALIGN=LEFT BGCOLOR=#FFFFFF>Permissions</TH>
+<TH ALIGN=LEFT BGCOLOR=#FFFFFF>Development Permissions</TH>
+</TR>
+END
+    foreach my $type (keys %{$info{'OWNERSHIP'}}) {
+	if (defined($fcm{$type})) {
+	    my $chmod=$info{'OWNERSHIP'}{$type}{'CHMOD'};
+	    my $chown=$info{'OWNERSHIP'}{$type}{'CHOWN'};
+	    my $devchmod=$info{'DEVOWNERSHIP'}{$type}{'CHMOD'};
+	    my $devchown=$info{'DEVOWNERSHIP'}{$type}{'CHOWN'};
+	    $description.=<<END;
+<TR>
+<TD><IMG SRC="$fcm{$type}.gif" ALT="$type"></TD>
+<TD>$type</TD>
+<TD><TT>$chmod $chown</TT></TD>
+<TD><TT>$devchmod $devchown</TT></TD>
+</TR>
+END
+        }
+    }
+    $description.=<<END;
+</TABLE>
+</P>
+END
+}
+
 # ------------------------- Make directory and file structure description block
 sub make_directory_and_file_structure_description_block {
     my ($dirs)=@_;
     my $description=<<END;
 <FONT SIZE=+2>Directory and File Structure Description, $date</FONT>
 <P>
-<TABLE BORDER=1 CELLPADDING=5>
+The icons on the left column correspond to the file type
+specified in the second column.  The last column "Notes" shows compilation,
+dependency, and configuration information.  The CVS location
+shows the location of the binary source file (if applicable) needed to
+be copied to the target.  If the binary source file is not at
+the specified location, then the text is shown in 
+<FONT COLOR=#FF0000>red</FONT>.
+</P>
+<P>
+<TABLE BORDER=1 CELLPADDING=5 WIDTH=500>
 END
     my $counter=0;
     my @colorindex=("#80FF80","#80FFFF","#FFFF80");
-    my @allfiles=keys %{$info{'LOCATION'}{$distribution}{'TARGET'}};
+    my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
     foreach my $d (@$dirs) {
 	# set color
 	my $color=$colorindex[$counter%3];
@@ -230,43 +878,90 @@ END
 	# find subdirectories that are contained in this directory
 	my @subdirs;
 	foreach my $d2 (@$dirs) {
-	    if ($d2=~/$d\/([^\/]+)/) {
+	    if ($d2=~/^$d\/([^\/]+)$/) {
 		push @subdirs,$1;
 	    }
 	}
 	# find files that are contained in this directory
 	my @files;
+	my @filesfull;
 	foreach my $f (@allfiles) {
-	    if ($file=~/$d\/(.+)/) {
+	    if ($f=~/^$d\/([^\/]+)$/) {
 		push @files,$1;
+		push @filesfull,$f;
 	    }
 	}
 	# render starting HTML formatting elements
 	if (@subdirs || @files) {
 	    my $subdirstring="<BR>* Relevant subdirectories: " . join(", ",@subdirs) if @subdirs;
 	    $description.=<<END;
-<TR><TD BGCOLOR=#000000 COLSPAN=5><FONT COLOR=$color><IMG SRC="directory.gif" ALT="directory">DIRECTORY -- $d $dirdescription
-$subdirstring</FONT></TD><TD>
+<TR><TD BGCOLOR=#000000 COLSPAN=6><FONT COLOR=$color><IMG SRC="directory.gif" ALT="directory">DIRECTORY -- $d $dirdescription
+$subdirstring</FONT></TD></TR>
 END
         }
 	else {
 	    $description.=<<END;
-<TR><TD BGCOLOR=#000000 COLSPAN=5><FONT COLOR=$color><IMG SRC="emptydirectory.gif" ALT="empty directory">EMPTY DIRECTORY - $d $dirdescription</FONT></TD>
+<TR><TD BGCOLOR=#000000 COLSPAN=6><FONT COLOR=$color><IMG SRC="emptydirectory.gif" ALT="empty directory">EMPTY DIRECTORY - $d $dirdescription</FONT></TD></TR>
 END
         }
 	if (@files) {
 	    $description.=<<END;
 <TR>
-<TH ALIGN=LEFT>Type</TH>
-<TH ALIGN=LEFT>File Name</TH>
-<TH ALIGN=LEFT>Function</TH>
-<TH ALIGN=LEFT>Notes</TH>
+<TH BGCOLOR=$color ALIGN=LEFT COLSPAN=2>Type</TH>
+<TH BGCOLOR=$color ALIGN=LEFT>File Name</TH>
+<TH BGCOLOR=$color ALIGN=LEFT>Function</TH>
+<TH BGCOLOR=$color ALIGN=LEFT>CVS Location</TH>
+<TH BGCOLOR=$color ALIGN=LEFT>Notes</TH>
 </TR>
 END
-	}
-	$description.=<<END;
+            foreach my $i (0..$#files) {
+		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
+		my $fdescription=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'DESCRIPTION'};
+		my $source=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'};
+		my $note=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'NOTE'};
+		$note.="<BR>" if $note;
+		my $listing=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'FILES'};
+		my @E=split(/\s+/,$listing);
+		$source=~/(.*)\/[^\/]+$/;
+		my $sd=$1;
+		my $eflag=0;
+		foreach my $e (@E) {
+		    unless (-e "../../$sd/$e") {
+			$e="<FONT COLOR=#FF0000>$e</FONT>";
+			$eflag=1;
+		    }
+		}
+		$listing=join("\n",@E);
+		$listing="<B>listing</B><BR><FONT SIZE=-2>$listing</FONT>" if $listing;
+		$listing.="<BR>" if $listing;
+		my $build=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'BUILD'};
+		$build="<B>build</B><BR>$build" if $build;
+		$build.="<BR>" if $build;
+		my $dependencies=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'DEPENDENCIES'};
+		$dependencies="<B>dependencies</B><BR>$dependencies" if $dependencies;
+		$dependencies.="<BR>" if $dependencies;
+		unless (-e "../../$source") {
+		    $source=~/([^\/]+)$/;
+		    my $s=$1;
+		    if ($source!~/\*/) {
+			$source="<FONT COLOR=#FF0000>$source</FONT>";
+		    }
+		    elsif ($eflag) {
+			$source="<FONT COLOR=#FF0000>$source</FONT>";
+		    }
+		}
+		$description.=<<END;
+<TR>
+<TD BGCOLOR=#A0A0A0><IMG SRC="$fcm{$category}.gif" ALT="$category"></TD>
+<TD BGCOLOR=$color>$category</TD>
+<TD BGCOLOR=$color>$files[$i]</TD>
+<TD BGCOLOR=$color>$fdescription&nbsp;</TD>
+<TD BGCOLOR=$color>$source</TD>
+<TD BGCOLOR=$color>$note$listing$build$dependencies&nbsp;</TD>
 </TR>
 END
+	    }
+	}
 	$counter++;
     }
     $description.=<<END;