summaryrefslogtreecommitdiffstats
path: root/tools/syncrpms
diff options
context:
space:
mode:
Diffstat (limited to 'tools/syncrpms')
-rwxr-xr-xtools/syncrpms157
1 files changed, 113 insertions, 44 deletions
diff --git a/tools/syncrpms b/tools/syncrpms
index 1c7eea761..ccb806d6c 100755
--- a/tools/syncrpms
+++ b/tools/syncrpms
@@ -28,7 +28,7 @@ sub version_compare {
my ($a, $b) = @_;
local $_;
- while ($a && $b) {
+ while ($a || $b) {
my ($sb, $sa) = map { $1 if $a =~ /^\W*\d/ ? s/^\W*0*(\d+)// : s/^\W*(\D+)// } ($b, $a);
$_ = length($sa) cmp length($sb) || $sa cmp $sb and return $_;
}
@@ -43,6 +43,14 @@ sub cp {
exec '/bin/cp', @_;
}
}
+sub mv {
+ my $pid;
+ if ($pid = fork()) {
+ waitpid($pid, 0);
+ } else {
+ exec '/bin/mv', @_;
+ }
+}
sub rm {
my $pid;
if ($pid = fork()) {
@@ -54,39 +62,57 @@ sub rm {
#- get a hash on name of srpms/rpms in a directory.
sub get_rpms {
- my ($dir, $rpms, $flag) = @_;
+ my ($dir, $rpms, $flag, $modifiable) = @_;
opendir D, $dir or die "cannot open directory $dir\n";
map {
- if (/([^\/]*?)-([^-]*)-([^-]*)\.([^-]*)(?:\.src)?\.rpm$/) {
- if ($rpms->{$1}) {
- if (version_compare($rpms->{$1}{version}, $2) > 0 ||
- version_compare($rpms->{$1}{version}, $2) == 0 && version_compare($rpms->{$1}{release}, $3) > 0) {
- if ($flag->{clean}) {
- print "removing obseleted $rpms->{$1}{file} by $_ in $rpms->{$1}{dir}\n" if $flag->{verbose};
- rm("$rpms->{$1}{dir}/$rpms->{$1}{file}");
+ if (/([^\/]*?)-([^-]*)-([^-]*)\.([^-\.]*)\.rpm$/) {
+ my $key = "$1 $4"; #- get name including architecture.
+ if ($rpms->{$key}) {
+ if (version_compare($2, $rpms->{$key}{version}) > 0 ||
+ version_compare($2, $rpms->{$key}{version}) == 0 && version_compare($3, $rpms->{$key}{release}) > 0) {
+ if ($modifiable) {
+ if ($flag->{sorted}) {
+ print "you said rpms directory are sorted, so I keep obseleted $rpms->{$key}{file} by $_ in $rpms->{$key}{dir}\n" if $flag->{verbose};
+ } else {
+ if (-d $flag->{conflict}) {
+ print "moving obseleted $rpms->{$key}{file} by $_ in $rpms->{$key}{dir}\n" if $flag->{verbose};
+ mv("$rpms->{$key}{dir}/$rpms->{$key}{file}", $flag->{conflict});
+ } elsif ($flag->{clean}) {
+ print "removing obseleted $rpms->{$key}{file} by $_ in $rpms->{$key}{dir}\n" if $flag->{verbose};
+ rm("$rpms->{$key}{dir}/$rpms->{$key}{file}");
+ }
+ }
}
- $rpms->{$1} = { name => $1,
- version => $2,
- release => $3,
- arch => $4,
- dir => $dir,
- file => $_,
- };
+ $rpms->{$key} = { key => $key,
+ name => $1,
+ version => $2,
+ release => $3,
+ arch => $4,
+ dir => $dir,
+ file => $_,
+ };
} else {
- if ($flag->{clean}) {
- print "removing older or equal $_ by $rpms->{$1}{file} in $dir\n" if $flag->{verbose};
- rm("$dir/$_");
+ if ($modifiable) {
+ if (-d $flag->{conflict}) {
+ print "copying older or equal $_ by $rpms->{$key}{file} in $flag->{conflict}\n" if $flag->{verbose};
+ cp("$dir/$_", $flag->{conflict});
+ chmod 0644, "$flag->{conflict}/$_";
+ } elsif ($flag->{clean}) {
+ print "removing older or equal $_ by $rpms->{$key}{file} in $dir\n" if $flag->{verbose};
+ rm("$dir/$_");
+ }
}
}
} else {
- $rpms->{$1} = { name => $1,
- version => $2,
- release => $3,
- arch => $4,
- dir => $dir,
- file => $_,
- };
+ $rpms->{$key} = { key => $key,
+ name => $1,
+ version => $2,
+ release => $3,
+ arch => $4,
+ dir => $dir,
+ file => $_,
+ };
}
} else {
print STDERR "unable to parse filename $_\n";
@@ -95,6 +121,39 @@ sub get_rpms {
closedir D;
}
+#- sync packages list according to hashes of rpms.
+sub sync_medium {
+ my ($rpmsdirs, $list, $rpms, $flag) = @_;
+ my %pkg2dir;
+
+ #- build a hash according to rpmsdirs and list for package name.
+ my $i = 0;
+ foreach (@$list) {
+ local *F;
+ open F, $_ or die "unable to open packages list file \"$_\"\n";
+ foreach (<F>) {
+ chomp;
+ print STDERR "package \"$_\" is listed in mulitple list files!\n" if $pkg2dir{$_};
+ $pkg2dir{$_} = $rpmsdirs->[$i];
+ print "package \"$_\" listed in list files does not exists in rpms directory\n" if $flag->{verbose} && !$rpms->{$_};
+ }
+ close F;
+
+ ++$i;
+ }
+
+ #- check for right directory, and move if necessary.
+ foreach (values %$rpms) {
+ unless ($pkg2dir{$_->{key}}) {
+ print "file $_->{file} in $_->{dir} define package \"$_->{name}\" not listed in list files\n" if $flag->{verbose};
+ } elsif ($_->{dir} ne $pkg2dir{$_->{key}}) {
+ print "moving file $_->{file} in $_->{dir} to $pkg2dir{$_->{key}}\n" if $flag->{verbose};
+ mv("$_->{dir}/$_->{file}", $pkg2dir{$_->{key}});
+ $_->{dir} = $pkg2dir{$_->{key}};
+ }
+ }
+}
+
#- sync two hashes of rpms, update rpms and printer newer version that are not taken into account.
sub sync_rpms {
my ($source, $target, $flag) = @_;
@@ -107,6 +166,7 @@ sub sync_rpms {
}
if (-d $flag->{add}) {
cp("$source->{$_}{dir}/$source->{$_}{file}", $flag->{add});
+ chmod 0644, "$flag->{add}/$source->{$_}{file}";
}
}
}
@@ -122,15 +182,16 @@ sub sync_rpms {
}
if ($flag->{update}) {
cp("$source->{$_}{dir}/$source->{$_}{file}", $target->{$_}{dir});
+ chmod 0644, "$target->{$_}{dir}/$source->{$_}{file}";
unless (-e "$target->{$_}{dir}/$source->{$_}{file}") {
die "unable to copy $source->{$_}{file} from $source->{$_}{dir} into $target->{$_}{dir}\n";
}
- rm("$target->{$_}{dir}/$target->{$_}{file}");
+ rm("$target->{$_}{dir}/$target->{$_}{file}") unless $source->{$_}{file} eq $target->{$_}{file}; #- copy on eq
}
} elsif (version_compare($source->{$_}{version}, $target->{$_}{version}) != 0 ||
version_compare($source->{$_}{release}, $target->{$_}{release}) != 0) {
if ($flag->{verbose}) {
- print STDERR "keeping more up-to-date version $target->{$_}{dir}/$source->{$_}{file} against $source->{$_}{dir}/$source->{$_}{file}, check your repository !\n";
+ print STDERR "keeping more up-to-date version $target->{$_}{dir}/$target->{$_}{file} against $source->{$_}{dir}/$source->{$_}{file}, check your repository !\n";
}
} #- say nothing if source is equal to target.
}
@@ -140,8 +201,9 @@ sub sync_rpms {
foreach (keys %$target) {
unless ($source->{$_}) {
if ($flag->{verbose}) {
- print "removing $target->{$_}{file}" . ($flag->{remove} ? " from $target->{$_}{dir}\n" : " is neccessary!\n")
- }
+ print "removing $target->{$_}{file}" . ($flag->{remove} ? " from $target->{$_}{dir}\n" : " is neccessary!\n");
+ my $k = $_;
+ }
if ($flag->{remove}) {
rm("$target->{$_}{dir}/$target->{$_}{file}");
}
@@ -153,21 +215,24 @@ sub sync_rpms {
sub main {
my @from_rpms;
my @to_rpms;
- my $target_rpms;
+ my @list;
+ my $target;
my %flag;
my %source;
my %target;
foreach (@_) {
if (/^--(\w*)$/) {
- if ($1 eq 'verbose' || $1 eq 'update' || $1 eq 'remove' || $1 eq 'clean') {
+ if ($1 eq 'verbose' || $1 eq 'update' || $1 eq 'remove' || $1 eq 'clean' || $1 eq 'sorted') {
$flag{$1} = 1;
- } elsif ($1 eq 'add') {
- $flag{add} = undef;
+ } elsif ($1 eq 'add' || $1 eq 'conflict') {
+ $flag{$1} = undef;
} elsif ($1 eq 'from') {
- $target_rpms = \@from_rpms;
+ $target = \@from_rpms;
} elsif ($1 eq 'to') {
- $target_rpms = \@to_rpms;
+ $target = \@to_rpms;
+ } elsif ($1 eq 'list') {
+ $target = \@list;
} else {
die "unknown option: $1\n";
}
@@ -175,26 +240,30 @@ sub main {
if (exists $flag{add} && ! $flag{add}) {
$flag{add} = $_;
die "cannot add to non-directory: $_\n" unless -d $flag{add};
+ } elsif (exists $flag{conflict} && ! $flag{conflict}) {
+ $flag{conflict} = $_;
+ die "cannot add to non-directory: $_\n" unless -d $flag{conflict};
} else {
- die "unknown parameter: $_\n" unless $target_rpms;
- push @$target_rpms, $_;
+ die "unknown parameter: $_\n" unless $target;
+ push @$target, $_;
}
}
}
- die "usage: syncrpms [--update] [--remove] [--clean] [--add <dir>] --from <dir_sources> --to <dir_target>\n"
- unless scalar(@from_rpms) > 0 && scalar(@to_rpms) > 0;
+ die "usage: syncrpms [--update] [--remove] [--clean] [--sorted] [--add <dir>] [--conflict <dir>] --from <dir_sources> --to <dir_targets> [--list <files>]\n"
+ unless scalar(@from_rpms) > 0 || scalar(@to_rpms) > 0;
#- parse directory structures.
- get_rpms($_, \%source, \%flag) foreach @from_rpms;
- get_rpms($_, \%target, \%flag) foreach @to_rpms;
-
+ get_rpms($_, \%source, \%flag, 0) foreach @from_rpms;
print STDERR "reading " . scalar(keys %source) . " packages as source rpms from\n";
print STDERR " $_\n" foreach @from_rpms;
+
+ get_rpms($_, \%target, \%flag, 1) foreach @to_rpms;
print STDERR "reading " . scalar(keys %target) . " packages as target rpms from\n";
print STDERR " $_\n" foreach @to_rpms;
- sync_rpms(\%source, \%target, \%flag);
+ sync_medium(\@to_rpms, \@list, \%target, \%flag) if scalar(@list) > 0 && scalar(@to_rpms) > 0;
+ sync_rpms(\%source, \%target, \%flag) if scalar(@from_rpms) > 0 && scalar(@to_rpms) > 0;
}
main(@ARGV);