PageRenderTime 61ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/dirvish_1_3_ds/dirvish-locate.pl

https://bitbucket.org/dirvish/dirvish
Perl | 264 lines | 179 code | 30 blank | 55 comment | 19 complexity | ef453b0251cc62a632903ed175a5ae2f MD5 | raw file
  1. #!/usr/bin/perl
  2. # dirvish-locate
  3. # 1.3.X series
  4. # Copyright 2005 by the dirvish project
  5. # http://www.dirvish.org
  6. #
  7. # Last Revision : $Rev: 650 $
  8. # Revision date : $Date: 2009-02-04 16:09:41 +0100 (Mi, 04 Feb 2009) $
  9. # Last Changed by : $Author: tex $
  10. # Stored as : $HeadURL: https://secure.id-schulz.info/svn/tex/priv/dirvish_1_3_1/dirvish-locate.pl $
  11. #
  12. #########################################################################
  13. # #
  14. # Licensed under the Open Software License version 2.0 #
  15. # #
  16. # This program is free software; you can redistribute it #
  17. # and/or modify it under the terms of the Open Software #
  18. # License, version 2.0 by Lauwrence E. Rosen. #
  19. # #
  20. # This program is distributed in the hope that it will be #
  21. # useful, but WITHOUT ANY WARRANTY; without even the implied #
  22. # warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR #
  23. # PURPOSE. See the Open Software License for details. #
  24. # #
  25. #########################################################################
  26. #
  27. #----------------------------------------------------------------------------
  28. # Revision information
  29. #----------------------------------------------------------------------------
  30. my %CodeID = (
  31. Rev => '$Rev: 650 $' ,
  32. Date => '$Date: 2009-02-04 16:09:41 +0100 (Mi, 04 Feb 2009) $' ,
  33. Author => '$Author: tex $' ,
  34. URL => '$HeadURL: https://secure.id-schulz.info/svn/tex/priv/dirvish_1_3_1/dirvish-locate.pl $' ,
  35. );
  36. $VERSION = $CodeID{URL};
  37. $VERSION =~ s#^.*dirvish_##; # strip off the front
  38. $VERSION =~ s#\/.*##; # strip off the rear after the last /
  39. $VERSION =~ s#[_-]#.#g; # _ or - to "."
  40. #----------------------------------------------------------------------------
  41. # Modules and includes
  42. #----------------------------------------------------------------------------
  43. use strict;
  44. use warnings;
  45. use Time::ParseDate;
  46. use POSIX qw(strftime);
  47. use Getopt::Long;
  48. use Dirvish;
  49. #----------------------------------------------------------------------------
  50. # SIG Handler
  51. #----------------------------------------------------------------------------
  52. $SIG{TERM} = \&sigterm; # handles "kill <PID>"
  53. $SIG{INT} = \&sigterm; # handles Ctrl+C or "kill -2 <PID>"
  54. #----------------------------------------------------------------------------
  55. # Initialisation
  56. #----------------------------------------------------------------------------
  57. my $KILLCOUNT = 1000;
  58. my $MAXCOUNT = 100;
  59. my $Options = reset_options( \&usage, @ARGV); # initialize the %$Options hash
  60. load_master_config('f', $Options); # load master config into $Options
  61. GetOptions($Options, qw(
  62. version
  63. help|?
  64. )) or &usage();
  65. my $Vault = shift;
  66. my $Branch = undef;
  67. $Vault =~ /:/ and ($Vault, $Branch) = split(/:/, $Vault);
  68. my $Pattern = shift;
  69. $Vault && length($Pattern) or &usage();
  70. # prepend dot if asterisk or question mark is
  71. # the first character. Make rsync-like patterns like *.xml work
  72. $Pattern = ".".$Pattern if($Pattern =~ m/^(\*|\?)/);
  73. my $fullpattern = $Pattern;
  74. my $partpattern = undef;
  75. $fullpattern =~ /\$$/ or $fullpattern .= '[^/]*$';
  76. ($partpattern = $fullpattern) =~ s/^\^//;
  77. my $bank = undef;
  78. for $b (@{$$Options{bank}})
  79. {
  80. -d "$b/$Vault" and $bank = $b;
  81. }
  82. $bank or seppuku 220, "No such vault: $Vault";
  83. opendir VAULT, "$bank/$Vault" or seppuku 221, "cannot open vault: $Vault";
  84. my @invault = readdir(VAULT);
  85. closedir VAULT;
  86. my @images = ();
  87. for my $image (@invault)
  88. {
  89. $image eq 'dirvish' and next;
  90. my $imdir = "$bank/$Vault/$image";
  91. -f "$imdir/summary" or next;
  92. (-l $imdir && $imdir =~ /current/) and next; # skip current-symlink
  93. my $conf = loadconfig('R', "$imdir/summary", $Options) or next;
  94. $$conf{Status} eq 'success' || $$conf{Status} =~ /^warn/
  95. or next;
  96. $$conf{'Backup-complete'} or next;
  97. $Branch && $$conf{branch} ne $Branch and next;
  98. unshift @images, {
  99. imdir => $imdir,
  100. image => $$conf{Image},
  101. branch => $$conf{branch},
  102. created => $$conf{'Backup-complete'},
  103. }
  104. }
  105. my $imagecount = 0;
  106. my $pathcount = 0;
  107. my $path = undef;
  108. my %match = ();
  109. for my $image (sort(imsort_locate @images))
  110. {
  111. my $imdir = $$image{imdir};
  112. my $index = undef;
  113. -f "$imdir/index.bz2" and $index = "bzip2 -d -c $imdir/index.bz2|";
  114. -f "$imdir/index.gz" and $index = "gzip -d -c $imdir/index|";
  115. -f "$imdir/index" and $index = "<$imdir/index";
  116. $index or next;
  117. ++$imagecount;
  118. # can't use three-fold open here, see above
  119. open(INDEX, $index) or next;
  120. while (<INDEX>)
  121. {
  122. chomp;
  123. m($partpattern) or next;
  124. # this parse operation is too slow. It might be faster as a
  125. # split with trimmed leading whitespace and remerged modtime
  126. my $f = { image => $image };
  127. (
  128. $$f{inode},
  129. $$f{blocks},
  130. $$f{perms},
  131. $$f{links},
  132. $$f{owner},
  133. $$f{group},
  134. $$f{bytes},
  135. $$f{mtime},
  136. $path
  137. ) = m<^
  138. \s*(\S+) # inode
  139. \s+(\S+) # block count
  140. \s+(\S+) # perms
  141. \s+(\S+) # link count
  142. \s+(\S+) # owner
  143. \s+(\S+) # group
  144. \s+(\S+) # byte count
  145. \s+(\S+\s+\S+\s+\S+) # date
  146. \s+(\S.*) # path
  147. $>x;
  148. $$f{perms} =~ /^[dl]/ and next;
  149. $path =~ m($fullpattern) or next;
  150. exists($match{$path}) or ++$pathcount;
  151. push @{$match{$path}}, $f;
  152. }
  153. if ($pathcount >= $KILLCOUNT)
  154. {
  155. print "dirvish-locate: too many paths match pattern, interrupting search\n";
  156. last;
  157. }
  158. }
  159. printf "%d matches in %d images\n", $pathcount, $imagecount;
  160. $pathcount >= $MAXCOUNT
  161. and printf "Pattern '%s' too vague, listing paths only.\n", $Pattern;
  162. my $last = undef;
  163. my $linesize = 0;
  164. for my $path (sort(keys(%match)))
  165. {
  166. $last = undef;
  167. print $path;
  168. if ($pathcount >= $MAXCOUNT)
  169. {
  170. print "\n";
  171. next;
  172. }
  173. for my $hit (@{$match{$path}})
  174. {
  175. my $inode = $$hit{inode};
  176. my $mtime = $$hit{mtime};
  177. my $image = $$hit{image}{image};
  178. if (defined($last) && $inode ne $last)
  179. {
  180. $linesize = 5 + length($mtime) + length($image);
  181. printf "\n %s %s", $mtime, $image;
  182. } else {
  183. $linesize += length($image) + 2;
  184. if ($linesize > 78)
  185. {
  186. $linesize = 5 + length($mtime) + length($image);
  187. print "\n",
  188. " " x (5 + length($mtime)),
  189. $image;
  190. } else {
  191. printf ", %s", $$hit{image}{image};
  192. }
  193. }
  194. $last = $inode;
  195. }
  196. print "\n\n";
  197. }
  198. exit 0;
  199. #----------------------------------------------------------------------------
  200. # Subs
  201. #----------------------------------------------------------------------------
  202. # Sort images
  203. sub imsort_locate {
  204. ## WARNING: don't mess with the sort order, it is needed so that if
  205. ## WARNING: all images are expired the newest will be retained.
  206. $$a{branch} cmp $$b{branch}
  207. || $$a{created} cmp $$b{created};
  208. }
  209. sub usage
  210. {
  211. my $message = shift(@_);
  212. length($message) and print STDERR $message, "\n\n";
  213. print STDERR <<EOUSAGE;
  214. USAGE
  215. dirvish-locate vault[:branch] pattern
  216. Pattern can be any PCRE.
  217. EOUSAGE
  218. exit 255;
  219. }
  220. # Handle SIGTERM (SIG-15)
  221. sub sigterm
  222. {
  223. print STDERR "Received SIGTERM. Aborting running backup ...";
  224. # kill childs - kill(TERM, -$$):
  225. use POSIX;
  226. my $cnt = kill(SIGTERM, -$$);
  227. no POSIX;
  228. print STDERR "Signaled $cnt processes in current processgroup";
  229. # quit
  230. exit;
  231. }
  232. #----------------------------------------------------------------------------
  233. # EOF
  234. #----------------------------------------------------------------------------