dpkg-statoverride.pl 4.8 KB

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