windows-nt/Source/XPSP1/NT/tools/makelist.pl
2020-09-26 16:20:57 +08:00

965 lines
22 KiB
Perl

#++
# Barbara Kess
# Copyright (c) 1998 Microsoft Corporation
#
# Module Name:
# makelist.pl
#
# Abstract:
#
#
#--
#
# Set global vars
#
#Flush output buffer for remote.exe
select(STDOUT); $|=1;
# Get the parameters
%Params = &GetArguments(@ARGV);
if ( exists $Params{"i"} ) {
@list = &IntersectLists( %Params );
}
elsif ( exists $Params{"u"} ) {
@list = &UnionLists( %Params );
}
elsif ( exists $Params{"d"} ) {
@list = &DiffLists( %Params );
}
elsif ( exists $Params{"c"} ) {
@list = &CreateListFromDirectory( %Params );
}
elsif ( exists $Params{"n"} ) {
@list = &DosnetToList(%Params);
}
elsif ( exists $Params{"m"} ) {
@list = &FileToList( %Params );
}
elsif ( exists $Params{"a"} ) {
@list = &SourceDestDiff( %Params );
}
elsif ( exists $Params{"q"} ) {
@list = &ExDosnetToList( %Params );
}
elsif ( exists $Params{"b"} ) {
@list = &MediaToList( %Params );
}
elsif ( exists $Params{"r"} ) {
@list = &DrvindexToList( %Params );
}
if ( exists $Params{"h"} ) {
@header=&GetHeader( @{$Params{"h"}}[0] );
&PrintListWithHeader(\@header,\@list, @{$Params{"o"}}[0]);
}
else {
&PrintList(\@list, @{$Params{"o"}}[0]);
}
sub IntersectLists
{
my ( %params ) = @_;
my (@file_list, @file_l, @list, %MARK);
$first = 1;
foreach $file ( @{$params{"i"}} ) {
#open file put it into an array
unless ( open( FHANDLE, $file)) {
&LogMsg('err',"Unable to open $file");
}
if ($first == 1) {
@file_list = <FHANDLE>;
close (FHANDLE);
$i=0;
foreach $item (@file_list) {
chop $file_list[$i];
$i++;
}
$first = 0;
}
else {
@list = <FHANDLE>;
close (HANDLE);
$i=0;
foreach $item (@list) {
chop $list[$i];
$i++;
}
foreach $item (@file_list) {
$MARK{lc $item} = 1;
}
foreach $item (@list) {
if ( $MARK{lc $item} == 1) {
$MARK{lc $item} = 2;
}
}
foreach $item (keys %MARK) {
if ( $MARK{$item} == 2 ) {
push @file_l, $item;
}
}
}
}
return (@file_l);
}
sub UnionLists
{
my ( %params ) = @_;
my (@file_list, @file_l, @list, %MARK);
$first = 1;
foreach $file ( @{$params{"u"}} ) {
#open file put it into an array
unless ( open( FHANDLE, $file)) {
&LogMsg('err',"Unable to open $file");
}
if ($first == 1) {
@file_list = <FHANDLE>;
close (FHANDLE);
$first = 0;
$i=0;
foreach $item (@file_list) {
chop $file_list[$i];
$i++;
}
}
else {
@list = <FHANDLE>;
close (FHANDLE);
$i=0;
foreach $item (@list) {
chop $list[$i];
$i++;
}
foreach $item (@file_list) {
$MARK{lc $item} = 1;
}
foreach $item (@list) {
$MARK{lc $item} = 1;
}
foreach $item (keys %MARK) {
if ( $MARK{$item} == 1 ) {
push @file_l, $item;
}
}
}
}
return (@file_l);
}
sub DiffLists
{
my ( %params ) = @_;
my (@file_list, @file_l, @list, %MARK);
$first = 1;
foreach $file ( @{$params{"d"}} ) {
#open file put it into an array
unless ( open( FHANDLE, $file)) {
&LogMsg('err',"Unable to open $file");
}
if ($first == 1) {
@file_list = <FHANDLE>;
close (FHANDLE);
$first = 0;
$i=0;
foreach $item (@file_list) {
chop $file_list[$i];
$i++;
}
}
else {
@list = <FHANDLE>;
close (FHANDLE);
$i=0;
foreach $item (@list) {
chop $list[$i];
$i++;
}
foreach $item (@file_list) {
$MARK{lc $item}=1;
}
foreach $item (@list) {
$MARK{lc $item}=0;
}
foreach $item (keys %MARK) {
if ($MARK{$item} == 1) {
push @file_l, $item;
}
}
}
}
return (@file_l);
}
sub CreateListFromDirectory
{
my ( %params ) = @_;
my (@dir_list, @dir_l,$dir, %MARK);
$dir = @{$Params{"c"}}[0];
unless ( opendir(DIRECTORY, $dir) ) {
print "ERROR: Cannot open $dir\n";
}
@dir_list = readdir(DIRECTORY);
closedir(DIRECTORY);
$i=0;
foreach $item (@dir_list) {
chop $file_list[$i];
$i++;
}
foreach $item (@dir_list) {
# if this file is not a directory, put it in the list
unless (opendir (DIRECTORY, "$dir\\$item") ) {
$MARK{lc $item}++;
}
closedir(DIRECTORY);
}
@dir_l = grep($MARK{lc $_},@dir_list);
return(@dir_l);
}
sub DosnetToList
{
# $dosnet is the name of the dosnet file
# $path is a flag telling whether or not to include path
# information in the output file
# (i.e., filename=d:\binaries\filename)
# @search_paths tells where to search
# $check is a flag. If it is 1, then check the search paths,
# otherwise use the current directory as the path
my ( %params ) = @_;
$dosnet = @{$params{"n"}}[0];
my (@d_list);
@d_list = &MakeListFromDosnet($dosnet);
return (@d_list);
}
sub MediaToList
{
# $media is the name of the _media file
# $path is a flag telling whether or not to include path
# information in the output file
# (i.e., filename=d:\binaries\filename)
# @search_paths tells where to search
# $check is a flag. If it is 1, then check the search paths,
# otherwise use the current directory as the path
my ( %params ) = @_;
$media = @{$params{"b"}}[0];
my (@d_list);
@d_list = &MakeListFromMedia($media);
return (@d_list);
}
sub ExDosnetToList
{
# $exdosnet is the name of the dosnet file
# $path is a flag telling whether or not to include path
# information in the output file
# (i.e., filename=d:\binaries\filename)
# @search_paths tells where to search
# $check is a flag. If it is 1, then check the search paths,
# otherwise use the current directory as the path
my ( %params ) = @_;
$exdosnet = @{$params{"q"}}[0];
my (@d_list);
@d_list = &MakeListFromExDosnet($exdosnet);
return (@d_list);
}
sub DrvindexToList
{
# $drvindex is the name of the drvindex file
# $path is a flag telling whether or not to include path
# information in the output file
# (i.e., filename=d:\binaries\filename)
# @search_paths tells where to search
# $check is a flag. If it is 1, then check the search paths,
# otherwise use the current directory as the path
my ( %params ) = @_;
$drvindex = @{$params{"r"}}[0];
my (@d_list);
@d_list = &MakeListFromDrvindex($drvindex);
return (@d_list);
}
sub PrintList
{
my ($list,$outfile) = @_;
# Print the items in the list
open( OUTFILE, ">$outfile");
$count=0;
for ($i=0; $i<@{$list};$i++) {
$item = lc $list->[$i];
print OUTFILE "$item\n";
$count++;
}
# print "$outfile has $count items\n";
close (OUTFILE);
}
sub PrintListWithHeader
{
my ($header,$list,$outfile) = @_;
# Print the items in the list
open( OUTFILE, ">$outfile");
for ($i=0; $i<@{$header};$i++) {
print OUTFILE "$header->[$i]\n";
}
$count=0;
for ($i=0; $i<@{$list};$i++) {
$item = lc $list->[$i];
print OUTFILE "$item\n";
$count++;
}
print "$outfile has $count items\n\n";
close (OUTFILE);
}
sub SourceDestDiff
{
my ( %params ) = @_;
my ( @file_list, @diff_list );
$file_name = @{$params{"a"}}[0];
#Open file and put it into an array
unless ( open( FHANDLE, $file_name) ) {
&LogMsg('err',"Unable to open $file_name\n");
}
@file_list = <FHANDLE>;
close (FHANDLE);
$i=0;
foreach $item (@file_list) {
$item =~ /(\S+),(\S+)/;
if ($1 ne $2) {
push @diff_list, $1;
}
}
return (@diff_list);
}
sub FileToList
{
my ( %params ) = @_;
my (@file_list, $path, @final_list);
$file_name = @{$params{"m"}}[0];
#Open file and put it into an array
unless ( open( FILENAME, $file_name) ) {
&LogMsg('err',"Unable to open $file_name\n");
}
@file_list = <FILENAME>;
close (FILENAME);
$i=0;
foreach $item (@file_list) {
chop $file_list[$i];
$i++;
}
# Put the path info in
if ( $params{"p"} ) {
# Look for the file in the search path
if ( $params{"x"} ) {
foreach $item (@file_list) {
$found = 0;
foreach $search (@{$params{"s"}}) {
if ( !$found && (-e "$search\\$item") ) {
$found = 1;
push @final_list, "<HASH>$search\\$item=$search\\$item";
}
}
}
}
# Use the first search path as the path
else {
$path = @{$params{"s"}}[0];
foreach $item (@file_list) {
push @final_list, "<HASH>$path\\$item=$path\\$item";
}
}
return(@final_list);
}
else {
return (@file_list);
}
}
sub LogFileInit
#+
# Initialize the log file
#
{
$ThisScript = "makelist";
$logfile=$ENV{"TMP"}."\\$ThisScript.log";
system("del $logfile");
}
sub MakeListFromDosnet
#+
# Accepts a dosnet.inf file and returns an array
# of all the files that occur under the [Files] sections
#
#-
{
my($FileName)=@_;
my(@dosnet,@return_array);
#Open Dosnet File and put it into an array
unless ( open( DOSNET, $FileName) ) {
&LogMsg('err',"Unable to open $FileName\n");
}
@dosnet = <DOSNET>;
close (DOSNET);
$found = 0;
foreach $item (@dosnet) {
# Search for [Files]
if ( $item =~ /\[Files\]/ ) {
&LogMsg('dbg', "Found \[Files\]");
$found = 1;
}
# Quit adding files to the list when a new section is encountered
elsif ( $found && ($item =~ /\[/ ) ) {
$found = 0;
}
elsif ( $found) {
undef($file_name);
# Return the non-white space characters that occur
# after "d1,"
$item =~ /d\d,(\S+)/;
if ($1) {
$file_name = $1;
}
# Check for a comma after the file name and get everything
# before the comma
$file_name =~ /(\S+),/;
if ($1) {
$file_name=$1;
}
# If a file was found, put it in the hash
if ($file_name) {
push @return_array, lc $file_name;
}
}
}
return (@return_array);
}
sub MakeListFromMedia
#+
# Accepts a _media.inx file and returns an array
# of all the files that occur under the [Files] sections
#
#-
{
my($FileName)=@_;
my(@media,@return_array);
#Open _media File and put it into an array
unless ( open( MEDIA, $FileName) ) {
&LogMsg('err',"Unable to open $FileName\n");
}
@media = <MEDIA>;
close (MEDIA);
$found = 0;
foreach $item (@media) {
# Search for [SourceDisksFiles]
if ( $item =~ /\[SourceDisksFiles\]/ ) {
&LogMsg('dbg', "Found \[SourceDisksFiles\]");
$found = 1;
}
# Quit adding files to the list when a new section is encountered
elsif ( $found && ($item =~ /\[/ ) ) {
$found = 0;
}
elsif ( $found) {
undef($file_name);
$file_name = $item;
# Check for an '=' after the file name and get everything
# before the '='
$file_name =~ /(\S+ +)=/;
if ($1) {
$file_name=$1;
}
$file_name =~ s/ //;
# If a file was found, put it in the hash
if ((length($file_name)>1)&&!($file_name =~ /^;/)) {
push @return_array, lc $file_name;
}
}
}
foreach $item (@media) {
# Search for [SourceDisksFiles.x86]
if ( $item =~ /\[SourceDisksFiles.x86\]/ ) {
&LogMsg('dbg', "Found \[SourceDisksFiles.x86\]");
$found = 1;
}
# Quit adding files to the list when a new section is encountered
elsif ( $found && ($item =~ /\[/ ) ) {
$found = 0;
}
elsif ( $found) {
undef($file_name);
$file_name = $item;
# Check for an '=' after the file name and get everything
# before the '='
$file_name =~ /(\S+ +)=/;
if ($1) {
$file_name=$1;
}
$file_name =~ s/ //;
# If a file was found, put it in the hash
if ((length($file_name)>1)&&!($file_name =~ /^;/)) {
push @return_array, lc $file_name;
}
}
}
foreach $item (@media) {
# Search for [SourceDisksFiles.amd64]
if ( $item =~ /\[SourceDisksFiles.amd64\]/ ) {
&LogMsg('dbg', "Found \[SourceDisksFiles.amd64\]");
$found = 1;
}
# Quit adding files to the list when a new section is encountered
elsif ( $found && ($item =~ /\[/ ) ) {
$found = 0;
}
elsif ( $found) {
undef($file_name);
$file_name = $item;
# Check for an '=' after the file name and get everything
# before the '='
$file_name =~ /(\S+ +)=/;
if ($1) {
$file_name=$1;
}
$file_name =~ s/ //;
# If a file was found, put it in the hash
if ((length($file_name)>1)&&!($file_name =~ /^;/)) {
push @return_array, lc $file_name;
}
}
}
foreach $item (@media) {
# Search for [SourceDisksFiles.ia64]
if ( $item =~ /\[SourceDisksFiles.ia64\]/ ) {
&LogMsg('dbg', "Found \[SourceDisksFiles.ia64\]");
$found = 1;
}
# Quit adding files to the list when a new section is encountered
elsif ( $found && ($item =~ /\[/ ) ) {
$found = 0;
}
elsif ( $found) {
undef($file_name);
$file_name = $item;
# Check for an '=' after the file name and get everything
# before the '='
$file_name =~ /(\S+ +)=/;
if ($1) {
$file_name=$1;
}
$file_name =~ s/ //;
# If a file was found, put it in the hash
if ((length($file_name)>1)&&!($file_name =~ /^;/)) {
push @return_array, lc $file_name;
}
}
}
return (@return_array);
}
sub MakeListFromExDosnet
#+
# Accepts an exdosnet.inf file and returns an array
# of all the files that occur under the [Files] sections
#
#-
{
my($FileName)=@_;
my(@exdosnet,@return_array);
#Open ExDosnet File and put it into an array
unless ( open( EXDOSNET, $FileName) ) {
&LogMsg('err',"Unable to open $FileName\n");
}
@exdosnet = <EXDOSNET>;
close (EXDOSNET);
$found = 0;
foreach $item (@exdosnet) {
# Search for [Files]
if ( $item =~ /\[Files\]/ ) {
&LogMsg('dbg', "Found \[Files\]");
$found = 1;
}
# Quit adding files to the list when a new section is encountered
elsif ( $found && ($item =~ /\[/ ) ) {
$found = 0;
}
elsif ( $found) {
undef($file_name);
# Return the non-white space characters that occur
# after "d1,"
# $item =~ /d\d,(\S+)/;
# if ($1) {
# $file_name = $1;
# }
$file_name = $item;
chomp $file_name;
# printf("\$item='%s' \$file_name='%s'\n", $item, $file_name);
# Check for a comma after the file name and get everything
# before the comma
# $file_name =~ /(\S+),/;
# if ($1) {
# $file_name=$1;
# }
# If a file was found, put it in the hash
if ($file_name) {
push @return_array, lc $file_name; }
}
}
return (@return_array);
}
sub MakeListFromDrvindex
#+
# Accepts a drvindex.inf file and returns an array
# of all the files that occur under the [driver] sections
#
#-
{
my($FileName)=@_;
my(@dosnet,@return_array);
#Open Dosnet File and put it into an array
unless ( open( DOSNET, $FileName) ) {
&LogMsg('err',"Unable to open $FileName\n");
}
@dosnet = <DOSNET>;
close (DOSNET);
$found = 0;
foreach $item (@dosnet) {
# Search for [driver]
if ( $item =~ /\[driver\]/ ) {
&LogMsg('dbg', "Found \[driver\]");
$found = 1;
}
# Quit adding files to the list when a new section is encountered
elsif ( $found && ($item =~ /\[/ ) ) {
$found = 0;
}
elsif ( $found) {
undef($file_name);
# Return the non-white space characters that occur
$item =~ /(\S+)/;
if ($1) {
$file_name=$1;
}
# If a file was found, put it in the hash
if ($file_name) {
push @return_array, lc $file_name;
}
}
}
return (@return_array);
}
#
# Sub(routine)s below
#
# Parse arguments passed to bincomp into %Parameters
sub GetArguments {
my(@ArgList)=@_;
my(%params,$arg,%flag_counts_possible,%flag_counts_actual);
# The flag_counts has tells how many arguments should follow
# each flag.
%flag_counts_possible=('a',1,'b',1,'c',1,'d',3,'h',1,'i','list','m',1,'n',1,'q',1,
'o',1, 'p',0,'r',1,'s','list','x',0, 'u','list');
%flag_counts_actual=('a',0,'b',0,'c',0,'d',0,'h',0,'i',0,'m',0,'n',0,'q',0,'o',0,
'p',0,'r',0,'s',0,'x',0,'u',0);
foreach $arg (@ArgList) {
# If this is a flag, set the flag variable, so
# next time through it will parse the correct
# argument
if( substr(lc($arg),0,1) eq "-") {
$flag=substr($arg,1,1);
if ($flag eq "?") {
&PrintUsage;
}
elsif (! exists $flag_counts_possible{$flag}) {
print "ERROR: $flag is an incorrect flag or switch\n";
&PrintUsage;
}
# Set the flag equal to one
elsif ( ( $flag_counts_possible{$flag} ne "list" ) &&
( $flag_counts_possible{$flag} == 0 ) ) {
push @{$params{$flag}}, 1;
}
}
elsif ( $flag_counts_possible{$flag} eq "list" ) {
push @{$params{$flag}}, $arg;
$flag_counts_actual{$flag}++;
}
elsif ( $flag_counts_actual{$flag} < $flag_counts_possible{$flag} ) {
push @{$params{$flag}}, $arg;
$flag_counts_actual{$flag}++;
}
else {
print "ERROR: Incorrect parameters\n";
&PrintUsage;
}
}
#&PrintParameters(%params);
return %params;
}
# Create Catalog header
sub GetHeader {
my($fname)=@_;
my(@HeadA);
push @HeadA, "[CatalogHeader]";
push @HeadA, "Name=$fname";
push @HeadA, "PublicVersion=0x0000001";
push @HeadA, "EncodingType=0x00010001";
push @HeadA, "CATATTR1=0x10010001:OSAttr:2:5.X";
push @HeadA, "";
push @HeadA, "[CatalogFiles]";
return @HeadA;
}
# --------------------------------------
# Print Usage info
# --------------------------------------
sub PrintUsage {
print <<EOT;
Usage: makelist -i lists -o outfile [-h catfile]
makelist -u lists -o outfile [-h catfile]
makelist -d list1 lists -o outfile [-h catfile]
makelist -n dosnetfile -o outfile [-h catfile]
makelist -q excdosntfile -o outfile [-h catfile]
makelist -r drvindexfile -o outfile [-h catfile]
makelist -c directory -o outfile [-h catfile]
-i lists Take the intersection of one or more lists
and print it to outfile. Each list is in
a file.
-u lists Take the union of one or more lists. Each list
is in a file.
-d list1 lists
Subtract lists from list 1 and print the
remaining elements to outfile
-n dosnetfile
Create a list from a dosnet.inf file
-q excdosntfile
Create a list from a excdosnt.inf file
-r drvindexfile
Create a list from a drvindex.inf file
-b mediafile
Create a list from media.inx file
-c directory
Create a list from a directory
-o outfile
Output file
-h catfile
Make this a CDF file for catfile (catfile will be
included in the header of the output file). This
will work on 5.X OS's.
makelist -m file -s search_paths [-px] -o outfile [-h catfile]
-h catfile
-m Create a list from a file
-o Output file
-p Put path info into the list
-s Search paths
-x Check the search paths
-h Put catalog header info in the file
makelist -a source_dest -o outfile
-a List in the format source,dest
-o Outputs source name for files whose source name is
not the same as the destination
EOT
exit;
}
# Output formatting/logging
sub LogMsg {
my($type,$msg) = @_;
my($fmsg);
$fmsg = $ThisScript."[".$type."]: ".$msg;
if( $type ne "dbg" ) {
system("echo $fmsg >> $logfile");
}
if( ($type ne "dbg") || $DBG ) {
print $fmsg."\n";
}
if($type eq "err") {
exit;
}
return;
}
# Print parameters
sub PrintParameters {
my(%params)=@_;
my($ar);
print "Printing input parameters\n";
foreach $item (keys %params) {
print "Flag $item : ";
$ar = \@{$params{$item}};
for ($i=0; $i< @{$ar}; $i++) {
print " $ar->[$i] ";
}
print "\n";
}
}