version 1.24, 2001/01/16 15:48:45
|
version 1.36, 2001/04/17 14:09:51
|
Line 2
|
Line 2
|
|
|
# Scott Harrison |
# Scott Harrison |
# November 2000 |
# November 2000 |
|
# 12/5/2000,12/7,12/8,12/9,12/10,12/11,12/12,12/13,12/14,12/21 Scott Harrison |
# Read in loncapa tags and metagroup tags |
# 1/8/2001,1/10/2001,1/13/2001,1/16/2001,1/18/2001,1/23/2001 Scott Harrison |
|
# 2/26/2001,2/27/2001,3/5/2001,4/10/2001,4/11,2001,4/13,2001 Scott Harrison |
|
# 4/17/2001 Scott Harrison |
|
|
|
# Read in loncapa tags and metagroup tags. Output various |
|
# useful files for viewing, compiling, monitoring, updating, |
|
# and installing. |
|
|
|
# This code works well. HOWEVER, I was in a rush when I |
|
# wrote it. Future plans are that the parsing should be |
|
# much more event-state based and the input should be |
|
# more XML-ish. -Scott |
|
|
# ---------------------------------------------- Read in command line arguments |
# ---------------------------------------------- Read in command line arguments |
my ($file,$mode)=@ARGV; |
my ($file,$mode)=@ARGV; |
Line 179 ALL: ALL
|
Line 190 ALL: ALL
|
END |
END |
close OUT; |
close OUT; |
|
|
|
`install -o 500 -g 500 -m 0700 -d BinaryRoot/home/www`; |
|
open OUT,">>setup_file_list.txt"; |
|
print OUT "BinaryRoot/home/www\n"; |
|
close OUT; |
`install -d BinaryRoot/etc/pam.d`; |
`install -d BinaryRoot/etc/pam.d`; |
open OUT,">>setup_file_list.txt"; |
open OUT,">>setup_file_list.txt"; |
print OUT "BinaryRoot/etc/pam.d/passwd\n"; |
print OUT "BinaryRoot/etc/pam.d/passwd\n"; |
Line 211 close OUT;
|
Line 226 close OUT;
|
|
|
} |
} |
elsif ($mode eq "status") { |
elsif ($mode eq "status") { |
|
$a=&begin_description_page('status'); |
|
print $a; |
|
$a=&make_rpm_description_block('status'); |
|
print $a; |
|
@directories=&determine_directory_structure('status'); |
|
$a=&make_directory_structure_description_block(\@directories,'status'); |
|
print $a; |
|
$a=&make_file_type_ownership_and_permissions_description_block('status'); |
|
print $a; |
|
$a=&make_directory_and_file_structure_description_block(\@directories,'status'); |
|
print $a; |
|
$a=&end_description_page('status'); |
|
print $a; |
} |
} |
elsif ($mode eq "update") { |
elsif ($mode eq "update") { |
} |
} |
Line 551 sub make_files_build_segment {
|
Line 579 sub make_files_build_segment {
|
my $description; |
my $description; |
my @allfiles=keys %{$info{'LOCATION'}{$distribution}}; |
my @allfiles=keys %{$info{'LOCATION'}{$distribution}}; |
my $tab="\t"; |
my $tab="\t"; |
my $sources="all: "; |
my $sources="# Dynamic Makefile generated by LON-CAPA build process\n\n"; |
|
$sources.="SHELL=\"/bin/sh\"\n\n"; |
|
$sources.="\nall: "; |
foreach my $d (@$dirs) { |
foreach my $d (@$dirs) { |
# set other values |
# set other values |
my $dirdescription=$info{'DIRECTORY'}{$distribution}{$d}{'DESCRIPTION'}; |
my $dirdescription=$info{'DIRECTORY'}{$distribution}{$d}{'DESCRIPTION'}; |
Line 592 sub make_files_build_segment {
|
Line 622 sub make_files_build_segment {
|
$depstat=" alwaysrun"; |
$depstat=" alwaysrun"; |
} |
} |
$dependencies=~s/\s+/ $sdir/gs; |
$dependencies=~s/\s+/ $sdir/gs; |
|
my @deps=split(/\s+/,$dependencies); |
|
shift @deps; |
|
my $testing=<<END; |
|
\@if !(echo "");\\ |
|
then echo "**** LON-CAPA WARNING **** Strange shell. Check your path settings.";\\ |
|
END |
|
foreach my $d (@deps) { |
|
$testing.=<<END; |
|
elif !(test -r $d);\\ |
|
then echo "**** LON-CAPA WARNING **** missing the file: $d";\\ |
|
END |
|
} |
|
chop $testing; |
$description.=<<END; |
$description.=<<END; |
$source2: $dependencies$depstat |
$source2: $depstat |
${tab}cd $directory; sh ./$buildfile |
$testing |
|
else \\ |
|
${tab}cd $directory; sh ./$buildfile;\\ |
|
fi |
|
|
END |
END |
} |
} |
Line 657 END
|
Line 703 END
|
my $rot=$filesfull[$i]; |
my $rot=$filesfull[$i]; |
$rot=~s/[^\/]+$/\./ if $rot=~/\*/; |
$rot=~s/[^\/]+$/\./ if $rot=~/\*/; |
my ($owner,$group)=split(/\:/,$devchown); |
my ($owner,$group)=split(/\:/,$devchown); |
if ($category ne 'conf') { |
if ($category ne 'conf' && $category ne 'symbolic link') { |
$description.=<<END if $category ne 'symbolic link'; |
if ($source!~/\*/) { |
|
$description.=<<END; |
|
\ttest '-e \$(SOURCE)/$source' \&\& install -o $owner -g $group -m $devchmod \$(SOURCE)/$source \$(TARGET)/$rot || echo "**** LON-CAPA WARNING **** CVS source file does not exist: \$(SOURCE)/$source" |
|
END |
|
} |
|
else { |
|
$description.=<<END; |
\tinstall -o $owner -g $group -m $devchmod \$(SOURCE)/$source \$(TARGET)/$rot |
\tinstall -o $owner -g $group -m $devchmod \$(SOURCE)/$source \$(TARGET)/$rot |
END |
END |
|
} |
} |
} |
} |
} |
} |
} |
Line 710 END
|
Line 763 END
|
my ($owner,$group)=split(/\:/,$devchown); |
my ($owner,$group)=split(/\:/,$devchown); |
if ($category eq 'conf') { |
if ($category eq 'conf') { |
$description.=<<END; |
$description.=<<END; |
\tinstall -b -S `date +'.\%Y\%m\%d\%H\%M\%S'` -o $owner -g $group -m $devchmod \$(SOURCE)/$source \$(TARGET)/$rot |
\tcp -p \$(TARGET)/$rot \$(TARGET)/$rot`date +'.\%Y\%m\%d\%H\%M\%S'` 2>/dev/null; install -o $owner -g $group -m $devchmod \$(SOURCE)/$source \$(TARGET)/$rot |
END |
END |
} |
} |
} |
} |
Line 939 sub end_spec_page {
|
Line 992 sub end_spec_page {
|
|
|
# ------------------------------------------------------- Begin description page |
# ------------------------------------------------------- Begin description page |
sub begin_description_page { |
sub begin_description_page { |
my $description=<<END; |
my ($mode)=@_; |
|
my $description; |
|
unless ($mode eq 'status') { |
|
$description=<<END; |
<HTML> |
<HTML> |
<HEAD> |
<HEAD> |
<TITLE>LON-CAPA Software Description Page ($distribution, $date)</TITLE> |
<TITLE>LON-CAPA Software Description Page ($distribution, $date)</TITLE> |
Line 964 http://install.lon-capa.org/compile/inde
|
Line 1020 http://install.lon-capa.org/compile/inde
|
information. |
information. |
</P> |
</P> |
END |
END |
|
} |
|
else { |
|
$description=<<END; |
|
<HTML> |
|
<HEAD> |
|
<TITLE>LON-CAPA Software File System Status Page ($distribution, $date)</TITLE> |
|
</HEAD> |
|
<BODY> |
|
<FONT SIZE=+2>LON-CAPA Software File System Status Page ($distribution, $date)</FONT> |
|
<BR>Michigan State University |
|
<BR>Learning Online with CAPA |
|
<BR>Contact korte\@lon-capa.org |
|
<UL> |
|
<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> |
|
<P> |
|
This file is generated dynamically by <TT>parse.pl</TT> as |
|
part of a status checking process. See http://install.lon-capa.org/ |
|
for more information. |
|
</P> |
|
END |
|
} |
return $description; |
return $description; |
|
|
} |
} |
|
|
# ------------------------------------------------- End description page |
# ------------------------------------------------- End description page |
Line 980 END
|
Line 1064 END
|
|
|
# ------------------------------------------------- Make RPM description block |
# ------------------------------------------------- Make RPM description block |
sub make_rpm_description_block { |
sub make_rpm_description_block { |
my $description=<<END; |
my ($mode)=@_; |
|
my $description; |
|
unless ($mode eq 'status') { |
|
$description=<<END; |
<FONT SIZE=+2>Rolled in a RedHat 6.2 RPM, $date</FONT> |
<FONT SIZE=+2>Rolled in a RedHat 6.2 RPM, $date</FONT> |
<P> |
<P> |
<TABLE BGCOLOR=#FFFFFF BORDER=0 CELLPADDING=10 CELLSPACING=0> |
<TABLE BGCOLOR=#FFFFFF BORDER=0 CELLPADDING=10 CELLSPACING=0> |
Line 1001 $info{'RPM'}{'description'}
|
Line 1088 $info{'RPM'}{'description'}
|
</TABLE> |
</TABLE> |
</P> |
</P> |
END |
END |
|
} |
|
else { |
|
my $exist=`rpm -q LON-CAPA-base 2>/dev/null`; |
|
unless ($exist) { |
|
$description=<<END; |
|
<FONT SIZE=+2>No LON-CAPA RPM on the system, (installed ??????)</FONT> |
|
<P> |
|
<TABLE BGCOLOR=#FFFFFF BORDER=0 CELLPADDING=10 CELLSPACING=0> |
|
<TR><TD> |
|
<FONT SIZE=+3>Error! A LON-CAPA-base RPM |
|
was never installed on this system!</FONT> |
|
</TD></TR> |
|
</TD></TR> |
|
</TABLE> |
|
</P> |
|
END |
|
} |
|
else { |
|
chop $exist; |
|
my $rpmname=`rpm -q --queryformat '%{NAME}' LON-CAPA-base`; |
|
my $rpmversion=`rpm -q --queryformat '%{VERSION}' LON-CAPA-base`; |
|
my $rpmrelease=`rpm -q --queryformat '%{RELEASE}' LON-CAPA-base`; |
|
my $idate=`rpm -q --queryformat '%{INSTALLTIME:date}' LON-CAPA-base`; |
|
my $rpmvendor=`rpm -q --queryformat '%{VENDOR}' LON-CAPA-base`; |
|
my $rpmbuildhost=`rpm -q --queryformat '%{BUILDHOST}' LON-CAPA-base`; |
|
my $rpmgroup=`rpm -q --queryformat '%{GROUP}' LON-CAPA-base`; |
|
my $rpmlicense=`rpm -q --queryformat '%{LICENSE}' LON-CAPA-base`; |
|
my $rpmsummary=`rpm -q --queryformat '%{SUMMARY}' LON-CAPA-base`; |
|
my $rpmdescription=`rpm -q --queryformat '%{DESCRIPTION}' LON-CAPA-base`; |
|
$description=<<END; |
|
<FONT SIZE=+2>Current RedHat RPM on the system, (installed $idate)</FONT> |
|
<P> |
|
<TABLE BGCOLOR=#FFFFFF BORDER=0 CELLPADDING=10 CELLSPACING=0> |
|
<TR><TD> |
|
<PRE> |
|
Name : $rpmname |
|
Version : $rpmversion |
|
Vendor : $rpmvendor |
|
Release : $rpmrelease |
|
Build Host : $rpmbuildhost |
|
Group : $rpmgroup |
|
License : $rpmlicense |
|
Summary : $rpmsummary |
|
Description : |
|
$rpmdescription |
|
</PRE> |
|
</TD></TR> |
|
</TABLE> |
|
</P> |
|
END |
|
} |
|
} |
return $description; |
return $description; |
} |
} |
|
|
Line 1013 sub determine_directory_structure {
|
Line 1152 sub determine_directory_structure {
|
|
|
# ---------------------------------- Make directory structure description block |
# ---------------------------------- Make directory structure description block |
sub make_directory_structure_description_block { |
sub make_directory_structure_description_block { |
my ($dirs)=@_; |
my ($dirs,$mode)=@_; |
|
my $dirstatus; my $statusheader; |
my $description=<<END; |
my $description=<<END; |
<FONT SIZE=+2>Directory Structure Description, $date</FONT> |
<FONT SIZE=+2>Directory Structure Description, $date</FONT> |
<P> |
<P> |
Line 1039 END
|
Line 1179 END
|
$maxcount=$count if $count>$maxcount; |
$maxcount=$count if $count>$maxcount; |
delete $diraccount{$d}; |
delete $diraccount{$d}; |
} |
} |
|
if ($mode eq 'status') { |
|
$statusheader="<TH ALIGN=LEFT BGCOLOR=#FFFFFF>Current Status</TH>"; |
|
} |
$description.=<<END; |
$description.=<<END; |
<TR> |
<TR> |
|
$statusheader |
<TH ALIGN=LEFT BGCOLOR=#FFFFFF>Category</TH> |
<TH ALIGN=LEFT BGCOLOR=#FFFFFF>Category</TH> |
<TH ALIGN=LEFT BGCOLOR=#FFFFFF>Permissions</TH> |
<TH ALIGN=LEFT BGCOLOR=#FFFFFF>Permissions</TH> |
<TH ALIGN=LEFT BGCOLOR=#FFFFFF><FONT COLOR=#FF0000>Development<BR>Permissions</FONT></TH> |
<TH ALIGN=LEFT BGCOLOR=#FFFFFF><FONT COLOR=#FF0000>Development<BR>Permissions</FONT></TH> |
Line 1061 END
|
Line 1205 END
|
my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'}; |
my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'}; |
my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'}; |
my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'}; |
my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'}; |
my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'}; |
|
if ($mode eq 'status') { |
|
my $ds=`find /$d -type d -prune -printf "\%m\t\%u\t\%g" 2>/dev/null`; |
|
unless ($ds) { |
|
$dirstatus='<TD BGCOLOR=#FFFFFF><B><U>MISSING</U></B></TD>'; |
|
} |
|
else { |
|
my @dss=split(/\t/,$ds); |
|
my $dssz=$dss[0]; |
|
$dssz="0" . $dss[0] if length($dss[0])<4; |
|
$dss[0]=$dssz; |
|
$ds="$dss[0] $dss[1]:$dss[2]"; |
|
if ($ds eq "$chmod $chown" && $ds eq "$devchmod $devchown") { |
|
$dirstatus='<TD BGCOLOR=#FFFFFF>runtime+development</TD>'; |
|
} |
|
elsif ($ds eq "$chmod $chown") { |
|
$dirstatus='<TD BGCOLOR=#FFFFFF>runtime</TD>'; |
|
} |
|
elsif ($ds eq "$devchmod $devchown") { |
|
$dirstatus='<TD BGCOLOR=#FFFFFF>development</TD>'; |
|
} |
|
else { |
|
$dirstatus="<TD BGCOLOR=#FFFFFF><B><U>ERROR</U></B><BR>$ds</TD>"; |
|
} |
|
} |
|
} |
$description.=<<END; |
$description.=<<END; |
<TR> |
<TR> |
|
$dirstatus |
<TD BGCOLOR=#FFFFFF>$category</TD> |
<TD BGCOLOR=#FFFFFF>$category</TD> |
<TD BGCOLOR=#FFFFFF><TT>$chmod $chown</TT></TD> |
<TD BGCOLOR=#FFFFFF><TT>$chmod $chown</TT></TD> |
<TD BGCOLOR=#FFFFFF><FONT COLOR=#FF0000><TT>$devchmod $devchown</TT></FONT></TD> |
<TD BGCOLOR=#FFFFFF><FONT COLOR=#FF0000><TT>$devchmod $devchown</TT></FONT></TD> |
Line 1081 END
|
Line 1251 END
|
|
|
# ------------------- Make file type ownership and permissions description block |
# ------------------- Make file type ownership and permissions description block |
sub make_file_type_ownership_and_permissions_description_block { |
sub make_file_type_ownership_and_permissions_description_block { |
|
my ($mode)=@_; |
my $description=<<END; |
my $description=<<END; |
<FONT SIZE=+2>File Type Ownership and Permissions Descriptions, $date</FONT> |
<FONT SIZE=+2>File Type Ownership and Permissions Descriptions, $date</FONT> |
<P> |
<P> |
Line 1120 END
|
Line 1291 END
|
|
|
# ------------------------- Make directory and file structure description block |
# ------------------------- Make directory and file structure description block |
sub make_directory_and_file_structure_description_block { |
sub make_directory_and_file_structure_description_block { |
my ($dirs)=@_; |
my ($dirs,$mode)=@_; |
|
my $statusheader; my $filestatus; |
my $description=<<END; |
my $description=<<END; |
<FONT SIZE=+2>Directory and File Structure Description, $date</FONT> |
<FONT SIZE=+2>Directory and File Structure Description, $date</FONT> |
<P> |
<P> |
Line 1174 END
|
Line 1346 END
|
END |
END |
} |
} |
if (@files) { |
if (@files) { |
|
if ($mode eq 'status') { |
|
$statusheader=<<END; |
|
<TH BGCOLOR=$color ALIGN=LEFT>Current Status</TH> |
|
END |
|
} |
$description.=<<END; |
$description.=<<END; |
<TR> |
<TR> |
|
$statusheader |
<TH BGCOLOR=$color ALIGN=LEFT COLSPAN=2>Type</TH> |
<TH BGCOLOR=$color ALIGN=LEFT COLSPAN=2>Type</TH> |
<TH BGCOLOR=$color ALIGN=LEFT>File Name</TH> |
<TH BGCOLOR=$color ALIGN=LEFT>File Name</TH> |
<TH BGCOLOR=$color ALIGN=LEFT>Function</TH> |
<TH BGCOLOR=$color ALIGN=LEFT>Function</TH> |
Line 1187 END
|
Line 1365 END
|
my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'}; |
my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'}; |
my $fdescription=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'DESCRIPTION'}; |
my $fdescription=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'DESCRIPTION'}; |
my $source=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'}; |
my $source=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'}; |
|
my $source2=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'}; |
my $note=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'NOTE'}; |
my $note=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'NOTE'}; |
$note.="<BR>" if $note; |
$note.="<BR>" if $note; |
my $listing=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'FILES'}; |
my $listing=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'FILES'}; |
Line 1219 END
|
Line 1398 END
|
$source="<FONT COLOR=#FF0000>$source</FONT>"; |
$source="<FONT COLOR=#FF0000>$source</FONT>"; |
} |
} |
} |
} |
|
my $checksum; |
|
my $checksum_source; |
|
my $checksum_target; |
|
if ($mode eq 'status') { |
|
$filestatus=''; |
|
my $fs; |
|
my $listing2=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'FILES'}; |
|
my @E=split(/\s+/,$listing2); shift @E; |
|
if (@E) { |
|
$fs=`find /$filesfull[$i] -prune -printf "\%m\t\%u\t\%g\n" 2>/dev/null | wc -l`; chop $fs; |
|
if ($fs!=(@E+0)) { |
|
$ecount=(@E+0); |
|
$estuff=join(",",@E); |
|
$filestatus="<TD BGCOLOR=#FFFFFF><B><U>ERROR. SOME FILES ARE MISSING</U></B></TD>"; |
|
} |
|
$fs=`find /$filesfull[$i] -prune -printf "\%m\t\%u\t\%g\n" 2>/dev/null | sort | uniq | wc -l`; chop $fs; |
|
if ($fs!=1) { |
|
$filestatus='<TD BGCOLOR=#FFFFFF><B><U>ERROR. THERE ARE MULTIPLE OWNERSHIPS/PERMISSIONS WHEN ALL THESE FILES SHOULD HAVE THE SAME CONFIGURATION</U></B></TD>'; |
|
} |
|
else { |
|
$fs=`find /$filesfull[$i] -prune -printf "\%m\t\%u\t\%g\n" 2>/dev/null | sort | uniq`; chop $fs; |
|
} |
|
} |
|
else { |
|
$fs=`find /$filesfull[$i] -prune -printf "\%m\t\%u\t\%g" 2>/dev/null`; |
|
if (-f "/$filesfull[$i]" && !(-l "/$filesfull[$i]")) { |
|
$checksum_source=`md5sum ../../$source2 | cut -d ' ' -f1`; |
|
chop $checksum_source; |
|
$checksum_target=`md5sum /$filesfull[$i] | cut -d ' ' -f1`; |
|
chop $checksum_target; |
|
# warn ("CS: $checksum_source, CT: $checksum_target\n"); |
|
unless ($checksum_source eq $checksum_target) { |
|
$checksum="<BR><B><U>CHECKSUM DIFFERENCE</U></B>"; |
|
} |
|
} |
|
} |
|
my $fsl=`find /$filesfull[$i] -type l -prune -printf "\%m\t\%u\t\%g" 2>/dev/null`; |
|
unless ($fs || $filestatus) { |
|
$filestatus='<TD BGCOLOR=#FFFFFF><B><U>MISSING</U></B></TD>'; |
|
} |
|
elsif (!$filestatus) { |
|
|
|
$chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'}; |
|
$chown=$info{'OWNERSHIP'}{$category}{'CHOWN'}; |
|
$devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'}; |
|
$devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'}; |
|
|
|
my @fss=split(/\t/,$fs); |
|
my $fssz=$fss[0]; |
|
$fssz="0" . $fss[0] if length($fss[0])<4; |
|
$fss[0]=$fssz; |
|
$fs="$fss[0] $fss[1]:$fss[2]"; |
|
$s=' '; |
|
if ($fsl) { |
|
$fs="$fss[1]:$fss[2]"; |
|
$s=''; |
|
} |
|
if ($fs eq "$chmod$s$chown" && $fs eq "$devchmod$s$devchown") { |
|
$filestatus="<TD BGCOLOR=#FFFFFF>runtime+development$checksum</TD>"; |
|
} |
|
elsif ($fs eq "$chmod$s$chown") { |
|
$filestatus="<TD BGCOLOR=#FFFFFF>runtime$checksum</TD>"; |
|
} |
|
elsif ($fs eq "$devchmod$s$devchown") { |
|
$filestatus="<TD BGCOLOR=#FFFFFF>development$checksum</TD>"; |
|
} |
|
else { |
|
$filestatus="<TD BGCOLOR=#FFFFFF><B><U>ERROR</U></B><BR>$fs</TD>"; |
|
} |
|
} |
|
} |
$description.=<<END; |
$description.=<<END; |
<TR> |
<TR> |
|
$filestatus |
<TD BGCOLOR=#A0A0A0><IMG SRC="$fcm{$category}.gif" ALT="$category"></TD> |
<TD BGCOLOR=#A0A0A0><IMG SRC="$fcm{$category}.gif" ALT="$category"></TD> |
<TD BGCOLOR=$color>$category</TD> |
<TD BGCOLOR=$color>$category</TD> |
<TD BGCOLOR=$color>$files[$i]</TD> |
<TD BGCOLOR=$color>$files[$i]</TD> |