#!/usr/bin/perl use Switch; sub trim; sub get_value; sub get_var; sub get_field; # trim($str) # input: a string # output: the trimmed string (without whitespace) sub trim { $ans = $_[0]; $ans =~ s/^\s+//; #remove leading spaces $ans =~ s/\s+$//; #remove trailing spaces return $ans; } # get_value($str) # input: a XML tag # output: the tag name sub get_value { $start = 1 + index($_[0], ">"); $end = rindex($_[0], "<"); return substr($_[0], $start, ($end - $start)); } # get_var($str, $var_name) # input: a XML tag and a variable name # output: the variable value sub get_var { ($str, $var_name) = @_; # trim everything until the requested variable's value $start = index($str, " ".$var_name."="); $ans = substr($str, 3 + length($var_name) + $start); # trim everything after the value $start = index($ans, "\""); $ans = substr($ans, 0, $start); return $ans } # get_field($str) # input: a XML tag # output: the tag value sub get_field { $ans = substr($_[0], 1, (index($_[0], ">") - 1)); if (index($ans, " ") != -1) { $ans = substr($_[0], 1, (index($_[0], " ") - 1)); } return $ans; } if ((! -e $ARGV[0]) || (-e $ARGV[1])) { print("Usage: rpm2ppm [FILE] [OUTPUT] [DISTRO] [VERSION]\n"); exit(1); } open(rpm_package_list, $ARGV[0]); open(ppm_package_list, ">>$ARGV[1]"); while ($line = ) { $line = trim($line); $field = get_field($line); switch ($field) { case "name" { $package_name = get_value($line); print $package_name." "; } case "version" { $package_version = get_var($line, "ver"); $package_revision = get_var($line, "rel"); } case "summary" { $package_description = get_value($line); } case "size" { $package_size = get_var($line, "installed")."K"; } case "location" { $package_path = get_var($line, "href"); $pos = rindex($package_path, "/"); $package_file_name = substr($package_path, (1 + $pos)); $package_path = substr($package_path, 0, $pos); } case "rpm:provides" { $package_provides = ""; $provides = 1; } case "rpm:requires" { $package_dependencies = ""; $requires = 1; } case "rpm:entry" { $entry_name = get_var($line, "name"); # filter shared libraries, architecture names and files if ((index($entry_name, ".so") == -1) && (index($entry_name, "(") == -1) && (index($entry_name, "/") == -1)) { # process packages provided by the package if ($provides == 1) { if ($package_provides eq "") { $package_provides = "|".$entry_name."|"; } else { $package_provides = $package_provides."|".$entry_name."|"; } } else { # process dependencies if ($requires == 1) { # get rid of the package's dependencies provided by the package itself (e.g mktemp and coreutils) if (($entry_name ne $package_name) && (index($package_provides, "|".$entry_name."|")) == -1) { if ($package_dependencies eq "") { $package_dependencies = "+".$entry_name; } else { # make sure dependencies aren't added twice if ((index($package_dependencies, ",+".$entry_name) == -1) && (index($package_dependencies, "+".$entry_name.",") == -1)) { $package_dependencies = $package_dependencies.",+".$entry_name; } } } } } } } case "/rpm:provides" { $provides = 0; } case "/rpm:requires" { $requires = 0; } # the last tag of each entry case "/package" { print ppm_package_list $package_name."-".$package_version."|".$package_name."|".$package_version."|".$package_revision."|BuildingBlock|".$package_size."|".$package_path."|".$package_file_name."|".$package_dependencies."|".$package_description."|".$ARGV[2]."|".$ARGV[3]."|\n"; } } } print "\n"; close(rpm_package_list); close(ppm_package_list);