dpkg-statoverride.pl 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #! /usr/bin/perl
  2. use POSIX;
  3. use POSIX qw(:errno_h :signal_h);
  4. $admindir= "/var/lib/dpkg"; # This line modified by Makefile
  5. $version= '1.3.0'; # This line modified by Makefile
  6. my $dpkglibdir= "."; # This line modified by Makefile
  7. push (@INC, $dpkglibdir);
  8. require 'dpkg-gettext.pl';
  9. textdomain("dpkg");
  10. $verbose= 1;
  11. $doforce= 0;
  12. $doupdate= 0;
  13. $mode= "";
  14. sub UsageVersion {
  15. printf(STDERR _g(<<EOF), $version) || &quit(sprintf(_g("failed to write usage: %s"), $!));
  16. Debian dpkg-statoverride %s.
  17. Copyright (C) 2000 Wichert Akkerman.
  18. This is free software; see the GNU General Public Licence version 2 or later
  19. for copying conditions. There is NO warranty.
  20. Usage:
  21. dpkg-statoverride [options] --add <owner> <group> <mode> <file>
  22. dpkg-statoverride [options] --remove <file>
  23. dpkg-statoverride [options] --list [<glob-pattern>]
  24. Options:
  25. --update immediately update file permissions
  26. --force force an action even if a sanity check fails
  27. --quiet quiet operation, minimal output
  28. --help print this help screen and exit
  29. --admindir <directory> set the directory with the statoverride file
  30. EOF
  31. }
  32. sub CheckModeConflict {
  33. return unless $mode;
  34. &badusage("two modes specified: $_ and --$mode");
  35. }
  36. while (@ARGV) {
  37. $_=shift(@ARGV);
  38. last if m/^--$/;
  39. if (!m/^-/) {
  40. unshift(@ARGV,$_); last;
  41. } elsif (m/^--help$/) {
  42. &UsageVersion; exit(0);
  43. } elsif (m/^--update$/) {
  44. $doupdate=1;
  45. } elsif (m/^--quiet$/) {
  46. $verbose=0;
  47. } elsif (m/^--force$/) {
  48. $doforce=1;
  49. } elsif (m/^--admindir$/) {
  50. @ARGV || &badusage(_g("--admindir needs a directory argument"));
  51. $admindir= shift(@ARGV);
  52. } elsif (m/^--add$/) {
  53. &CheckModeConflict;
  54. $mode= 'add';
  55. } elsif (m/^--remove$/) {
  56. &CheckModeConflict;
  57. $mode= 'remove';
  58. } elsif (m/^--list$/) {
  59. &CheckModeConflict;
  60. $mode= 'list';
  61. } else {
  62. &badusage(sprintf(_g("unknown option \`%s'"), $_));
  63. }
  64. }
  65. $dowrite=0;
  66. $exitcode=0;
  67. &badusage(_g("no mode specified")) unless $mode;
  68. &ReadOverrides;
  69. if ($mode eq "add") {
  70. @ARGV==4 || &badusage(_g("--add needs four arguments"));
  71. $user=$ARGV[0];
  72. if ($user =~ m/^#([0-9]+)$/) {
  73. $uid=$1;
  74. &badusage(sprintf(_g("illegal user %s"), $user)) if ($uid<0);
  75. } else {
  76. (($name,$pw,$uid)=getpwnam($user)) || &badusage(sprintf(_g("non-existing user %s"), $user));
  77. }
  78. $group=$ARGV[1];
  79. if ($group =~ m/^#([0-9]+)$/) {
  80. $gid=$1;
  81. &badusage(sprintf(_g("illegal group %s"), $group)) if ($gid<0);
  82. } else {
  83. (($name,$pw,$gid)=getgrnam($group)) || &badusage(sprintf(_g("non-existing group %s"), $group));
  84. }
  85. $mode= $ARGV[2];
  86. (($mode<0) or (oct($mode)>07777) or ($mode !~ m/\d+/)) && &badusage(sprintf(_g("illegal mode %s"), $mode));
  87. $file= $ARGV[3];
  88. $file =~ m/\n/ && &badusage(_g("file may not contain newlines"));
  89. $file =~ s,/+$,, && print STDERR _g("stripping trailing /")."\n";
  90. if (defined $owner{$file}) {
  91. printf STDERR _g("An override for \"%s\" already exists, "), $file;
  92. if ($doforce) {
  93. print STDERR _g("but --force specified so lets ignore it.")."\n";
  94. } else {
  95. print STDERR _g("aborting")."\n";
  96. exit(3);
  97. }
  98. }
  99. $owner{$file}=$user;
  100. $group{$file}=$group;
  101. $mode{$file}=$mode;
  102. $dowrite=1;
  103. if ($doupdate) {
  104. if (not -e $file) {
  105. printf STDERR _g("warning: --update given but %s does not exist")."\n", $file;
  106. } else {
  107. chown ($uid,$gid,$file) || warn sprintf(_g("failed to chown %s: %s"), $file, $!)."\n";
  108. chmod (oct($mode),$file) || warn sprintf(_g("failed to chmod %s: %s"), $file, $!)."\n";
  109. }
  110. }
  111. } elsif ($mode eq "remove") {
  112. @ARGV==1 || &badusage(_g("--remove needs one arguments"));
  113. $file=$ARGV[0];
  114. $file =~ s,/+$,, && print STDERR _g("stripping trailing /")."\n";
  115. if (not defined $owner{$file}) {
  116. print STDERR _g("No override present.")."\n";
  117. exit(0) if ($doforce);
  118. exit(2);
  119. }
  120. delete $owner{$file};
  121. delete $group{$file};
  122. delete $mode{$file};
  123. $dowrite=1;
  124. print(STDERR _g("warning: --update is useless for --remove")."\n") if ($doupdate);
  125. } elsif ($mode eq "list") {
  126. my (@list,@ilist,$pattern,$file);
  127. @ilist= @ARGV ? @ARGV : ('*');
  128. while (defined($_=shift(@ilist))) {
  129. s/\W/\\$&/g;
  130. s/\\\?/./g;
  131. s/\\\*/.*/g;
  132. s,/+$,, && print STDERR _g("stripping trailing /")."\n";
  133. push(@list,"^$_\$");
  134. }
  135. $pat= join('|',@list);
  136. $exitcode=1;
  137. for $file (keys %owner) {
  138. next unless ($file =~ m/$pat/o);
  139. $exitcode=0;
  140. print "$owner{$file} $group{$file} $mode{$file} $file\n";
  141. }
  142. }
  143. &WriteOverrides if ($dowrite);
  144. exit($exitcode);
  145. sub ReadOverrides {
  146. open(SO,"$admindir/statoverride") || &quit(sprintf(_g("cannot open statoverride: %s"), $!));
  147. while (<SO>) {
  148. my ($owner,$group,$mode,$file);
  149. chomp;
  150. ($owner,$group,$mode,$file)=split(' ', $_, 4);
  151. die sprintf(_g("Multiple overrides for \"%s\", aborting"), $file)
  152. if defined $owner{$file};
  153. $owner{$file}=$owner;
  154. $group{$file}=$group;
  155. $mode{$file}=$mode;
  156. }
  157. close(SO);
  158. }
  159. sub WriteOverrides {
  160. my ($file);
  161. open(SO,">$admindir/statoverride-new") || &quit(sprintf(_g("cannot open new statoverride file: %s"), $!));
  162. foreach $file (keys %owner) {
  163. print SO "$owner{$file} $group{$file} $mode{$file} $file\n";
  164. }
  165. close(SO);
  166. chmod(0644, "$admindir/statoverride-new");
  167. unlink("$admindir/statoverride-old") ||
  168. $! == ENOENT || &quit(sprintf(_g("error removing statoverride-old: %s"), $!));
  169. link("$admindir/statoverride","$admindir/statoverride-old") ||
  170. $! == ENOENT || &quit(sprintf(_g("error creating new statoverride-old: %s"), $!));
  171. rename("$admindir/statoverride-new","$admindir/statoverride")
  172. || &quit(sprintf(_g("error installing new statoverride: %s"), $!));
  173. }
  174. sub quit { printf STDERR _g("dpkg-statoverride: %s")."\n", "@_"; exit(2); }
  175. sub badusage { printf STDERR _g("dpkg-statoverride: %s")."\n\n", "@_"; print(_g("You need --help.")."\n"); exit(2); }
  176. # vi: ts=8 sw=8 ai si cindent