dpkg-name.pl 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. #!/usr/bin/perl
  2. #
  3. # dpkg-name
  4. #
  5. # Copyright © 1995,1996 Erick Branderhorst <branderh@debian.org>.
  6. # Copyright © 2009 Guillem Jover <guillem@debian.org>.
  7. #
  8. # This program is free software; you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation; either version 2 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License
  19. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. use warnings;
  21. use strict;
  22. use File::Basename;
  23. use File::Path;
  24. use Dpkg;
  25. use Dpkg::Gettext;
  26. use Dpkg::ErrorHandling;
  27. use Dpkg::Control;
  28. use Dpkg::Arch qw(get_host_arch);
  29. textdomain("dpkg-dev");
  30. my %options = (
  31. subdir => 0,
  32. destdir => "",
  33. createdir => 0,
  34. overwrite => 0,
  35. symlink => 0,
  36. architecture => 1,
  37. );
  38. sub version()
  39. {
  40. printf(_g("Debian %s version %s.\n"), $progname, $version);
  41. }
  42. sub usage()
  43. {
  44. printf(_g("Usage: %s [<option>...] <file>...\n"), $progname);
  45. print(_g("
  46. Options:
  47. -a, --no-architecture no architecture part in filename.
  48. -o, --overwrite overwrite if file exists.
  49. -k, --symlink don't create a new file, but a symlink.
  50. -s, --subdir [dir] move file into subdir (use with care).
  51. -c, --create-dir create target dir if not there (use with care).
  52. -h, --help show this help message.
  53. -v, --version show the version.
  54. file.deb changes to <package>_<version>_<architecture>.<package_type>
  55. according to the 'underscores convention'.
  56. "));
  57. }
  58. sub fileexists($)
  59. {
  60. my ($filename) = @_;
  61. if (-f $filename) {
  62. return 1;
  63. } else {
  64. warning(_g("cannot find '%s'"), $filename);
  65. return 0;
  66. }
  67. }
  68. sub filesame($$)
  69. {
  70. my ($a, $b) = @_;
  71. my @sta = stat($a);
  72. my @stb = stat($b);
  73. # Same device and inode numbers.
  74. return (@sta and @stb and $sta[0] == $stb[0] and $sta[1] == $stb[1]);
  75. }
  76. sub getfields($)
  77. {
  78. my ($filename) = @_;
  79. # Read the fields
  80. open(CDATA, '-|', "dpkg-deb", "-f", "--", $filename) ||
  81. syserr(_g("cannot open %s"), $filename);
  82. my $fields = Dpkg::Control->new(type => CTRL_PKG_DEB);
  83. $fields->parse_fh(\*CDATA, sprintf(_g("binary control file %s"), $filename));
  84. close(CDATA);
  85. return $fields;
  86. }
  87. sub getarch($$)
  88. {
  89. my ($filename, $fields) = @_;
  90. my $arch = $fields->{Architecture};
  91. if (!$fields->{Architecture} and $options{architecture}) {
  92. $arch = get_host_arch();
  93. warning(_g("assuming architecture '%s' for '%s'"), $arch, $filename);
  94. }
  95. return $arch;
  96. }
  97. sub getname($$$)
  98. {
  99. my ($filename, $fields, $arch) = @_;
  100. my $pkg = $fields->{Package};
  101. (my $version = $fields->{Version}) =~ s/.*://;
  102. my $type = $fields->{'Package-Type'} || 'deb';
  103. my $tname;
  104. if ($options{architecture}) {
  105. $tname = "$pkg\_$version\_$arch.$type";
  106. } else {
  107. $tname = "$pkg\_$version.$type";
  108. }
  109. (my $name = $tname) =~ s/ //g;
  110. if ($tname ne $name) { # control fields have spaces
  111. warning("bad package control information for '%s'", $filename);
  112. }
  113. return $name;
  114. }
  115. sub getdir($$$)
  116. {
  117. my ($filename, $fields, $arch) = @_;
  118. my $dir;
  119. if (!$options{destdir}) {
  120. $dir = dirname($filename);
  121. if ($options{subdir}) {
  122. my $section = $fields->{Section};
  123. if (!$section) {
  124. $section = "no-section";
  125. warning("assuming section '%s' for '%s'", $section, $filename);
  126. }
  127. if ($section ne "non-free" and $section ne "contrib" and
  128. $section ne "no-section") {
  129. $dir = "unstable/binary-$arch/$section";
  130. } else {
  131. $dir = "$section/binary-$arch";
  132. }
  133. }
  134. } else {
  135. $dir = $options{destdir};
  136. }
  137. return $dir;
  138. }
  139. sub move($)
  140. {
  141. my ($filename) = @_;
  142. if (fileexists($filename)) {
  143. my $fields = getfields($filename);
  144. unless (exists $fields->{Package}) {
  145. warning("no Package field found in '%s', skipping it", $filename);
  146. return;
  147. }
  148. my $arch = getarch($filename, $fields);
  149. my $name = getname($filename, $fields, $arch);
  150. my $dir = getdir($filename, $fields, $arch);
  151. if (! -d $dir) {
  152. if ($options{createdir}) {
  153. if (mkpath($dir)) {
  154. info("created directory '%s'", $dir);
  155. } else {
  156. error("failed creating directory '%s'", $dir);
  157. }
  158. } else {
  159. error("no such dir '%s', try --create-dir (-c) option", $dir);
  160. }
  161. }
  162. my $newname = "$dir/$name";
  163. my @command;
  164. if ($options{symlink}) {
  165. @command = ("ln", "-s", "--");
  166. } else {
  167. @command = ("mv", "--");
  168. }
  169. if (filesame($newname, $filename)) {
  170. warning("skipping '%s'", $filename);
  171. } elsif (-f $newname and !$options{overwrite}) {
  172. warning("cannot move '%s' to existing file", $filename);
  173. } elsif (system(@command, $filename, $newname) == 0) {
  174. info("moved '%s' to '%s'", basename($filename), $newname);
  175. } else {
  176. error("mkdir can be used to create directory");
  177. }
  178. }
  179. }
  180. @ARGV || usageerr(_g("need at least a filename"));
  181. while (@ARGV) {
  182. $_ = shift(@ARGV);
  183. if (m/^-[h?]|--help$/) {
  184. usage();
  185. exit(0);
  186. } elsif (m/^-v|--version$/) {
  187. version();
  188. exit(0);
  189. } elsif (m/^-c|--create-dir$/) {
  190. $options{createdir} = 1;
  191. } elsif (m/^-s|--subdir$/) {
  192. $options{subdir} = 1;
  193. if (-d $ARGV[0]) {
  194. $options{destdir} = shift(@ARGV);
  195. }
  196. } elsif (m/^-o|--overwrite$/) {
  197. $options{overwite} = 1;
  198. } elsif (m/^-k|--symlink$/) {
  199. $options{symlink} = 1;
  200. } elsif (m/^-a|--no-architecture$/) {
  201. $options{architecture} = 0;
  202. } elsif (m/^--$/) {
  203. foreach (@ARGV) {
  204. move($_);
  205. }
  206. exit 0;
  207. } else {
  208. move($_);
  209. }
  210. }
  211. 0;