controllib.pl 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use English;
  5. use POSIX qw(:errno_h);
  6. use Dpkg;
  7. push(@INC,$dpkglibdir);
  8. require 'dpkg-gettext.pl';
  9. textdomain("dpkg-dev");
  10. our $sourcepackage; # - name of sourcepackage
  11. our %f; # - fields ???
  12. our %fi; # - map of fields values. keys are of the form "S# key"
  13. # where S is source (L is changelog, C is control)
  14. # and # is an index
  15. our %fieldimps;
  16. our %p2i; # - map from datafile+packagename to index in controlfile
  17. # (used if multiple packages can be listed). Key is
  18. # "S key" where S is the source and key is the packagename
  19. my $maxsubsts = 50;
  20. our %substvar; # - map with substitution variables
  21. my $parsechangelog = 'dpkg-parsechangelog';
  22. our @pkg_dep_fields = qw(Pre-Depends Depends Recommends Suggests Enhances
  23. Conflicts Replaces Provides);
  24. our @src_dep_fields = qw(Build-Depends Build-Depends-Indep
  25. Build-Conflicts Build-Conflicts-Indep);
  26. our $warnable_error = 1;
  27. our $quiet_warnings = 0;
  28. sub getfowner
  29. {
  30. my $getlogin = getlogin();
  31. if (!defined($getlogin)) {
  32. open(SAVEIN, "<&STDIN");
  33. open(STDIN, "<&STDERR");
  34. $getlogin = getlogin();
  35. close(STDIN);
  36. open(STDIN, "<&SAVEIN");
  37. close(SAVEIN);
  38. }
  39. if (!defined($getlogin)) {
  40. open(SAVEIN, "<&STDIN");
  41. open(STDIN, "<&STDOUT");
  42. $getlogin = getlogin();
  43. close(STDIN);
  44. open(STDIN, "<&SAVEIN");
  45. close(SAVEIN);
  46. }
  47. my @fowner;
  48. if (defined($ENV{'LOGNAME'})) {
  49. @fowner = getpwnam($ENV{'LOGNAME'});
  50. if (!@fowner) {
  51. die(sprintf(_g('unable to get login information for username "%s"'), $ENV{'LOGNAME'}));
  52. }
  53. } elsif (defined($getlogin)) {
  54. @fowner = getpwnam($getlogin);
  55. if (!@fowner) {
  56. die(sprintf(_g('unable to get login information for username "%s"'), $getlogin));
  57. }
  58. } else {
  59. warning(sprintf(_g('no utmp entry available and LOGNAME not defined; using uid of process (%d)'), $<));
  60. @fowner = getpwuid($<);
  61. if (!@fowner) {
  62. die (sprintf(_g('unable to get login information for uid %d'), $<));
  63. }
  64. }
  65. @fowner = @fowner[2,3];
  66. return @fowner;
  67. }
  68. sub capit {
  69. my @pieces = map { ucfirst(lc) } split /-/, $_[0];
  70. return join '-', @pieces;
  71. }
  72. #
  73. # Architecture library
  74. #
  75. my (@cpu, @os);
  76. my (%cputable, %ostable);
  77. my (%cputable_re, %ostable_re);
  78. my %debtriplet_to_debarch;
  79. my %debarch_to_debtriplet;
  80. {
  81. my $host_arch;
  82. sub get_host_arch()
  83. {
  84. return $host_arch if defined $host_arch;
  85. $host_arch = `dpkg-architecture -qDEB_HOST_ARCH`;
  86. $? && subprocerr("dpkg-architecture -qDEB_HOST_ARCH");
  87. chomp $host_arch;
  88. return $host_arch;
  89. }
  90. }
  91. sub get_valid_arches()
  92. {
  93. read_cputable() if (!@cpu);
  94. read_ostable() if (!@os);
  95. foreach my $os (@os) {
  96. foreach my $cpu (@cpu) {
  97. my $arch = debtriplet_to_debarch(split(/-/, $os, 2), $cpu);
  98. print $arch."\n" if defined($arch);
  99. }
  100. }
  101. }
  102. sub read_cputable
  103. {
  104. local $_;
  105. open CPUTABLE, "$pkgdatadir/cputable"
  106. or syserr(_g("unable to open cputable"));
  107. while (<CPUTABLE>) {
  108. if (m/^(?!\#)(\S+)\s+(\S+)\s+(\S+)/) {
  109. $cputable{$1} = $2;
  110. $cputable_re{$1} = $3;
  111. push @cpu, $1;
  112. }
  113. }
  114. close CPUTABLE;
  115. }
  116. sub read_ostable
  117. {
  118. local $_;
  119. open OSTABLE, "$pkgdatadir/ostable"
  120. or syserr(_g("unable to open ostable"));
  121. while (<OSTABLE>) {
  122. if (m/^(?!\#)(\S+)\s+(\S+)\s+(\S+)/) {
  123. $ostable{$1} = $2;
  124. $ostable_re{$1} = $3;
  125. push @os, $1;
  126. }
  127. }
  128. close OSTABLE;
  129. }
  130. sub read_triplettable()
  131. {
  132. read_cputable() if (!@cpu);
  133. local $_;
  134. open TRIPLETTABLE, "$pkgdatadir/triplettable"
  135. or syserr(_g("unable to open triplettable"));
  136. while (<TRIPLETTABLE>) {
  137. if (m/^(?!\#)(\S+)\s+(\S+)/) {
  138. my $debtriplet = $1;
  139. my $debarch = $2;
  140. if ($debtriplet =~ /<cpu>/) {
  141. foreach my $_cpu (@cpu) {
  142. (my $dt = $debtriplet) =~ s/<cpu>/$_cpu/;
  143. (my $da = $debarch) =~ s/<cpu>/$_cpu/;
  144. $debarch_to_debtriplet{$da} = $dt;
  145. $debtriplet_to_debarch{$dt} = $da;
  146. }
  147. } else {
  148. $debarch_to_debtriplet{$2} = $1;
  149. $debtriplet_to_debarch{$1} = $2;
  150. }
  151. }
  152. }
  153. close TRIPLETTABLE;
  154. }
  155. sub debtriplet_to_gnutriplet(@)
  156. {
  157. read_cputable() if (!@cpu);
  158. read_ostable() if (!@os);
  159. my ($abi, $os, $cpu) = @_;
  160. return undef unless defined($abi) && defined($os) && defined($cpu) &&
  161. exists($cputable{$cpu}) && exists($ostable{"$abi-$os"});
  162. return join("-", $cputable{$cpu}, $ostable{"$abi-$os"});
  163. }
  164. sub gnutriplet_to_debtriplet($)
  165. {
  166. my ($gnu) = @_;
  167. return undef unless defined($gnu);
  168. my ($gnu_cpu, $gnu_os) = split(/-/, $gnu, 2);
  169. return undef unless defined($gnu_cpu) && defined($gnu_os);
  170. read_cputable() if (!@cpu);
  171. read_ostable() if (!@os);
  172. my ($os, $cpu);
  173. foreach my $_cpu (@cpu) {
  174. if ($gnu_cpu =~ /^$cputable_re{$_cpu}$/) {
  175. $cpu = $_cpu;
  176. last;
  177. }
  178. }
  179. foreach my $_os (@os) {
  180. if ($gnu_os =~ /^(.*-)?$ostable_re{$_os}$/) {
  181. $os = $_os;
  182. last;
  183. }
  184. }
  185. return undef if !defined($cpu) || !defined($os);
  186. return (split(/-/, $os, 2), $cpu);
  187. }
  188. sub debtriplet_to_debarch(@)
  189. {
  190. read_triplettable() if (!%debtriplet_to_debarch);
  191. my ($abi, $os, $cpu) = @_;
  192. if (!defined($abi) || !defined($os) || !defined($cpu)) {
  193. return undef;
  194. } elsif (exists $debtriplet_to_debarch{"$abi-$os-$cpu"}) {
  195. return $debtriplet_to_debarch{"$abi-$os-$cpu"};
  196. } else {
  197. return undef;
  198. }
  199. }
  200. sub debarch_to_debtriplet($)
  201. {
  202. read_triplettable() if (!%debarch_to_debtriplet);
  203. local ($_) = @_;
  204. my $arch;
  205. # FIXME: 'any' is handled here, to be able to do debarch_eq('any', foo).
  206. if (/^any$/ || /^all$/) {
  207. return ($_, $_, $_);
  208. } elsif (/^linux-([^-]*)/) {
  209. # XXX: Might disappear in the future, not sure yet.
  210. $arch = $1;
  211. } else {
  212. $arch = $_;
  213. }
  214. my $triplet = $debarch_to_debtriplet{$arch};
  215. if (defined($triplet)) {
  216. return split('-', $triplet, 3);
  217. } else {
  218. return undef;
  219. }
  220. }
  221. sub debwildcard_to_debtriplet($)
  222. {
  223. local ($_) = @_;
  224. if (/any/) {
  225. if (/^([^-]*)-([^-]*)-(.*)/) {
  226. return ($1, $2, $3);
  227. } elsif (/^([^-]*)-([^-]*)$/) {
  228. return ('any', $1, $2);
  229. } else {
  230. return ($_, $_, $_);
  231. }
  232. } else {
  233. return debarch_to_debtriplet($_);
  234. }
  235. }
  236. sub debarch_eq($$)
  237. {
  238. my ($a, $b) = @_;
  239. my @a = debarch_to_debtriplet($a);
  240. my @b = debarch_to_debtriplet($b);
  241. return 0 if grep(!defined, (@a, @b));
  242. return ($a[0] eq $b[0] && $a[1] eq $b[1] && $a[2] eq $b[2]);
  243. }
  244. sub debarch_is($$)
  245. {
  246. my ($real, $alias) = @_;
  247. my @real = debarch_to_debtriplet($real);
  248. my @alias = debwildcard_to_debtriplet($alias);
  249. return 0 if grep(!defined, (@real, @alias));
  250. if (($alias[0] eq $real[0] || $alias[0] eq 'any') &&
  251. ($alias[1] eq $real[1] || $alias[1] eq 'any') &&
  252. ($alias[2] eq $real[2] || $alias[2] eq 'any')) {
  253. return 1;
  254. }
  255. return 0;
  256. }
  257. sub substvars {
  258. my ($v) = @_;
  259. my $lhs;
  260. my $vn;
  261. my $rhs = '';
  262. my $count = 0;
  263. while ($v =~ m/\$\{([-:0-9a-z]+)\}/i) {
  264. # If we have consumed more from the leftover data, then
  265. # reset the recursive counter.
  266. $count= 0 if (length($POSTMATCH) < length($rhs));
  267. $count < $maxsubsts ||
  268. &error(sprintf(_g("too many substitutions - recursive ? - in \`%s'"), $v));
  269. $lhs=$`; $vn=$1; $rhs=$';
  270. if (defined($substvar{$vn})) {
  271. $v= $lhs.$substvar{$vn}.$rhs;
  272. $count++;
  273. } else {
  274. warning(sprintf(_g("unknown substitution variable \${%s}"), $vn));
  275. $v= $lhs.$rhs;
  276. }
  277. }
  278. return $v;
  279. }
  280. sub set_field_importance(@)
  281. {
  282. my @fields = @_;
  283. my $i = 1;
  284. grep($fieldimps{$_} = $i++, @fields);
  285. }
  286. sub sort_field_by_importance($$)
  287. {
  288. my ($a, $b) = @_;
  289. if (defined $fieldimps{$a} && defined $fieldimps{$b}) {
  290. $fieldimps{$a} <=> $fieldimps{$b};
  291. } elsif (defined($fieldimps{$a})) {
  292. -1;
  293. } elsif (defined($fieldimps{$b})) {
  294. 1;
  295. } else {
  296. $a cmp $b;
  297. }
  298. }
  299. sub outputclose {
  300. my ($varlistfile) = @_;
  301. for my $f (keys %f) {
  302. $substvar{"F:$f"} = $f{$f};
  303. }
  304. &parsesubstvars($varlistfile) if (defined($varlistfile));
  305. for my $f (sort sort_field_by_importance keys %f) {
  306. my $v = $f{$f};
  307. if (defined($varlistfile)) {
  308. $v= &substvars($v);
  309. }
  310. $v =~ m/\S/ || next; # delete whitespace-only fields
  311. $v =~ m/\n\S/ && &internerr(sprintf(_g("field %s has newline then non whitespace >%s<"), $f, $v));
  312. $v =~ m/\n[ \t]*\n/ && &internerr(sprintf(_g("field %s has blank lines >%s<"), $f, $v));
  313. $v =~ m/\n$/ && &internerr(sprintf(_g("field %s has trailing newline >%s<"), $f, $v));
  314. if (defined($varlistfile)) {
  315. $v =~ s/,[\s,]*,/,/g;
  316. $v =~ s/^\s*,\s*//;
  317. $v =~ s/\s*,\s*$//;
  318. }
  319. $v =~ s/\$\{\}/\$/g;
  320. print("$f: $v\n") || &syserr(_g("write error on control data"));
  321. }
  322. close(STDOUT) || &syserr(_g("write error on close control data"));
  323. }
  324. sub parsecontrolfile {
  325. my $controlfile = shift;
  326. $controlfile="./$controlfile" if $controlfile =~ m/^\s/;
  327. open(CDATA,"< $controlfile") || &error(sprintf(_g("cannot read control file %s: %s"), $controlfile, $!));
  328. binmode(CDATA);
  329. my $indices = parsecdata(\*CDATA, 'C', 1,
  330. sprintf(_g("control file %s"), $controlfile));
  331. $indices >= 2 || &error(_g("control file must have at least one binary package part"));
  332. for (my $i = 1; $i < $indices; $i++) {
  333. defined($fi{"C$i Package"}) ||
  334. &error(sprintf(_g("per-package paragraph %d in control ".
  335. "info file is missing Package line"),
  336. $i));
  337. }
  338. defined($fi{"C Source"}) ||
  339. &error(_g("source paragraph in control info file is ".
  340. "missing Source line"));
  341. }
  342. my $substvarsparsed = 0;
  343. sub parsesubstvars {
  344. my $varlistfile = shift;
  345. if (length($varlistfile) && !$substvarsparsed) {
  346. $varlistfile="./$varlistfile" if $varlistfile =~ m/\s/;
  347. if (open(SV,"< $varlistfile")) {
  348. binmode(SV);
  349. while (<SV>) {
  350. next if m/^\#/ || !m/\S/;
  351. s/\s*\n$//;
  352. m/^(\w[-:0-9A-Za-z]*)\=/ ||
  353. &error(sprintf(_g("bad line in substvars file %s at line %d"),
  354. $varlistfile, $.));
  355. $substvar{$1}= $';
  356. }
  357. close(SV);
  358. } elsif ($! != ENOENT ) {
  359. &error(sprintf(_g("unable to open substvars file %s: %s"),
  360. $varlistfile, $!));
  361. }
  362. $substvarsparsed = 1;
  363. }
  364. }
  365. sub parsedep {
  366. my ($dep_line, $use_arch, $reduce_arch) = @_;
  367. my @dep_list;
  368. my $host_arch = get_host_arch();
  369. foreach my $dep_and (split(/,\s*/m, $dep_line)) {
  370. my @or_list = ();
  371. ALTERNATE:
  372. foreach my $dep_or (split(/\s*\|\s*/m, $dep_and)) {
  373. my ($package, $relation, $version);
  374. $package = $1 if ($dep_or =~ s/^([a-zA-Z0-9][a-zA-Z0-9+._-]*)\s*//m);
  375. ($relation, $version) = ($1, $2)
  376. if ($dep_or =~ s/^\(\s*(=|<=|>=|<<?|>>?)\s*([^)]+).*\)\s*//m);
  377. my @arches;
  378. @arches = split(/\s+/m, $1) if ($use_arch && $dep_or =~ s/^\[([^]]+)\]\s*//m);
  379. if ($reduce_arch && @arches) {
  380. my $seen_arch='';
  381. foreach my $arch (@arches) {
  382. $arch=lc($arch);
  383. if ($arch =~ /^!/) {
  384. my $not_arch;
  385. ($not_arch = $arch) =~ s/^!//;
  386. if (debarch_is($host_arch, $not_arch)) {
  387. next ALTERNATE;
  388. } else {
  389. # This is equivilant to
  390. # having seen the current arch,
  391. # unless the current arch
  392. # is also listed..
  393. $seen_arch=1;
  394. }
  395. } elsif (debarch_is($host_arch, $arch)) {
  396. $seen_arch=1;
  397. next;
  398. }
  399. }
  400. if (! $seen_arch) {
  401. next;
  402. }
  403. }
  404. if (length($dep_or)) {
  405. warning(sprintf(_g("can't parse dependency %s"), $dep_and));
  406. return undef;
  407. }
  408. push @or_list, [ $package, $relation, $version, \@arches ];
  409. }
  410. push @dep_list, \@or_list;
  411. }
  412. \@dep_list;
  413. }
  414. sub showdep {
  415. my ($dep_list, $show_arch) = @_;
  416. my @and_list;
  417. foreach my $dep_and (@$dep_list) {
  418. my @or_list = ();
  419. foreach my $dep_or (@$dep_and) {
  420. my ($package, $relation, $version, $arch_list) = @$dep_or;
  421. push @or_list, $package . ($relation && $version ? " ($relation $version)" : '') . ($show_arch && @$arch_list ? " [@$arch_list]" : '');
  422. }
  423. push @and_list, join(' | ', @or_list);
  424. }
  425. join(', ', @and_list);
  426. }
  427. sub parsechangelog {
  428. my ($changelogfile, $changelogformat, $since) = @_;
  429. defined(my $c = open(CDATA, "-|")) || syserr(_g("fork for parse changelog"));
  430. if ($c) {
  431. binmode(CDATA);
  432. parsecdata(\*CDATA, 'L', 0, _g("parsed version of changelog"));
  433. close(CDATA);
  434. $? && subprocerr(_g("parse changelog"));
  435. } else {
  436. binmode(STDOUT);
  437. my @al = ($parsechangelog);
  438. push(@al,"-l$changelogfile");
  439. push(@al, "-F$changelogformat") if defined($changelogformat);
  440. push(@al, "-v$since") if defined($since);
  441. exec(@al) || &syserr("exec parsechangelog $parsechangelog");
  442. }
  443. }
  444. sub init_substvars
  445. {
  446. $substvar{'Format'} = 1.7;
  447. $substvar{'Newline'} = "\n";
  448. $substvar{'Space'} = " ";
  449. $substvar{'Tab'} = "\t";
  450. # XXX: Source-Version is now deprecated, remove in the future.
  451. $substvar{'Source-Version'}= $fi{"L Version"};
  452. $substvar{'binary:Version'} = $fi{"L Version"};
  453. $substvar{'source:Version'} = $fi{"L Version"};
  454. $substvar{'source:Version'} =~ s/\+b[0-9]+$//;
  455. $substvar{'source:Upstream-Version'} = $fi{"L Version"};
  456. $substvar{'source:Upstream-Version'} =~ s/-[^-]*$//;
  457. $substvar{"dpkg:Version"} = $version;
  458. $substvar{"dpkg:Upstream-Version"} = $version;
  459. $substvar{"dpkg:Upstream-Version"} =~ s/-[^-]+$//;
  460. }
  461. sub init_substvar_arch()
  462. {
  463. $substvar{'Arch'} = get_host_arch();
  464. }
  465. sub checkpackagename {
  466. my $name = shift || '';
  467. $name =~ m/[^-+.0-9a-z]/o &&
  468. &error(sprintf(_g("source package name `%s' contains illegal character `%s'"), $name, $&));
  469. $name =~ m/^[0-9a-z]/o ||
  470. &error(sprintf(_g("source package name `%s' starts with non-alphanum"), $name));
  471. }
  472. sub checkversion {
  473. my $version = shift || '';
  474. $version =~ m/[^-+:.0-9a-zA-Z~]/o &&
  475. &error(sprintf(_g("version number contains illegal character `%s'"), $&));
  476. }
  477. sub setsourcepackage {
  478. my $v = shift;
  479. checkpackagename( $v );
  480. if (defined($sourcepackage)) {
  481. $v eq $sourcepackage ||
  482. &error(sprintf(_g("source package has two conflicting values - %s and %s"), $sourcepackage, $v));
  483. } else {
  484. $sourcepackage= $v;
  485. }
  486. }
  487. sub readmd5sum {
  488. (my $md5sum = shift) or return;
  489. $md5sum =~ s/^([0-9a-f]{32})\s*\*?-?\s*\n?$/$1/o
  490. || &failure(sprintf(_g("md5sum gave bogus output `%s'"), $md5sum));
  491. return $md5sum;
  492. }
  493. # XXX: Should not be a global!!
  494. my $whatmsg;
  495. sub parsecdata {
  496. my ($cdata, $source, $many);
  497. ($cdata, $source, $many, $whatmsg) = @_;
  498. # many=0: ordinary control data like output from dpkg-parsechangelog
  499. # many=1: many paragraphs like in source control file
  500. # many=-1: single paragraph of control data optionally signed
  501. my $index = '';
  502. my $cf = '';
  503. my $paraborder = 1;
  504. while (<$cdata>) {
  505. s/\s*\n$//;
  506. next if (m/^$/ and $paraborder);
  507. next if (m/^#/);
  508. $paraborder=0;
  509. if (m/^(\S+)\s*:\s*(.*)$/) {
  510. $cf = $1;
  511. my $v = $2;
  512. $cf= &capit($cf);
  513. $fi{"$source$index $cf"}= $v;
  514. $fi{"o:$source$index $cf"}= $1;
  515. if (lc $cf eq 'package') { $p2i{"$source $v"}= $index; }
  516. } elsif (m/^\s+\S/) {
  517. length($cf) || &syntax(_g("continued value line not in field"));
  518. $fi{"$source$index $cf"}.= "\n$_";
  519. } elsif (m/^-----BEGIN PGP/ && $many<0) {
  520. $many == -2 && syntax(_g("expected blank line before PGP signature"));
  521. while (<$cdata>) {
  522. last if m/^$/;
  523. }
  524. $many= -2;
  525. } elsif (m/^$/) {
  526. $paraborder = 1;
  527. if ($many>0) {
  528. $index++; $cf='';
  529. } elsif ($many == -2) {
  530. $_ = <$cdata> while defined($_) && $_ =~ /^\s*$/;
  531. length($_) ||
  532. &syntax(_g("expected PGP signature, found EOF after blank line"));
  533. s/\n$//;
  534. m/^-----BEGIN PGP/ ||
  535. &syntax(sprintf(_g("expected PGP signature, found something else \`%s'"), $_));
  536. $many= -3; last;
  537. } else {
  538. while (<$cdata>) {
  539. /^\s*$/ ||
  540. &syntax(_g("found several \`paragraphs' where only one expected"));
  541. }
  542. }
  543. } else {
  544. &syntax(_g("line with unknown format (not field-colon-value)"));
  545. }
  546. }
  547. $many == -2 && &syntax(_g("found start of PGP body but no signature"));
  548. if (length($cf)) { $index++; }
  549. $index || &syntax(_g("empty file"));
  550. return $index;
  551. }
  552. sub unknown {
  553. my $field = $_;
  554. warning(sprintf(_g("unknown information field '%s' in input data in %s"),
  555. $field, $_[0]));
  556. }
  557. sub syntax {
  558. &error(sprintf(_g("syntax error in %s at line %d: %s"), $whatmsg, $., $_[0]));
  559. }
  560. sub failure { die sprintf(_g("%s: failure: %s"), $progname, $_[0])."\n"; }
  561. sub syserr { die sprintf(_g("%s: failure: %s: %s"), $progname, $_[0], $!)."\n"; }
  562. sub error { die sprintf(_g("%s: error: %s"), $progname, $_[0])."\n"; }
  563. sub internerr { die sprintf(_g("%s: internal error: %s"), $progname, $_[0])."\n"; }
  564. sub warning
  565. {
  566. if (!$quiet_warnings) {
  567. warn sprintf(_g("%s: warning: %s"), $progname, $_[0])."\n";
  568. }
  569. }
  570. sub usageerr
  571. {
  572. printf(STDERR "%s: %s\n\n", $progname, "@_");
  573. &usage;
  574. exit(2);
  575. }
  576. sub warnerror
  577. {
  578. if ($warnable_error) {
  579. warning(@_);
  580. } else {
  581. error(@_);
  582. }
  583. }
  584. sub subprocerr {
  585. my ($p) = @_;
  586. require POSIX;
  587. if (POSIX::WIFEXITED($?)) {
  588. die sprintf(_g("%s: failure: %s gave error exit status %s"),
  589. $progname, $p, POSIX::WEXITSTATUS($?))."\n";
  590. } elsif (POSIX::WIFSIGNALED($?)) {
  591. die sprintf(_g("%s: failure: %s died from signal %s"),
  592. $progname, $p, POSIX::WTERMSIG($?))."\n";
  593. } else {
  594. die sprintf(_g("%s: failure: %s failed with unknown exit code %d"),
  595. $progname, $p, $?)."\n";
  596. }
  597. }
  598. 1;