dpkg-statoverride.pl 5.0 KB

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