|
Packit |
fcad23 |
#! /usr/bin/perl
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
use strict;
|
|
Packit |
fcad23 |
use File::Copy;
|
|
Packit |
fcad23 |
use File::Basename;
|
|
Packit |
fcad23 |
use IO::File;
|
|
Packit |
fcad23 |
use Getopt::Std;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
my $ID_NOREAD = "NETSNMP_NO_READ_SUPPORT";
|
|
Packit |
fcad23 |
my $ID_NOWRITE = "NETSNMP_NO_WRITE_SUPPORT";
|
|
Packit |
fcad23 |
# my $ID_MIN = "NETSNMP_MINIMAL_CODE";
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
my($ST_OFF, $ST_IF, $ST_ELSE, $ST_IFN, $ST_ELSEN) =
|
|
Packit |
fcad23 |
("off", "if", "else", "ifnot", "elsenot");
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
my %opts = ();
|
|
Packit |
fcad23 |
my %thash = ();
|
|
Packit |
fcad23 |
my $canwrite = 1; # current write state
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
my($appname,$apppath) = fileparse($0);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
my $minimal_include_path = "include/net-snmp/net-snmp-features.h";
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ( (!getopts("rwmi:v",\%opts)) || (1 != $#ARGV) ) {
|
|
Packit |
fcad23 |
print "$appname [options] from-directory to-direpctory\n";
|
|
Packit |
fcad23 |
print "-r parse out code unneeded by $ID_NOREAD ifdef\n";
|
|
Packit |
fcad23 |
print "-w parse out code unneeded by $ID_NOWRITE ifdef (DEFAULT)\n";
|
|
Packit |
fcad23 |
print "-m parse out code unneeded according minimalist ifdefs\n";
|
|
Packit |
fcad23 |
print " requires from-directory to be the top of the net-snmp tree\n";
|
|
Packit |
fcad23 |
print " (This is multiple ifdefs auto selected depending\n";
|
|
Packit |
fcad23 |
print " on the net-snmp source configuration)\n\n";
|
|
Packit |
fcad23 |
print "-i 'ignore-file' file of files to ignore (not copy)\n";
|
|
Packit |
fcad23 |
print "-v print verbose info to standard out\n";
|
|
Packit |
fcad23 |
die "Error: two command line arguments required\n";
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#default to everything
|
|
Packit |
fcad23 |
if ( (!exists $opts{r}) && (!exists $opts{w}) && (!exists $opts{m}) ) {
|
|
Packit |
fcad23 |
$thash{"$ID_NOWRITE"} = "$ST_OFF";
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else {
|
|
Packit |
fcad23 |
$thash{"$ID_NOREAD"} = "$ST_OFF" if ( exists $opts{r} );
|
|
Packit |
fcad23 |
$thash{"$ID_NOWRITE"} = "$ST_OFF" if ( exists $opts{w} );
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
my $fromdir = $ARGV[0];
|
|
Packit |
fcad23 |
my $todir = $ARGV[1];
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ( !(-e $fromdir) ) {
|
|
Packit |
fcad23 |
die "Error: $appname: from directory does not exist: '$fromdir'\n";
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if ( !(-d $fromdir) ) {
|
|
Packit |
fcad23 |
die "Error: $appname: from directory, '$fromdir', must be a directory\n";
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ( exists $opts{m} ) {
|
|
Packit |
fcad23 |
load_minamal_ifdefs();
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
# create search string from tags
|
|
Packit |
fcad23 |
# minimal must be done before this
|
|
Packit |
fcad23 |
my $search = join "|", (keys %thash);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
# check for and load ignore file
|
|
Packit |
fcad23 |
my $igstring = "";
|
|
Packit |
fcad23 |
if ( exists $opts{i} ) {
|
|
Packit |
fcad23 |
open my($IH), "< $opts{i}" or
|
|
Packit |
fcad23 |
die "Could not open ignore-file '$opts{i}': $!";
|
|
Packit |
fcad23 |
my @iglist = <$IH>;
|
|
Packit |
fcad23 |
$IH->close();
|
|
Packit |
fcad23 |
chomp @iglist;
|
|
Packit |
fcad23 |
$igstring = join "|", @iglist;
|
|
Packit |
fcad23 |
$igstring = "(" . $igstring . ")";
|
|
Packit |
fcad23 |
print "ignore string: \'$igstring\'\n" if (exists $opts{v});
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ( -e $todir ) {
|
|
Packit |
fcad23 |
if ( ((-d $fromdir) && !(-d $todir)) ||
|
|
Packit |
fcad23 |
(!(-d $fromdir) && (-d $todir)) ) {
|
|
Packit |
fcad23 |
die "Error: $appname: from-directory and to-directory must both either be a file or both be a directory\n";
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else {
|
|
Packit |
fcad23 |
if (-d $fromdir) {
|
|
Packit |
fcad23 |
print "Warning: $appname: '$todir' does not exist, creating\n";
|
|
Packit |
fcad23 |
mkdir "$todir" or
|
|
Packit |
fcad23 |
die "Error: $appname: Unable to create to-directory '$todir': $!\n";
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (-d $fromdir) {
|
|
Packit |
fcad23 |
parsedirectory($fromdir, $todir);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else {
|
|
Packit |
fcad23 |
parsefile($fromdir, $todir);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
exit(0);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
# PROCEDURES PROCEDURES PROCEDURES PROCEDURES PROCEDURES
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
sub parsedirectory {
|
|
Packit |
fcad23 |
my($fdir, $tdir) = @_;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
my @ldirs = ();
|
|
Packit |
fcad23 |
my $DH;
|
|
Packit |
fcad23 |
opendir my($DH), $fdir or die "Could not open directory '$fdir': $!";
|
|
Packit |
fcad23 |
if ( !(-e $tdir) || !(-d $tdir) ) {
|
|
Packit |
fcad23 |
mkdir $tdir or die "Could not create directory '$tdir': $!";
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
my @flist = readdir $DH;
|
|
Packit |
fcad23 |
closedir $DH;
|
|
Packit |
fcad23 |
# remove . and ..
|
|
Packit |
fcad23 |
@flist = grep (! /(^\.$|^\.\.$)/ , @flist);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
while (my $name = shift @flist) {
|
|
Packit |
fcad23 |
if (-d "$fdir/$name") {
|
|
Packit |
fcad23 |
push @ldirs, "$name";
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else {
|
|
Packit |
fcad23 |
parsefile("$fdir/$name", "$tdir/$name");
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
while (my $name = shift @ldirs) {
|
|
Packit |
fcad23 |
parsedirectory("$fdir/$name", "$tdir/$name")
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
} # parsedirectory
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
# returns 1 if current state for tag is write, 0 otherwise
|
|
Packit |
fcad23 |
sub iswritestate {
|
|
Packit |
fcad23 |
my $tag = "";
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
foreach $tag (keys %thash) {
|
|
Packit |
fcad23 |
if ( ($thash{$tag} eq "$ST_ELSE") ||
|
|
Packit |
fcad23 |
($thash{$tag} eq "$ST_IFN") ) {
|
|
Packit |
fcad23 |
return(0);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return(1);
|
|
Packit |
fcad23 |
} # iswritestate
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
# Check $line for ifdef state changes for all of the tags and change
|
|
Packit |
fcad23 |
# state.
|
|
Packit |
fcad23 |
# If there is a state change error return 0, otherwise return 1;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
sub checkifdef {
|
|
Packit |
fcad23 |
my($TF, $line, $fromfilename) = @_;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ( $line =~ /(#ifdef|#ifndef|#else|#endif).*($search)(\s|$|\*)/ ) {
|
|
Packit |
fcad23 |
my $copt = $1;
|
|
Packit |
fcad23 |
my $tag = $2;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ( $copt eq "#ifdef" ) {
|
|
Packit |
fcad23 |
if ($thash{"$tag"} eq "$ST_OFF") {
|
|
Packit |
fcad23 |
$thash{"$tag"} = "$ST_IF";
|
|
Packit |
fcad23 |
print "state change $tag: $ST_OFF -> $ST_IF\n" if (exists $opts{v});
|
|
Packit |
fcad23 |
$canwrite = iswritestate();
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else {
|
|
Packit |
fcad23 |
print "Error: $fromfilename: Found '#ifdef $tag' with state $thash{$tag}\n";
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
elsif ( $copt eq "#ifndef" ) {
|
|
Packit |
fcad23 |
if ($thash{"$tag"} eq "$ST_OFF") {
|
|
Packit |
fcad23 |
# before changing to a non-write state (ifn) print #IFNDEF
|
|
Packit |
fcad23 |
# line, if current state is a write state.
|
|
Packit |
fcad23 |
print $TF "$line" if ( $canwrite );
|
|
Packit |
fcad23 |
$thash{"$tag"} = "$ST_IFN";
|
|
Packit |
fcad23 |
print "state change $tag: $ST_OFF -> $ST_IFN\n" if (exists $opts{v});
|
|
Packit |
fcad23 |
$canwrite = iswritestate();
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else {
|
|
Packit |
fcad23 |
print "Error: $fromfilename: Found '#ifndef $tag' with state $thash{$tag}\n";
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
elsif ( $copt eq "#else" ) {
|
|
Packit |
fcad23 |
if ($thash{"$tag"} eq "$ST_IF") {
|
|
Packit |
fcad23 |
# before changing to a non-write state (else) print #else
|
|
Packit |
fcad23 |
# line, if current state is a write state.
|
|
Packit |
fcad23 |
print $TF "$line" if ( $canwrite );
|
|
Packit |
fcad23 |
$thash{"$tag"} = "$ST_ELSE";
|
|
Packit |
fcad23 |
print "state change $tag: $ST_IF -> $ST_ELSE\n" if (exists $opts{v});
|
|
Packit |
fcad23 |
$canwrite = iswritestate();
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
elsif ($thash{"$tag"} eq "$ST_IFN") {
|
|
Packit |
fcad23 |
$thash{"$tag"} = "$ST_ELSEN";
|
|
Packit |
fcad23 |
print "state change $tag: $ST_IFN -> $ST_ELSEN\n" if (exists $opts{v});
|
|
Packit |
fcad23 |
$canwrite = iswritestate();
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else {
|
|
Packit |
fcad23 |
print "Error: $fromfilename: Found '#else (...) $tag' with state $thash{$tag}\n";
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
elsif ( $copt eq "#endif" ) {
|
|
Packit |
fcad23 |
if (($thash{"$tag"} eq "$ST_ELSE") || ($thash{"$tag"} eq "$ST_IF") ||
|
|
Packit |
fcad23 |
($thash{"$tag"} eq "$ST_ELSEN") || ($thash{"$tag"} eq "$ST_IFN"))
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
print "state change $tag: $thash{$tag} -> $ST_OFF\n"
|
|
Packit |
fcad23 |
if (exists $opts{v});
|
|
Packit |
fcad23 |
$thash{"$tag"} = "$ST_OFF";
|
|
Packit |
fcad23 |
$canwrite = iswritestate();
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else {
|
|
Packit |
fcad23 |
print "Error: Found '#endif (...) $tag' with state $thash{$tag}\n";
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
} # foreach tag
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return 1;
|
|
Packit |
fcad23 |
} # checkifdef
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
sub parsefile {
|
|
Packit |
fcad23 |
my($fname, $tname) = @_;
|
|
Packit |
fcad23 |
my $FF; my $TF;
|
|
Packit |
fcad23 |
my @fromfile = ();
|
|
Packit |
fcad23 |
$canwrite = 1;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
# ignore file for file names
|
|
Packit |
fcad23 |
if ( (exists $opts{i}) && ("$fname" =~ /$igstring/) ) {
|
|
Packit |
fcad23 |
print "IGNORING $fname\n" if ( exists $opts{v} );
|
|
Packit |
fcad23 |
return 1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
print "Info: Opening '$fname'\n" if ( exists $opts{v} );
|
|
Packit |
fcad23 |
if ( !(open($FF, "< $fname")) ) {
|
|
Packit |
fcad23 |
print "Warning: unable to open input file, skipping: '$fname': $!\n";
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
my @fromfile = <$FF>;
|
|
Packit |
fcad23 |
$FF->close();
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ( !(open($TF, "> $tname")) ) {
|
|
Packit |
fcad23 |
print "Warning: unable to open output file, skipping: '$tname': $!\n";
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
my $mode = (stat("$fname"))[2];
|
|
Packit |
fcad23 |
if ($mode) { my $resp = chmod $mode, "$tname"; }
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
my $line = "";
|
|
Packit |
fcad23 |
my @tout = ();
|
|
Packit |
fcad23 |
my $retval = 1;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
while ( $line = shift @fromfile ) {
|
|
Packit |
fcad23 |
# check for any ifdef state changes
|
|
Packit |
fcad23 |
if ( ! checkifdef($TF, $line, $fname) ) {
|
|
Packit |
fcad23 |
$FF->close();
|
|
Packit |
fcad23 |
$TF->close();
|
|
Packit |
fcad23 |
die "Error: tag error in file \'$fname\', exiting\n";
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ( $canwrite ) {
|
|
Packit |
fcad23 |
print $TF "$line";
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else {
|
|
Packit |
fcad23 |
print "Info: not copying: $fname: $line" if ( exists $opts{v} );
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (! $canwrite) {
|
|
Packit |
fcad23 |
print "End of $fname reached and we're not reset into 'canwrite' state\n";
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
$TF->close();
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return $retval;
|
|
Packit |
fcad23 |
} # parsefile
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
# note, fromdir should have already been checked to exist and be a
|
|
Packit |
fcad23 |
# directory
|
|
Packit |
fcad23 |
sub load_minamal_ifdefs {
|
|
Packit |
fcad23 |
my @filelist = ();
|
|
Packit |
fcad23 |
my $MF;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if ( !(open($MF, "< $fromdir/$minimal_include_path")) ) {
|
|
Packit |
fcad23 |
die "Unable to open main minimal feature file: '$fromdir/$minimal_include_path'\n";
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
my $line;
|
|
Packit |
fcad23 |
# skip preceding lines
|
|
Packit |
fcad23 |
while ( ($line = <$MF>) &&
|
|
Packit |
fcad23 |
($line !~ /^#else.*NETSNMP_FEATURE_CHECKING/ ) ) {
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
# grab the fetaure .h files
|
|
Packit |
fcad23 |
while ( ($line = <$MF>) &&
|
|
Packit |
fcad23 |
($line !~ /^#endif.*NET_SNMP_FEATURE_CHECKING/) ) {
|
|
Packit |
fcad23 |
if ($line =~ /include.*<(.*.h)>/) {
|
|
Packit |
fcad23 |
push @filelist, $1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
close($MF);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
while (my $fname = shift @filelist) {
|
|
Packit |
fcad23 |
if ( !( -e "$fromdir/include/$fname" ) ) {
|
|
Packit |
fcad23 |
print "Warn: feature file does not exist, skipping: '$fromdir/include/$fname'";
|
|
Packit |
fcad23 |
next;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if ( !(open($MF, "< $fromdir/include/$fname")) ) {
|
|
Packit |
fcad23 |
die "Unable to open minimal feature file: '$fromdir/include/$fname'\n";
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
while ( ($line = <$MF>) ) {
|
|
Packit |
fcad23 |
if ( $line =~ /^#define.*(NETSNMP_FEATURE_REMOVE[^ ]+) / ) {
|
|
Packit |
fcad23 |
$thash{"$1"} = $ST_OFF;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
close($MF);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
} # load_minamal_ifdefs
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|