chkstow.in 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #!@PERL@
  2. #
  3. # This file is part of GNU Stow.
  4. #
  5. # GNU Stow is free software: you can redistribute it and/or modify it
  6. # under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # GNU Stow is distributed in the hope that it will be useful, but
  11. # WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. # General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see https://www.gnu.org/licenses/.
  17. use strict;
  18. use warnings;
  19. require 5.006_001;
  20. use File::Find;
  21. use Getopt::Long;
  22. my $DEFAULT_TARGET = $ENV{STOW_DIR} || '/usr/local/';
  23. our $Wanted = \&bad_links;
  24. our %Package = ();
  25. our $Stow_dir = '';
  26. our $Target = $DEFAULT_TARGET;
  27. # put the main loop into a block so that tests can load this as a module
  28. if ( not caller() ) {
  29. if (@ARGV == 0) {
  30. usage();
  31. }
  32. process_options();
  33. #check_stow($Target, $Wanted);
  34. check_stow();
  35. }
  36. sub process_options {
  37. GetOptions(
  38. 'b|badlinks' => sub { $Wanted = \&bad_links },
  39. 'a|aliens' => sub { $Wanted = \&aliens },
  40. 'l|list' => sub { $Wanted = \&list },
  41. 't|target=s' => \$Target,
  42. ) or usage();
  43. return;
  44. }
  45. sub usage {
  46. print <<"EOT";
  47. USAGE: chkstow [options]
  48. Options:
  49. -t DIR, --target=DIR Set the target directory to DIR
  50. (default is $DEFAULT_TARGET)
  51. -b, --badlinks Report symlinks that point to non-existent files
  52. -a, --aliens Report non-symlinks in the target directory
  53. -l, --list List packages in the target directory
  54. --badlinks is the default mode.
  55. EOT
  56. exit(0);
  57. }
  58. sub check_stow {
  59. #my ($Target, $Wanted) = @_;
  60. my (%options) = (
  61. wanted => $Wanted,
  62. preprocess => \&skip_dirs,
  63. );
  64. find(\%options, $Target);
  65. if ($Wanted == \&list) {
  66. delete $Package{''};
  67. delete $Package{'..'};
  68. if (keys %Package) {
  69. print map "$_\n", sort(keys %Package);
  70. }
  71. }
  72. return;
  73. }
  74. sub skip_dirs {
  75. # skip stow source and unstowed targets
  76. if (-e ".stow" || -e ".notstowed" ) {
  77. warn "skipping $File::Find::dir\n";
  78. return ();
  79. }
  80. else {
  81. return @_;
  82. }
  83. }
  84. # checking for files that do not link to anything
  85. sub bad_links {
  86. -l && !-e && print "Bogus link: $File::Find::name\n";
  87. }
  88. # checking for files that are not owned by stow
  89. sub aliens {
  90. !-l && !-d && print "Unstowed file: $File::Find::name\n";
  91. }
  92. # just list the packages in the target directory
  93. # FIXME: what if the stow dir is not called 'stow'?
  94. sub list {
  95. if (-l) {
  96. $_ = readlink;
  97. s{\A(?:\.\./)+stow/}{}g;
  98. s{/.*}{}g;
  99. $Package{$_} = 1;
  100. }
  101. }
  102. 1; # Hey, it's a module!
  103. # Local variables:
  104. # mode: perl
  105. # cperl-indent-level: 4
  106. # End:
  107. # vim: ft=perl