File:  [LON-CAPA] / loncom / build / Attic / parse.pl
Revision 1.28: download - view: text, annotated - select for diffs
Mon Feb 26 21:21:47 2001 UTC (23 years, 3 months ago) by harris41
Branches: MAIN
CVS tags: HEAD
implementing checksum comparisons to support the make status/ make statuspost
targets -Scott

    1: #!/usr/bin/perl
    2: 
    3: # Scott Harrison
    4: # November 2000
    5: 
    6: # Read in loncapa tags and metagroup tags
    7: 
    8: # ---------------------------------------------- Read in command line arguments
    9: my ($file,$mode)=@ARGV;
   10: 
   11: # ---------------------------------------------------- Read in master data file
   12: open IN,"<$file";
   13: my @lines=<IN>;
   14: close IN;
   15: my $info1=join('',@lines);
   16: my $info2=$info1; # value to allow for meta data group retrieval
   17: 
   18: # ------------------------------------------------------- Make default settings
   19: my $distribution="redhat6.2";
   20: my $date=`date +'%B %e, %Y'`; chop $date;
   21: my $buildhost=`hostname`; chop $buildhost;
   22: # file category mappings
   23: my %fcm=(
   24: 	 'conf' => 'configurable',
   25: 	 'graphic file' => 'graphicfile',
   26: 	 'handler' => 'handler',
   27: 	 'interface file' => 'interfacefile',
   28: 	 'symbolic link' => 'link',
   29: 	 'root script' => 'rootscript',
   30: 	 'script' => 'script',
   31: 	 'setuid script' => 'setuid',
   32: 	 'static conf' => 'static',
   33: 	 'system file' => 'systemfile',
   34: 	 );
   35: 
   36: # ---------------------------------------------------- Parse the marked up data
   37: my %info; # big data storage object
   38: while ($info1=~/\<loncapa\s+(.*?)\>/isg) {
   39:     my $keystring=$1;
   40:     # In the parsing of LON-CAPA tags, remove boundary white-space,
   41:     # and handle quotation commands.
   42:     my %hash=map {my ($key,$value)=split(/\=(?!")|\=(?=\s*"[^"]*"[^"]*$)/);
   43:                                    $value=~s/^"//;
   44:  				   $value=~s/"$//;
   45:                                    (uc($key),$value);}
   46:              split(/\s+(?=\w+\s*\=)/,$keystring);
   47:     # Handle the different types of commands
   48:     if (uc($hash{'TYPE'}) eq "OWNERSHIP") {
   49:         $info{$hash{'TYPE'}}{$hash{'CATEGORY'}}{'CHMOD'}=$hash{'CHMOD'};
   50:         $info{$hash{'TYPE'}}{$hash{'CATEGORY'}}{'CHOWN'}=$hash{'CHOWN'};
   51:     }
   52:     elsif (uc($hash{'TYPE'}) eq "DEVOWNERSHIP") {
   53:         $info{$hash{'TYPE'}}{$hash{'CATEGORY'}}{'CHMOD'}=$hash{'CHMOD'};
   54:         $info{$hash{'TYPE'}}{$hash{'CATEGORY'}}{'CHOWN'}=$hash{'CHOWN'};
   55:     }
   56:     elsif (uc($hash{'TYPE'}) eq "RPM") {
   57:         $hash{'VALUE'}=~s/\\n/\n/g;
   58:         $info{$hash{'TYPE'}}{$hash{'NAME'}}=$hash{'VALUE'};
   59:     }
   60:     elsif (uc($hash{'TYPE'}) eq "DIRECTORY") {
   61:         $info{$hash{'TYPE'}}{$hash{'DIST'}}{$hash{'TARGET'}}{'CATEGORY'}=
   62:                                                        $hash{'CATEGORY'};
   63:         $info{$hash{'TYPE'}}{$hash{'DIST'}}{$hash{'TARGET'}}{'DESCRIPTION'}=
   64:                                $hash{'DESCRIPTION'} if $hash{'DESCRIPTION'};
   65:     }
   66:     elsif (uc($hash{'TYPE'}) eq "LOCATION") {
   67:         $info{$hash{'TYPE'}}{$hash{'DIST'}}{$hash{'TARGET'}}{'CATEGORY'}=                               $hash{'CATEGORY'};
   68:         $info{$hash{'TYPE'}}{$hash{'DIST'}}{$hash{'TARGET'}}{'LINKTO'}=                               $hash{'LINKTO'};
   69:         $info{$hash{'TYPE'}}{$hash{'DIST'}}{$hash{'TARGET'}}{'SOURCE'}=                                               $hash{'SOURCE'};
   70:         # get surrounding metagroup information
   71:         my $ckeystring=$keystring; $ckeystring=~s/(SOURCE\=\"[^"]*)\*/$1\\\*/g;
   72:         $ckeystring=~s/(TARGET\=\"[^"]*)\*/$1\\\*/g;
   73:         $info2=~/.*\<(?:metagroup|metasupergroup)\>(.*?)\<loncapa\s+$ckeystring\>(.*?)\<\/(?:metagroup|metasupergroup)\>/is;
   74: 	my $data=$1.$2;
   75:         my @meta=('description','build','dependencies','files','note');
   76:         foreach my $m (@meta) {
   77: 	    if ($data=~/\<($m)\>(.*?)\<\/$m\>/sgi) {
   78: 		my ($key,$value)=($1,$2);
   79: 		$info{$hash{'TYPE'}}{$hash{'DIST'}}{$hash{'TARGET'}}{uc($key)}=
   80: 		                                                    $value;
   81: 	    }
   82:         }
   83:     }
   84:     else {
   85:         warn("WARNING: this tag text will be ignored since it cannot be understood\n---> $keystring\n");
   86:     }
   87: }
   88: 
   89: my $a;
   90: my @directories;
   91: if ($mode eq "HTML") {
   92:     $a=&begin_description_page;
   93:     print $a;
   94:     $a=&make_rpm_description_block;
   95:     print $a;
   96:     @directories=&determine_directory_structure;
   97:     $a=&make_directory_structure_description_block(\@directories);
   98:     print $a;
   99:     $a=&make_file_type_ownership_and_permissions_description_block;
  100:     print $a;
  101:     $a=&make_directory_and_file_structure_description_block(\@directories);
  102:     print $a;
  103:     $a=&end_description_page;
  104:     print $a;
  105: }
  106: elsif ($mode eq "SPEC") {
  107:     my $out=$info{'RPM'}{'Name'} . '-' . $info{'RPM'}{'Version'} . '.spec';
  108:     open OUT,">$out";
  109:     $a=&make_rpm_spec_block;
  110:     print OUT $a;
  111:     $a=&make_rpm_build_block;
  112:     print OUT $a;
  113:     @directories=&determine_directory_structure;
  114:     $a=&make_directory_structure_spec_block(\@directories);
  115:     print OUT $a;
  116:     $a=&make_directory_and_file_structure_spec_block(\@directories);
  117:     print OUT $a;
  118:     $a=&end_spec_page;
  119:     print OUT $a;
  120:     close OUT;
  121: }
  122: elsif ($mode eq "LCMakefile") {
  123:     @directories=&determine_directory_structure;
  124:     $a=&make_directory_LCMakefile_segment(\@directories);
  125:     print $a;
  126:     $a=&make_files_LCMakefile_segment(\@directories);
  127:     print $a;
  128:     $a=&make_links_LCMakefile_segment(\@directories);
  129:     print $a;
  130: }
  131: elsif ($mode eq "BinaryRoot") {
  132:     mkdir "BinaryRoot",0755;
  133:     open OUT,">Makefile.BinaryRoot";
  134:     @directories=&determine_directory_structure;
  135:     $a=&make_directory_binaryroot_segment(\@directories);
  136:     print OUT $a;
  137:     $a=&make_files_binaryroot_segment(\@directories);
  138:     print OUT $a;
  139:     $a=&make_links_binaryroot_segment(\@directories);
  140:     print OUT $a;
  141:     close OUT;
  142:     print `make -f Makefile.BinaryRoot TARGET='BinaryRoot' SOURCE='../..' directories`;
  143:     print `make -f Makefile.BinaryRoot TARGET='BinaryRoot' SOURCE='../..' files`;
  144:     print `make -f Makefile.BinaryRoot TARGET='BinaryRoot' SOURCE='../..' links`;
  145:     open OUT,">base_file_list.txt";
  146:     $a=&make_file_list(\@directories);
  147:     print OUT $a;
  148:     close OUT;
  149:     open OUT,">setup_file_list.txt";
  150:     print OUT "BinaryRoot/etc/passwd\n";
  151:     close OUT;
  152:     open OUT,">BinaryRoot/etc/passwd";
  153:     print OUT<<END;
  154: root::0:0:root:/root:/bin/bash
  155: bin:!!:1:1:bin:/bin:
  156: daemon:!!:2:2:daemon:/sbin:
  157: adm:!!:3:4:adm:/var/adm:
  158: lp:!!:4:7:lp:/var/spool/lpd:
  159: sync:!!:5:0:sync:/sbin:/bin/sync
  160: shutdown:!!:6:0:shutdown:/sbin:/sbin/shutdown
  161: halt:!!:7:0:halt:/sbin:/sbin/halt
  162: mail:!!:8:12:mail:/var/spool/mail:
  163: news:!!:9:13:news:/var/spool/news:
  164: uucp:!!:10:14:uucp:/var/spool/uucp:
  165: operator:!!:11:0:operator:/root:
  166: games:!!:12:100:games:/usr/games:
  167: gopher:!!:13:30:gopher:/usr/lib/gopher-data:
  168: ftp:!!:14:50:FTP User:/home/ftp:
  169: nobody:!!:99:99:Nobody:/:
  170: www:!!:500:500:www:/home/www:/bin/bash
  171: END
  172: close OUT;
  173:     open OUT,">>setup_file_list.txt";
  174:     print OUT "BinaryRoot/etc/hosts.deny\n";
  175:     close OUT;
  176:     open OUT,">BinaryRoot/etc/hosts.deny";
  177:     print OUT<<END;
  178: ALL: ALL
  179: END
  180: close OUT;
  181:     
  182:     `install -o 500 -g 500 -m 0700 -d BinaryRoot/home/www`;
  183:     open OUT,">>setup_file_list.txt";
  184:     print OUT "BinaryRoot/home/www\n";
  185:     close OUT;
  186:     `install -d BinaryRoot/etc/pam.d`;
  187:     open OUT,">>setup_file_list.txt";
  188:     print OUT "BinaryRoot/etc/pam.d/passwd\n";
  189:     close OUT;
  190:     open OUT,">BinaryRoot/etc/pam.d/passwd";
  191:     print OUT<<END;
  192: #%PAM-1.0
  193: auth       required     /lib/security/pam_pwdb.so shadow nullok
  194: account    required     /lib/security/pam_pwdb.so
  195: password   required     /lib/security/pam_cracklib.so retry=3
  196: password   required     /lib/security/pam_pwdb.so use_authtok nullok
  197: END
  198: close OUT;
  199:     open OUT,">>setup_file_list.txt";
  200:     print OUT "BinaryRoot/etc/pam.d/login\n";
  201:     close OUT;
  202:     open OUT,">BinaryRoot/etc/pam.d/login";
  203:     print OUT<<END;
  204: #%PAM-1.0
  205: auth       required     /lib/security/pam_securetty.so
  206: auth       required     /lib/security/pam_pwdb.so shadow nullok
  207: auth       required     /lib/security/pam_nologin.so
  208: account    required     /lib/security/pam_pwdb.so
  209: password   required     /lib/security/pam_cracklib.so
  210: password   required     /lib/security/pam_pwdb.so nullok use_authtok
  211: session    required     /lib/security/pam_pwdb.so
  212: session    optional     /lib/security/pam_console.so
  213: END
  214: close OUT;
  215: 
  216: }
  217: elsif ($mode eq "status") {
  218:     $a=&begin_description_page('status');
  219:     print $a;
  220:     $a=&make_rpm_description_block('status');
  221:     print $a;
  222:     @directories=&determine_directory_structure('status');
  223:     $a=&make_directory_structure_description_block(\@directories,'status');
  224:     print $a;
  225:     $a=&make_file_type_ownership_and_permissions_description_block('status');
  226:     print $a;
  227:     $a=&make_directory_and_file_structure_description_block(\@directories,'status');
  228:     print $a;
  229:     $a=&end_description_page('status');
  230:     print $a;
  231: }
  232: elsif ($mode eq "update") {
  233: }
  234: elsif ($mode eq "configinstall") {
  235:     @directories=&determine_directory_structure;
  236:     $a=&make_files_configinstall_segment(\@directories);
  237:     print $a;
  238:     $a=&make_files_configpermissions_segment(\@directories);
  239:     print $a;
  240: }
  241: elsif ($mode eq "install") {
  242:     @directories=&determine_directory_structure;
  243:     $a=&make_directory_install_segment(\@directories);
  244:     print $a;
  245:     $a=&make_files_install_segment(\@directories);
  246:     print $a;
  247:     $a=&make_links_install_segment(\@directories);
  248:     print $a;
  249: }
  250: elsif ($mode eq "build") {
  251:     @directories=&determine_directory_structure;
  252:     $a=&make_files_build_segment(\@directories);
  253:     print $a;
  254: }
  255: 
  256: # ------------------------------------------------------ a list of file targets
  257: sub make_file_list {
  258:     my ($dirs)=@_;
  259:     my $description;
  260:     my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
  261:     foreach my $d (@$dirs) {
  262: 	# set other values
  263: 	$description.=<<END;
  264: BinaryRoot/$d
  265: END
  266: 	my $dirdescription=$info{'DIRECTORY'}{$distribution}{$d}{'DESCRIPTION'};
  267: 	$dirdescription="(" . $dirdescription . ")" if $dirdescription;
  268: 	# find files that are contained in this directory
  269: 	my @files;
  270: 	my @filesfull;
  271: 	foreach my $f (@allfiles) {
  272: 	    if ($f=~/^$d\/([^\/]+)$/) {
  273: 		push @files,$1;
  274: 		push @filesfull,$f;
  275: 	    }
  276: 	}
  277: 	# render starting HTML formatting elements
  278: 	if (@files) {
  279:         }
  280: 	my $pwd=`pwd`; chop $pwd;
  281: 	if (@files) {
  282:             foreach my $i (0..$#files) {
  283: 		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
  284: 		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
  285: 		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
  286: 		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
  287: 		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
  288: 		my $source=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'};
  289: 		my $rot="/".$filesfull[$i];
  290: 		if ($rot=~/\*/) {
  291: 		    $rot=~s/[^\/]+$// if $rot=~/\*/;
  292: 		    my $listing=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'FILES'};
  293: 		    chop $listing;
  294: 		    my @list=split(/\s+/,$listing);
  295: 		    my $rot2;
  296: 		    foreach my $l (@list) {
  297: 			$l=~s/^\s*//; $l=~s/\s*$//;
  298: 			$rot2.="BinaryRoot$rot$l\n" if length($l);
  299: 		    }
  300: 		    chop $rot2;
  301: 		    $rot=$rot2;
  302: 		}
  303: 		else {
  304: 		    $rot="BinaryRoot$rot";
  305: 		}
  306: 		if ($category eq "conf") {
  307: 		    $rot.=" # config";
  308: 		}
  309: 		$description.=<<END;
  310: $rot
  311: END
  312: 	    }
  313: 	}
  314:     }
  315:     $description.=<<END;
  316: 
  317: END
  318:     return $description;
  319: }
  320: 
  321: # --------------------------------- Commands to make BinaryRoot directories
  322: sub make_directory_binaryroot_segment {
  323:     my ($dirs)=@_;
  324:     my $description=<<END;
  325: directories:
  326: END
  327:     foreach my $d (@$dirs) {
  328: 	my $category=$info{'DIRECTORY'}{$distribution}{$d}{'CATEGORY'};
  329: 	my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
  330: 	my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
  331: 	my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
  332: 	my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
  333: 	my ($owner,$group)=split(/\:/,$devchown);
  334: 	my $own=$devchown; $own=~s/\:/\,/;
  335: 	$description.=<<END;
  336: \tinstall -o $owner -g $group -m $devchmod -d \$(TARGET)/$d
  337: END
  338:     }
  339:     $description.=<<END;
  340: 
  341: END
  342:     return $description;
  343: }
  344: 
  345: # --------------------------------------- Commands to make BinaryRoot files
  346: sub make_files_binaryroot_segment {
  347:     my ($dirs)=@_;
  348:     my $description=<<END;
  349: files:
  350: END
  351:     my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
  352:     foreach my $d (@$dirs) {
  353: 	# set other values
  354: 	my $dirdescription=$info{'DIRECTORY'}{$distribution}{$d}{'DESCRIPTION'};
  355: 	$dirdescription="(" . $dirdescription . ")" if $dirdescription;
  356: 	# find files that are contained in this directory
  357: 	my @files;
  358: 	my @filesfull;
  359: 	foreach my $f (@allfiles) {
  360: 	    if ($f=~/^$d\/([^\/]+)$/) {
  361: 		push @files,$1;
  362: 		push @filesfull,$f;
  363: 	    }
  364: 	}
  365: 	# render starting HTML formatting elements
  366: 	if (@files) {
  367: 	    $description.=<<END;
  368: \t# $d $dirdescription
  369: END
  370:         }
  371: 	if (@files) {
  372:             foreach my $i (0..$#files) {
  373: 		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
  374: 		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
  375: 		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
  376: 		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
  377: 		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
  378: 		my $source=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'};
  379: 		my $rot=$filesfull[$i];
  380: 		$rot=~s/[^\/]+$/\./ if $rot=~/\*/;
  381: 		my ($owner,$group)=split(/\:/,$devchown);
  382: 		$description.=<<END if $category ne 'symbolic link';
  383: \tinstall -o $owner -g $group -m $devchmod \$(SOURCE)/$source \$(TARGET)/$rot
  384: END
  385: 	    }
  386: 	}
  387:     }
  388:     $description.=<<END;
  389: 
  390: END
  391:     return $description;
  392: }
  393: 
  394: # ------------------------------ Commands to make BinaryRoot symbolic links
  395: sub make_links_binaryroot_segment {
  396:     my ($dirs)=@_;
  397:     my $description=<<END;
  398: links:
  399: END
  400:     my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
  401:     foreach my $d (@$dirs) {
  402: 	# find files that are contained in this directory
  403: 	my @files;
  404: 	my @filesfull;
  405: 	foreach my $f (@allfiles) {
  406: 	    if ($f=~/^$d\/([^\/]+)$/) {
  407: 		push @files,$1;
  408: 		push @filesfull,$f;
  409: 	    }
  410: 	}
  411: 	# render starting HTML formatting elements
  412: 	if (@files) {
  413:             foreach my $i (0..$#files) {
  414: 		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
  415: 		my $linkto=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'LINKTO'};
  416: 		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
  417: 		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
  418: 		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
  419: 		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
  420: 		$description.=<<END if $category eq 'symbolic link';
  421: \tln -s /$linkto \$(TARGET)/$filesfull[$i]
  422: END
  423: 	    }
  424: 	}
  425:     }
  426:     $description.=<<END;
  427: 
  428: END
  429:     return $description;
  430: }
  431: 
  432: # ------ Installation commands for a Makefile used only by a rpm -ba invocation
  433: sub make_directory_LCMakefile_segment {
  434:     my ($dirs)=@_;
  435:     my $description=<<END;
  436: directories:
  437: END
  438:     foreach my $d (@$dirs) {
  439: 	my $category=$info{'DIRECTORY'}{$distribution}{$d}{'CATEGORY'};
  440: 	my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
  441: 	my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
  442: 	my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
  443: 	my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
  444: 	my $own=$devchown; $own=~s/\:/\,/;
  445: 	$description.=<<END;
  446: \tinstall -m $devchmod -d \$(SOURCE)/$d \$(ROOT)/$d
  447: END
  448:     }
  449:     $description.=<<END;
  450: 
  451: END
  452:     return $description;
  453: }
  454: 
  455: # ------ Installation commands for a Makefile used only by a rpm -ba invocation
  456: sub make_files_LCMakefile_segment {
  457:     my ($dirs)=@_;
  458:     my $description=<<END;
  459: files:
  460: END
  461:     my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
  462:     foreach my $d (@$dirs) {
  463: 	# set other values
  464: 	my $dirdescription=$info{'DIRECTORY'}{$distribution}{$d}{'DESCRIPTION'};
  465: 	$dirdescription="(" . $dirdescription . ")" if $dirdescription;
  466: 	# find files that are contained in this directory
  467: 	my @files;
  468: 	my @filesfull;
  469: 	foreach my $f (@allfiles) {
  470: 	    if ($f=~/^$d\/([^\/]+)$/) {
  471: 		push @files,$1;
  472: 		push @filesfull,$f;
  473: 	    }
  474: 	}
  475: 	# render starting HTML formatting elements
  476: 	if (@files) {
  477: 	    $description.=<<END;
  478: \t# $d $dirdescription
  479: END
  480:         }
  481: 	if (@files) {
  482:             foreach my $i (0..$#files) {
  483: 		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
  484: 		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
  485: 		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
  486: 		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
  487: 		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
  488: 		my $rot=$filesfull[$i];
  489: 		$rot=~s/[^\/]+$/\./ if $rot=~/\*/;
  490: 		$description.=<<END if $category ne 'symbolic link';
  491: \tinstall -m $devchmod \$(SOURCE)/$filesfull[$i] \$(ROOT)/$rot
  492: END
  493: 	    }
  494: 	}
  495:     }
  496:     $description.=<<END;
  497: 
  498: END
  499:     return $description;
  500: }
  501: 
  502: # ------ Installation commands for a Makefile used only by a rpm -ba invocation
  503: sub make_links_LCMakefile_segment {
  504:     my ($dirs)=@_;
  505:     my $description=<<END;
  506: links:
  507: END
  508:     my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
  509:     foreach my $d (@$dirs) {
  510: 	# find files that are contained in this directory
  511: 	my @files;
  512: 	my @filesfull;
  513: 	foreach my $f (@allfiles) {
  514: 	    if ($f=~/^$d\/([^\/]+)$/) {
  515: 		push @files,$1;
  516: 		push @filesfull,$f;
  517: 	    }
  518: 	}
  519: 	# render starting HTML formatting elements
  520: 	if (@files) {
  521:             foreach my $i (0..$#files) {
  522: 		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
  523: 		my $linkto=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'LINKTO'};
  524: 		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
  525: 		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
  526: 		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
  527: 		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
  528: 		$description.=<<END if $category eq 'symbolic link';
  529: \tln -s /$linkto \$(ROOT)/$filesfull[$i]
  530: END
  531: 	    }
  532: 	}
  533:     }
  534:     $description.=<<END;
  535: 
  536: END
  537:     return $description;
  538: }
  539: 
  540: # --------------------------------- Installation commands to install directories
  541: sub make_directory_install_segment {
  542:     my ($dirs)=@_;
  543:     my $description=<<END;
  544: directories:
  545: END
  546:     foreach my $d (@$dirs) {
  547: 	my $category=$info{'DIRECTORY'}{$distribution}{$d}{'CATEGORY'};
  548: 	my $source=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'};
  549: 	my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
  550: 	my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
  551: 	my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
  552: 	my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
  553: 	my ($owner,$group)=split(/\:/,$devchown);
  554: 	my $own=$devchown; $own=~s/\:/\,/;
  555: 	$description.=<<END;
  556: \tinstall -o $owner -g $group -m $devchmod -d \$(TARGET)/$d
  557: END
  558:     }
  559:     $description.=<<END;
  560: 
  561: END
  562:     return $description;
  563: }
  564: 
  565: # ------------------------------------------------------ Commands to build files
  566: sub make_files_build_segment {
  567:     my ($dirs)=@_;
  568:     my $description;
  569:     my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
  570:     my $tab="\t";
  571:     my $sources="all: ";
  572:     foreach my $d (@$dirs) {
  573: 	# set other values
  574: 	my $dirdescription=$info{'DIRECTORY'}{$distribution}{$d}{'DESCRIPTION'};
  575: 	$dirdescription="(" . $dirdescription . ")" if $dirdescription;
  576: 	# find files that are contained in this directory
  577: 	my @files;
  578: 	my @filesfull;
  579: 	foreach my $f (@allfiles) {
  580: 	    if ($f=~/^$d\/([^\/]+)$/) {
  581: 		push @files,$1;
  582: 		push @filesfull,$f;
  583: 	    }
  584: 	}
  585: 	if (@files) {
  586:             foreach my $i (0..$#files) {
  587: 		# if has build information, output appropriate something
  588: 		my $build=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'BUILD'};
  589: 		my $source=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'};
  590: 		$build=~s/^\s+//; $build=~s/\s+$//;
  591: 		if ($build) {
  592: 		    my $dependencies=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'DEPENDENCIES'};
  593: 		    my $source2=$source;
  594: 		    $source2=~s/^[^\/]+\///;
  595:  		    $source2="../" . $source2;
  596: 		    $sources.="$source2 ";
  597: 		    my $directory=$build;
  598: 		    $directory=~s/^[^\/]+\///;
  599: 		    $directory=~s/([^\/]+)$//;
  600:  		    $directory="../" . $directory;
  601: 		    my $buildfile=$1;
  602: 		    my $sdir=$source;
  603: 		    $sdir=~s/^[^\/]+\///;
  604: 		    $sdir=~s/([^\/]+)$//;
  605:  		    $sdir="../" . $sdir;
  606: 		    $dependencies=~s/\s+$//;
  607: 		    my $depstat="";
  608: 		    if ($dependencies=~s/\s+\[ALWAYS_RUN_BUILD_COMMAND\]//) {
  609: 			$depstat=" alwaysrun";
  610: 		    }
  611: 		    $dependencies=~s/\s+/ $sdir/gs;
  612: 		    $description.=<<END;
  613: $source2: $dependencies$depstat
  614: ${tab}cd $directory; sh ./$buildfile
  615: 
  616: END
  617: 		}
  618: 		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
  619: 		my $source=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'};
  620: 		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
  621: 		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
  622: 		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
  623: 		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
  624: 		my $rot=$filesfull[$i];
  625: 		$rot=~s/[^\/]+$/\./ if $rot=~/\*/;
  626: #		$description.=<<END if $category ne 'symbolic link';
  627: #\tinstall -o $owner -g $group -m $devchmod \$(SOURCE)/$source \$(TARGET)/$rot
  628: #END
  629: 	    }
  630: 	}
  631:     }
  632:     $description.=<<END;
  633: alwaysrun:
  634: 
  635: END
  636:     $sources.="\n\n";
  637:     return ($sources . $description);
  638: }
  639: 
  640: # --------------------------------------- Installation commands to install files
  641: sub make_files_install_segment {
  642:     my ($dirs)=@_;
  643:     my $description=<<END;
  644: files:
  645: END
  646:     my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
  647:     foreach my $d (@$dirs) {
  648: 	# set other values
  649: 	my $dirdescription=$info{'DIRECTORY'}{$distribution}{$d}{'DESCRIPTION'};
  650: 	$dirdescription="(" . $dirdescription . ")" if $dirdescription;
  651: 	# find files that are contained in this directory
  652: 	my @files;
  653: 	my @filesfull;
  654: 	foreach my $f (@allfiles) {
  655: 	    if ($f=~/^$d\/([^\/]+)$/) {
  656: 		push @files,$1;
  657: 		push @filesfull,$f;
  658: 	    }
  659: 	}
  660: 	# render starting HTML formatting elements
  661: 	if (@files) {
  662: 	    $description.=<<END;
  663: \t# $d $dirdescription
  664: END
  665:         }
  666: 	if (@files) {
  667:             foreach my $i (0..$#files) {
  668: 		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
  669: 		my $source=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'};
  670: 		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
  671: 		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
  672: 		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
  673: 		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
  674: 		my $rot=$filesfull[$i];
  675: 		$rot=~s/[^\/]+$/\./ if $rot=~/\*/;
  676: 		my ($owner,$group)=split(/\:/,$devchown);
  677: 		if ($category ne 'conf') {
  678: 		    $description.=<<END if $category ne 'symbolic link';
  679: \tinstall -o $owner -g $group -m $devchmod \$(SOURCE)/$source \$(TARGET)/$rot
  680: END
  681:                 }
  682: 	    }
  683: 	}
  684:     }
  685:     $description.=<<END;
  686: 
  687: END
  688:     return $description;
  689: }
  690: 
  691: # ------ Installation commands to install configuration files (and make backups)
  692: sub make_files_configinstall_segment {
  693:     my ($dirs)=@_;
  694:     my $description=<<END;
  695: configfiles:
  696: END
  697:     my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
  698:     foreach my $d (@$dirs) {
  699: 	# set other values
  700: 	my $dirdescription=$info{'DIRECTORY'}{$distribution}{$d}{'DESCRIPTION'};
  701: 	$dirdescription="(" . $dirdescription . ")" if $dirdescription;
  702: 	# find files that are contained in this directory
  703: 	my @files;
  704: 	my @filesfull;
  705: 	foreach my $f (@allfiles) {
  706: 	    if ($f=~/^$d\/([^\/]+)$/) {
  707: 		push @files,$1;
  708: 		push @filesfull,$f;
  709: 	    }
  710: 	}
  711: 	# render starting HTML formatting elements
  712: 	if (@files) {
  713: 	    $description.=<<END;
  714: \t# $d $dirdescription
  715: END
  716:         }
  717: 	if (@files) {
  718:             foreach my $i (0..$#files) {
  719: 		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
  720: 		my $source=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'};
  721: 		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
  722: 		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
  723: 		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
  724: 		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
  725: 		my $rot=$filesfull[$i];
  726: 		$rot=~s/[^\/]+$/\./ if $rot=~/\*/;
  727: 		my ($owner,$group)=split(/\:/,$devchown);
  728: 		if ($category eq 'conf') {
  729: 		    $description.=<<END;
  730: \tinstall -b -S `date +'.\%Y\%m\%d\%H\%M\%S'` -o $owner -g $group -m $devchmod \$(SOURCE)/$source \$(TARGET)/$rot
  731: END
  732:                 }
  733: 	    }
  734: 	}
  735:     }
  736:     $description.=<<END;
  737: 
  738: END
  739:     return $description;
  740: }
  741: 
  742: # ------ Commands to enforce configuration file permissions
  743: sub make_files_configpermissions_segment {
  744:     my ($dirs)=@_;
  745:     my $description=<<END;
  746: configpermissions:
  747: END
  748:     my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
  749:     foreach my $d (@$dirs) {
  750: 	# set other values
  751: 	my $dirdescription=$info{'DIRECTORY'}{$distribution}{$d}{'DESCRIPTION'};
  752: 	$dirdescription="(" . $dirdescription . ")" if $dirdescription;
  753: 	# find files that are contained in this directory
  754: 	my @files;
  755: 	my @filesfull;
  756: 	foreach my $f (@allfiles) {
  757: 	    if ($f=~/^$d\/([^\/]+)$/) {
  758: 		push @files,$1;
  759: 		push @filesfull,$f;
  760: 	    }
  761: 	}
  762: 	# render starting HTML formatting elements
  763: 	if (@files) {
  764: 	    $description.=<<END;
  765: \t# $d $dirdescription
  766: END
  767:         }
  768: 	if (@files) {
  769:             foreach my $i (0..$#files) {
  770: 		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
  771: 		my $source=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'};
  772: 		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
  773: 		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
  774: 		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
  775: 		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
  776: 		my $rot=$filesfull[$i];
  777: 		$rot=~s/[^\/]+$/\./ if $rot=~/\*/;
  778: 		my ($owner,$group)=split(/\:/,$devchown);
  779: 		if ($category eq 'conf') {
  780: 		    $description.=<<END;
  781: \tchmod $devchmod \$(TARGET)/$rot
  782: \tchown $devchown \$(TARGET)/$rot
  783: END
  784:                 }
  785: 	    }
  786: 	}
  787:     }
  788:     $description.=<<END;
  789: 
  790: END
  791:     return $description;
  792: }
  793: 
  794: # ------------------------------ Installation commands to install symbolic links
  795: sub make_links_install_segment {
  796:     my ($dirs)=@_;
  797:     my $description=<<END;
  798: links:
  799: END
  800:     chop $description;
  801:     my $description2;
  802:     my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
  803:     foreach my $d (@$dirs) {
  804: 	# find files that are contained in this directory
  805: 	my @files;
  806: 	my @filesfull;
  807: 	foreach my $f (@allfiles) {
  808: 	    if ($f=~/^$d\/([^\/]+)$/) {
  809: 		push @files,$1;
  810: 		push @filesfull,$f;
  811: 	    }
  812: 	}
  813: 	# render starting HTML formatting elements
  814: 	if (@files) {
  815:             foreach my $i (0..$#files) {
  816: 		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
  817: 		my $linkto=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'LINKTO'};
  818: 		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
  819: 		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
  820: 		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
  821: 		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
  822: 		if ($category eq 'symbolic link') {
  823: 		    $description.=" \$(TARGET)/$filesfull[$i]";
  824: 		    $description2.=<<END;
  825: \$(TARGET)/$filesfull[$i]:
  826: \tln -s /$linkto \$(TARGET)/$filesfull[$i]
  827: 
  828: END
  829:                 }
  830: 	    }
  831: 	}
  832:     }
  833:     $description.=<<END;
  834: 
  835: END
  836:     $description.=$description2;
  837:     return $description;
  838: }
  839: 
  840: # --------------------------------------------------------- Make RPM .spec block
  841: sub make_rpm_spec_block {
  842:     my $pwd=`pwd`; chop $pwd;
  843:     my $buildroot="$pwd/LON-CAPA-BuildRoot";
  844:     my $source=$info{'RPM'}{'Name'} . "-" . $info{'RPM'}{'Version'} . '.tar.gz';
  845:     my $description=<<END;
  846: Summary: $info{'RPM'}{'Summary'}
  847: Name: $info{'RPM'}{'Name'}
  848: Version: $info{'RPM'}{'Version'}
  849: Release: $info{'RPM'}{'Release'}
  850: Vendor: $info{'RPM'}{'Vendor'} 
  851: BuildRoot: $buildroot
  852: Copyright: $info{'RPM'}{'Copyright'}
  853: Group: $info{'RPM'}{'Group'}
  854: Source: $source
  855: AutoReqProv: $info{'RPM'}{'AutoReqProv'}
  856: \%description
  857: $info{'RPM'}{'description'}
  858: 
  859: END
  860:     return $description;
  861: }
  862: 
  863: # --------------------------------------------------- Make RPM build .spec block
  864: sub make_rpm_build_block {
  865:     my $pwd=`pwd`; chop $pwd;
  866:     my $buildroot="$pwd/LON-CAPA-BuildRoot";
  867:     my $sourceroot="$pwd/LON-CAPA-SourceRoot";
  868:     my $description=<<END;
  869: 
  870: \%prep
  871: \%setup
  872: 
  873: \%build
  874: rm -Rf "$buildroot"
  875: 
  876: \%install
  877: make -f LCMakefile ROOT="\$RPM_BUILD_ROOT" SOURCE="$sourceroot" directories
  878: make -f LCMakefile ROOT="\$RPM_BUILD_ROOT" SOURCE="$sourceroot" files
  879: make -f LCMakefile ROOT="\$RPM_BUILD_ROOT" SOURCE="$sourceroot" links
  880: 
  881: \%pre
  882: $info{'RPM'}{'pre'}
  883: 
  884: \%post
  885: \%postun
  886: 
  887: \%files
  888: # \%doc README COPYING ChangeLog LICENSE
  889: END
  890:     return $description;
  891: }
  892: 
  893: # ------------------------------------- Make directory structure RPM .spec block
  894: sub make_directory_structure_spec_block {
  895:     my ($dirs)=@_;
  896:     foreach my $d (@$dirs) {
  897: 	my $category=$info{'DIRECTORY'}{$distribution}{$d}{'CATEGORY'};
  898: 	my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
  899: 	my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
  900: 	my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
  901: 	my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
  902: 	my $own=$devchown; $own=~s/\:/\,/;
  903: 	$description.=<<END;
  904: \%dir \%attr($devchmod,$own) /$d
  905: END
  906:     }
  907:     return $description;
  908: }
  909: 
  910: # ---------------------------- Make directory and file structure RPM .spec block
  911: sub make_directory_and_file_structure_spec_block {
  912:     my ($dirs)=@_;
  913:     my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
  914:     foreach my $d (@$dirs) {
  915: 	# set other values
  916: 	my $dirdescription=$info{'DIRECTORY'}{$distribution}{$d}{'DESCRIPTION'};
  917: 	$dirdescription="(" . $dirdescription . ")" if $dirdescription;
  918: 	# find files that are contained in this directory
  919: 	my @files;
  920: 	my @filesfull;
  921: 	foreach my $f (@allfiles) {
  922: 	    if ($f=~/^$d\/([^\/]+)$/) {
  923: 		push @files,$1;
  924: 		push @filesfull,$f;
  925: 	    }
  926: 	}
  927: 	# render starting HTML formatting elements
  928: 	if (@files) {
  929: 	    $description.=<<END;
  930: # $d $dirdescription
  931: END
  932:         }
  933: 	if (@files) {
  934:             foreach my $i (0..$#files) {
  935: 		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
  936: 		my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
  937: 		my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
  938: 		my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
  939: 		my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
  940: 		my $own=$devchown; $own=~s/\:/\,/;
  941: 		my $config="";
  942: 		$config="\%config " if $category eq 'conf';
  943: 		$devchmod='-' if $category eq 'symbolic link';
  944: 		$description.=<<END;
  945: $config\%attr($devchmod,$own) /$filesfull[$i]
  946: END
  947: 	    }
  948: 	}
  949:     }
  950:     return $description;
  951: }
  952: 
  953: # ----------------------------------------------------------- End RPM .spec page
  954: sub end_spec_page {
  955: }
  956: 
  957: # ------------------------------------------------------- Begin description page
  958: sub begin_description_page {
  959:     my ($mode)=@_;
  960:     my $description;
  961:     unless ($mode eq 'status') {
  962:     $description=<<END;
  963: <HTML>
  964: <HEAD>
  965: <TITLE>LON-CAPA Software Description Page ($distribution, $date)</TITLE>
  966: </HEAD>
  967: <BODY>
  968: <FONT SIZE=+2>LON-CAPA Software Description Page ($distribution, $date)</FONT>
  969: <BR>Michigan State University
  970: <BR>Learning Online with CAPA
  971: <BR>Contact korte\@lon-capa.org
  972: <UL>
  973: <LI>About this file
  974: <LI>Software Package Description
  975: <LI>Directory Structure
  976: <LI>File Type Ownership and Permissions
  977: <LI>File and Directory Structure
  978: </UL>
  979: <FONT SIZE=+2>About this file</FONT>
  980: <P>
  981: This file is generated dynamically by <TT>parse.pl</TT> as
  982: part of a development compilation process.  See 
  983: http://install.lon-capa.org/compile/index.html for more
  984: information.
  985: </P>
  986: END
  987: }
  988:     else {
  989: 	$description=<<END;
  990: <HTML>
  991: <HEAD>
  992: <TITLE>LON-CAPA Software File System Status Page ($distribution, $date)</TITLE>
  993: </HEAD>
  994: <BODY>
  995: <FONT SIZE=+2>LON-CAPA Software File System Status Page ($distribution, $date)</FONT>
  996: <BR>Michigan State University
  997: <BR>Learning Online with CAPA
  998: <BR>Contact korte\@lon-capa.org
  999: <UL>
 1000: <LI>About this file
 1001: <LI>Software Package Description
 1002: <LI>Directory Structure
 1003: <LI>File Type Ownership and Permissions
 1004: <LI>File and Directory Structure
 1005: </UL>
 1006: <FONT SIZE=+2>About this file</FONT>
 1007: <P>
 1008: This file is generated dynamically by <TT>parse.pl</TT> as
 1009: part of a status checking process.  See http://install.lon-capa.org/
 1010: for more information.
 1011: </P>
 1012: END
 1013:     }
 1014:     return $description;
 1015: 
 1016: }
 1017: 
 1018: # ------------------------------------------------- End description page
 1019: sub end_description_page {
 1020:     my $description=<<END;
 1021: <HR>
 1022: <FONT SIZE=-1>LON-CAPA Software Development Team</FONT>
 1023: </BODY>
 1024: </HTML>
 1025: END
 1026:     return $description;
 1027: }
 1028: 
 1029: # ------------------------------------------------- Make RPM description block
 1030: sub make_rpm_description_block {
 1031:     my ($mode)=@_;
 1032:     my $description;
 1033:     unless ($mode eq 'status') {
 1034:     $description=<<END;
 1035: <FONT SIZE=+2>Rolled in a RedHat 6.2 RPM, $date</FONT>
 1036: <P>
 1037: <TABLE BGCOLOR=#FFFFFF BORDER=0 CELLPADDING=10 CELLSPACING=0>
 1038: <TR><TD>
 1039: <PRE>
 1040: Name        : $info{'RPM'}{'Name'}
 1041: Version     : $info{'RPM'}{'Version'}
 1042: Vendor      : $info{'RPM'}{'Vendor'} 
 1043: Release     : $info{'RPM'}{'Release'}                             
 1044: Build Host  : $buildhost
 1045: Group       : $info{'RPM'}{'Group'}
 1046: License     : $info{'RPM'}{'Copyright'}
 1047: Summary     : $info{'RPM'}{'Summary'}
 1048: Description : 
 1049: $info{'RPM'}{'description'}
 1050: </PRE>
 1051: </TD></TR>
 1052: </TABLE>
 1053: </P>
 1054: END
 1055: }
 1056:     else {
 1057: 	my $exist=`rpm -q LON-CAPA-base 2>/dev/null`;
 1058: 	unless ($exist) {
 1059: 	    $description=<<END;
 1060: <FONT SIZE=+2>No LON-CAPA RPM on the system, (installed ??????)</FONT>
 1061: <P>
 1062: <TABLE BGCOLOR=#FFFFFF BORDER=0 CELLPADDING=10 CELLSPACING=0>
 1063: <TR><TD>
 1064: <FONT SIZE=+3>Error! A LON-CAPA-base RPM
 1065: was never installed on this system!</FONT>
 1066: </TD></TR>
 1067: </TD></TR>
 1068: </TABLE>
 1069: </P>
 1070: END
 1071: 	}
 1072: 	else {
 1073: 	    chop $exist;
 1074: 	    my $rpmname=`rpm -q --queryformat '%{NAME}' LON-CAPA-base`;
 1075: 	    my $rpmversion=`rpm -q --queryformat '%{VERSION}' LON-CAPA-base`;
 1076: 	    my $rpmrelease=`rpm -q --queryformat '%{RELEASE}' LON-CAPA-base`;
 1077: 	    my $idate=`rpm -q --queryformat '%{INSTALLTIME:date}' LON-CAPA-base`;
 1078: 	    my $rpmvendor=`rpm -q --queryformat '%{VENDOR}' LON-CAPA-base`;
 1079: 	    my $rpmbuildhost=`rpm -q --queryformat '%{BUILDHOST}' LON-CAPA-base`;
 1080: 	    my $rpmgroup=`rpm -q --queryformat '%{GROUP}' LON-CAPA-base`;
 1081: 	    my $rpmlicense=`rpm -q --queryformat '%{LICENSE}' LON-CAPA-base`;
 1082: 	    my $rpmsummary=`rpm -q --queryformat '%{SUMMARY}' LON-CAPA-base`;
 1083: 	    my $rpmdescription=`rpm -q --queryformat '%{DESCRIPTION}' LON-CAPA-base`;
 1084: 	    $description=<<END;
 1085: <FONT SIZE=+2>Current RedHat RPM on the system, (installed $idate)</FONT>
 1086: <P>
 1087: <TABLE BGCOLOR=#FFFFFF BORDER=0 CELLPADDING=10 CELLSPACING=0>
 1088: <TR><TD>
 1089: <PRE>
 1090: Name        : $rpmname
 1091: Version     : $rpmversion
 1092: Vendor      : $rpmvendor
 1093: Release     : $rpmrelease
 1094: Build Host  : $rpmbuildhost
 1095: Group       : $rpmgroup
 1096: License     : $rpmlicense
 1097: Summary     : $rpmsummary
 1098: Description : 
 1099: $rpmdescription
 1100: </PRE>
 1101: </TD></TR>
 1102: </TABLE>
 1103: </P>
 1104: END
 1105: }
 1106:     }
 1107:     return $description;
 1108: }
 1109: 
 1110: # ----------------------------------------------- Determine directory structure
 1111: sub determine_directory_structure {
 1112:     my @directories=keys %{$info{'DIRECTORY'}{$distribution}};
 1113:     return (sort @directories);
 1114: }
 1115: 
 1116: 
 1117: # ---------------------------------- Make directory structure description block
 1118: sub make_directory_structure_description_block {
 1119:     my ($dirs,$mode)=@_;
 1120:     my $dirstatus; my $statusheader;
 1121:     my $description=<<END;
 1122: <FONT SIZE=+2>Directory Structure Description, $date</FONT>
 1123: <P>
 1124: The directory structure description below shows only those
 1125: directories which either contain LON-CAPA specific files
 1126: or normally do not exist on a RedHat Linux system (and
 1127: must be generated to allow proper placement of files
 1128: during LON-CAPA run-time operation).
 1129: </P>
 1130: <P>
 1131: <TABLE BORDER=1 CELLPADDING=3 CELLSPACING=0>
 1132: END
 1133:     my $maxcount=0;
 1134:     my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
 1135:     my %diraccount; # hash to track which directories are accounted for
 1136:     foreach my $file (@allfiles) {
 1137: 	$file=~/^(.*)\/([^\/]+)$/;
 1138: 	$diraccount{$1}=1;
 1139:     }
 1140:     foreach my $d (@$dirs) {
 1141:         my (@matches)=($d=~/\//g);
 1142: 	my $count=scalar(@matches);
 1143: 	$maxcount=$count if $count>$maxcount;
 1144: 	delete $diraccount{$d};
 1145:     }
 1146:     if ($mode eq 'status') {
 1147: 	$statusheader="<TH ALIGN=LEFT BGCOLOR=#FFFFFF>Current Status</TH>";
 1148:     }
 1149:     $description.=<<END;
 1150: <TR>
 1151: $statusheader
 1152: <TH ALIGN=LEFT BGCOLOR=#FFFFFF>Category</TH>
 1153: <TH ALIGN=LEFT BGCOLOR=#FFFFFF>Permissions</TH>
 1154: <TH ALIGN=LEFT BGCOLOR=#FFFFFF><FONT COLOR=#FF0000>Development<BR>Permissions</FONT></TH>
 1155: END
 1156:     $description.="<TH ALIGN=LEFT BGCOLOR=#FFFFFF COLSPAN=".($maxcount+1).">Directory Path</TH>\n";
 1157:     if (keys %diraccount) {
 1158: 	$description.= "<TR><TD ALIGN=LEFT BGCOLOR=#FFFFFF COLSPAN=".($maxcount+4)."><I><PRE>Directories that are unaccounted for: \n";
 1159: 	foreach my $d (keys %diraccount) {
 1160: 	    $description.="$d\n";
 1161: 	}
 1162: 	$description.="</PRE></I></TH></TR>\n";
 1163:     }
 1164:     foreach my $d (@$dirs) {
 1165: 	my $dtable=$d;
 1166: 	$dtable=~s/\//\<\/TD\>\<TD\>/g;
 1167: 	my $category=$info{'DIRECTORY'}{$distribution}{$d}{'CATEGORY'};
 1168: 	my $chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
 1169: 	my $chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
 1170: 	my $devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
 1171: 	my $devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
 1172: 	if ($mode eq 'status') {
 1173: 	    my $ds=`find /$d -type d -prune -printf "\%m\t\%u\t\%g" 2>/dev/null`;
 1174: 	    unless ($ds) {
 1175: 		$dirstatus='<TD BGCOLOR=#FFFFFF><B><U>MISSING</U></B></TD>';
 1176: 	    }
 1177: 	    else {
 1178: 		my @dss=split(/\t/,$ds);
 1179: 		my $dssz=$dss[0];
 1180: 		$dssz="0" . $dss[0] if length($dss[0])<4;
 1181: 		$dss[0]=$dssz;
 1182: 		$ds="$dss[0] $dss[1]:$dss[2]";
 1183: 		if ($ds eq "$chmod $chown" && $ds eq "$devchmod $devchown") {
 1184: 		    $dirstatus='<TD BGCOLOR=#FFFFFF>runtime+development</TD>';
 1185: 		}
 1186: 		elsif ($ds eq "$chmod $chown") {
 1187: 		    $dirstatus='<TD BGCOLOR=#FFFFFF>runtime</TD>';
 1188: 		}
 1189: 		elsif ($ds eq "$devchmod $devchown") {
 1190: 		    $dirstatus='<TD BGCOLOR=#FFFFFF>development</TD>';
 1191: 		}
 1192: 		else {
 1193: 		    $dirstatus="<TD BGCOLOR=#FFFFFF><B><U>ERROR</U></B><BR>$ds</TD>";
 1194: 		}
 1195: 	    }
 1196: 	}
 1197: 	$description.=<<END;
 1198: <TR>
 1199: $dirstatus
 1200: <TD BGCOLOR=#FFFFFF>$category</TD>
 1201: <TD BGCOLOR=#FFFFFF><TT>$chmod $chown</TT></TD>
 1202: <TD BGCOLOR=#FFFFFF><FONT COLOR=#FF0000><TT>$devchmod $devchown</TT></FONT></TD>
 1203: <TD>
 1204: $dtable
 1205: </TD>
 1206: </TR>
 1207: END
 1208:     }
 1209:     $description.=<<END;
 1210: </TABLE>
 1211: </P>
 1212: END
 1213:     return $description;
 1214: }
 1215: 
 1216: # ------------------- Make file type ownership and permissions description block
 1217: sub make_file_type_ownership_and_permissions_description_block {
 1218:     my ($mode)=@_;
 1219:     my $description=<<END;
 1220: <FONT SIZE=+2>File Type Ownership and Permissions Descriptions, $date</FONT>
 1221: <P>
 1222: This table shows what permissions and ownership settings correspond
 1223: to each kind of file type.
 1224: </P>
 1225: <P>
 1226: <TABLE BORDER=1 CELLPADDING=5 WIDTH=60%>
 1227: <TR>
 1228: <TH ALIGN=LEFT BGCOLOR=#FFFFFF>Icon</TH>
 1229: <TH ALIGN=LEFT BGCOLOR=#FFFFFF>Type</TH>
 1230: <TH ALIGN=LEFT BGCOLOR=#FFFFFF>Permissions</TH>
 1231: <TH ALIGN=LEFT BGCOLOR=#FFFFFF>Development Permissions</TH>
 1232: </TR>
 1233: END
 1234:     foreach my $type (keys %{$info{'OWNERSHIP'}}) {
 1235: 	if (defined($fcm{$type})) {
 1236: 	    my $chmod=$info{'OWNERSHIP'}{$type}{'CHMOD'};
 1237: 	    my $chown=$info{'OWNERSHIP'}{$type}{'CHOWN'};
 1238: 	    my $devchmod=$info{'DEVOWNERSHIP'}{$type}{'CHMOD'};
 1239: 	    my $devchown=$info{'DEVOWNERSHIP'}{$type}{'CHOWN'};
 1240: 	    $description.=<<END;
 1241: <TR>
 1242: <TD><IMG SRC="$fcm{$type}.gif" ALT="$type"></TD>
 1243: <TD>$type</TD>
 1244: <TD><TT>$chmod $chown</TT></TD>
 1245: <TD><TT>$devchmod $devchown</TT></TD>
 1246: </TR>
 1247: END
 1248:         }
 1249:     }
 1250:     $description.=<<END;
 1251: </TABLE>
 1252: </P>
 1253: END
 1254: }
 1255: 
 1256: # ------------------------- Make directory and file structure description block
 1257: sub make_directory_and_file_structure_description_block {
 1258:     my ($dirs,$mode)=@_;
 1259:     my $statusheader; my $filestatus;
 1260:     my $description=<<END;
 1261: <FONT SIZE=+2>Directory and File Structure Description, $date</FONT>
 1262: <P>
 1263: The icons on the left column correspond to the file type
 1264: specified in the second column.  The last column "Notes" shows compilation,
 1265: dependency, and configuration information.  The CVS location
 1266: shows the location of the binary source file (if applicable) needed to
 1267: be copied to the target.  If the binary source file is not at
 1268: the specified location, then the text is shown in 
 1269: <FONT COLOR=#FF0000>red</FONT>.
 1270: </P>
 1271: <P>
 1272: <TABLE BORDER=1 CELLPADDING=5 WIDTH=500>
 1273: END
 1274:     my $counter=0;
 1275:     my @colorindex=("#80FF80","#80FFFF","#FFFF80");
 1276:     my @allfiles=keys %{$info{'LOCATION'}{$distribution}};
 1277:     foreach my $d (@$dirs) {
 1278: 	# set color
 1279: 	my $color=$colorindex[$counter%3];
 1280: 	# set other values
 1281: 	my $dirdescription=$info{'DIRECTORY'}{$distribution}{$d}{'DESCRIPTION'};
 1282: 	$dirdescription="(" . $dirdescription . ")" if $dirdescription;
 1283: 	# find subdirectories that are contained in this directory
 1284: 	my @subdirs;
 1285: 	foreach my $d2 (@$dirs) {
 1286: 	    if ($d2=~/^$d\/([^\/]+)$/) {
 1287: 		push @subdirs,$1;
 1288: 	    }
 1289: 	}
 1290: 	# find files that are contained in this directory
 1291: 	my @files;
 1292: 	my @filesfull;
 1293: 	foreach my $f (@allfiles) {
 1294: 	    if ($f=~/^$d\/([^\/]+)$/) {
 1295: 		push @files,$1;
 1296: 		push @filesfull,$f;
 1297: 	    }
 1298: 	}
 1299: 	# render starting HTML formatting elements
 1300: 	if (@subdirs || @files) {
 1301: 	    my $subdirstring="<BR>* Relevant subdirectories: " . join(", ",@subdirs) if @subdirs;
 1302: 	    $description.=<<END;
 1303: <TR><TD BGCOLOR=#000000 COLSPAN=6><FONT COLOR=$color><IMG SRC="directory.gif" ALT="directory">DIRECTORY -- $d $dirdescription
 1304: $subdirstring</FONT></TD></TR>
 1305: END
 1306:         }
 1307: 	else {
 1308: 	    $description.=<<END;
 1309: <TR><TD BGCOLOR=#000000 COLSPAN=6><FONT COLOR=$color><IMG SRC="emptydirectory.gif" ALT="empty directory">EMPTY DIRECTORY - $d $dirdescription</FONT></TD></TR>
 1310: END
 1311:         }
 1312: 	if (@files) {
 1313: 	    if ($mode eq 'status') {
 1314: 		$statusheader=<<END;
 1315: <TH BGCOLOR=$color ALIGN=LEFT>Current Status</TH>
 1316: END
 1317: 	    }
 1318: 	    $description.=<<END;
 1319: <TR>
 1320: $statusheader
 1321: <TH BGCOLOR=$color ALIGN=LEFT COLSPAN=2>Type</TH>
 1322: <TH BGCOLOR=$color ALIGN=LEFT>File Name</TH>
 1323: <TH BGCOLOR=$color ALIGN=LEFT>Function</TH>
 1324: <TH BGCOLOR=$color ALIGN=LEFT>CVS Location</TH>
 1325: <TH BGCOLOR=$color ALIGN=LEFT>Notes</TH>
 1326: </TR>
 1327: END
 1328:             foreach my $i (0..$#files) {
 1329: 		my $category=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'CATEGORY'};
 1330: 		my $fdescription=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'DESCRIPTION'};
 1331: 		my $source=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'};
 1332: 		my $source2=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'SOURCE'};
 1333: 		my $note=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'NOTE'};
 1334: 		$note.="<BR>" if $note;
 1335: 		my $listing=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'FILES'};
 1336: 		my @E=split(/\s+/,$listing);
 1337: 		$source=~/(.*)\/[^\/]+$/;
 1338: 		my $sd=$1;
 1339: 		my $eflag=0;
 1340: 		foreach my $e (@E) {
 1341: 		    unless (-e "../../$sd/$e") {
 1342: 			$e="<FONT COLOR=#FF0000>$e</FONT>";
 1343: 			$eflag=1;
 1344: 		    }
 1345: 		}
 1346: 		$listing=join("\n",@E);
 1347: 		$listing="<B>listing</B><BR><FONT SIZE=-2>$listing</FONT>" if $listing;
 1348: 		$listing.="<BR>" if $listing;
 1349: 		my $build=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'BUILD'};
 1350: 		$build="<B>build</B><BR>$build" if $build;
 1351: 		$build.="<BR>" if $build;
 1352: 		my $dependencies=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'DEPENDENCIES'};
 1353: 		$dependencies="<B>dependencies</B><BR>$dependencies" if $dependencies;
 1354: 		$dependencies.="<BR>" if $dependencies;
 1355: 		unless (-e "../../$source") {
 1356: 		    $source=~/([^\/]+)$/;
 1357: 		    my $s=$1;
 1358: 		    if ($source!~/\*/) {
 1359: 			$source="<FONT COLOR=#FF0000>$source</FONT>";
 1360: 		    }
 1361: 		    elsif ($eflag) {
 1362: 			$source="<FONT COLOR=#FF0000>$source</FONT>";
 1363: 		    }
 1364: 		}
 1365: 		my $checksum;
 1366: 		my $checksum_source;
 1367: 		my $checksum_target;
 1368: 		if ($mode eq 'status') {
 1369: 		    $filestatus='';
 1370: 		    my $fs;
 1371: 		    my $listing2=$info{'LOCATION'}{$distribution}{$filesfull[$i]}{'FILES'};
 1372: 		    my @E=split(/\s+/,$listing2); shift @E;
 1373: 		    if (@E) {
 1374: 			$fs=`find /$filesfull[$i] -prune -printf "\%m\t\%u\t\%g\n" 2>/dev/null | wc -l`; chop $fs;
 1375: 			if ($fs!=(@E+0)) {
 1376: 			    $ecount=(@E+0);
 1377: 			    $estuff=join(",",@E);
 1378: 			    $filestatus="<TD BGCOLOR=#FFFFFF><B><U>ERROR. SOME FILES ARE MISSING</U></B></TD>";
 1379: 			}
 1380: 			$fs=`find /$filesfull[$i] -prune -printf "\%m\t\%u\t\%g\n" 2>/dev/null | sort | uniq | wc -l`; chop $fs;
 1381: 			if ($fs!=1) {
 1382: 			    $filestatus='<TD BGCOLOR=#FFFFFF><B><U>ERROR. THERE ARE MULTIPLE OWNERSHIPS/PERMISSIONS WHEN ALL THESE FILES SHOULD HAVE THE SAME CONFIGURATION</U></B></TD>';
 1383: 			}
 1384: 			else {
 1385: 			    $fs=`find /$filesfull[$i] -prune -printf "\%m\t\%u\t\%g\n" 2>/dev/null | sort | uniq`; chop $fs;
 1386: 			}
 1387: 		    }
 1388: 		    else {
 1389: 			$fs=`find /$filesfull[$i] -prune -printf "\%m\t\%u\t\%g" 2>/dev/null`;
 1390: 			if (-f "/$filesfull[$i]" && !(-l "/$filesfull[$i]")) {
 1391: 			    $checksum_source=`md5sum ../../$source2 | cut -d ' ' -f1`;
 1392: 			    chop $checksum_source;
 1393: 			    $checksum_target=`md5sum /$filesfull[$i] | cut -d ' ' -f1`;
 1394: 			    chop $checksum_target;
 1395: 			    warn ("CS: $checksum_source, CT: $checksum_target\n");
 1396: 			    unless ($checksum_source eq $checksum_target) {
 1397: 				$checksum="<BR><B><U>CHECKSUM DIFFERENCE</U></B>";
 1398: 			    }
 1399: 			}
 1400: 		    }
 1401: 		    my $fsl=`find /$filesfull[$i] -type l -prune -printf "\%m\t\%u\t\%g" 2>/dev/null`;
 1402: 		    unless ($fs || $filestatus) {
 1403: 			$filestatus='<TD BGCOLOR=#FFFFFF><B><U>MISSING</U></B></TD>';
 1404: 		    }
 1405: 		    elsif (!$filestatus) {
 1406: 
 1407: 			$chmod=$info{'OWNERSHIP'}{$category}{'CHMOD'};
 1408: 			$chown=$info{'OWNERSHIP'}{$category}{'CHOWN'};
 1409: 			$devchmod=$info{'DEVOWNERSHIP'}{$category}{'CHMOD'};
 1410: 			$devchown=$info{'DEVOWNERSHIP'}{$category}{'CHOWN'};
 1411: 
 1412: 			my @fss=split(/\t/,$fs);
 1413: 			my $fssz=$fss[0];
 1414: 			$fssz="0" . $fss[0] if length($fss[0])<4;
 1415: 			$fss[0]=$fssz;
 1416: 			$fs="$fss[0] $fss[1]:$fss[2]";
 1417: 			$s=' ';
 1418: 			if ($fsl) {
 1419: 			    $fs="$fss[1]:$fss[2]";
 1420: 			    $s='';
 1421: 			}
 1422: 			if ($fs eq "$chmod$s$chown" && $fs eq "$devchmod$s$devchown") {
 1423: 			    $filestatus="<TD BGCOLOR=#FFFFFF>runtime+development$checksum</TD>";
 1424: 			}
 1425: 			elsif ($fs eq "$chmod$s$chown") {
 1426: 			    $filestatus="<TD BGCOLOR=#FFFFFF>runtime$checksum</TD>";
 1427: 			}
 1428: 			elsif ($fs eq "$devchmod$s$devchown") {
 1429: 			    $filestatus="<TD BGCOLOR=#FFFFFF>development$checksum</TD>";
 1430: 			}
 1431: 			else {
 1432: 			    $filestatus="<TD BGCOLOR=#FFFFFF><B><U>ERROR</U></B><BR>$fs</TD>";
 1433: 			}
 1434: 		    }
 1435: 		}	    
 1436: 		$description.=<<END;
 1437: <TR>
 1438: $filestatus
 1439: <TD BGCOLOR=#A0A0A0><IMG SRC="$fcm{$category}.gif" ALT="$category"></TD>
 1440: <TD BGCOLOR=$color>$category</TD>
 1441: <TD BGCOLOR=$color>$files[$i]</TD>
 1442: <TD BGCOLOR=$color>$fdescription&nbsp;</TD>
 1443: <TD BGCOLOR=$color>$source</TD>
 1444: <TD BGCOLOR=$color>$note$listing$build$dependencies&nbsp;</TD>
 1445: </TR>
 1446: END
 1447: 	    }
 1448: 	}
 1449: 	$counter++;
 1450:     }
 1451:     $description.=<<END;
 1452: </TABLE>
 1453: </P>
 1454: END
 1455:     return $description;
 1456: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>