/contrib/cvs/contrib/rcslock.in

https://bitbucket.org/freebsd/freebsd-head/ · Autoconf · 265 lines · 99 code · 51 blank · 115 comment · 27 complexity · 0ce83d1ed2dc2d37a1f6354d15406a6d MD5 · raw file

  1. #! @PERL@ -T
  2. # -*-Perl-*-
  3. # Copyright (C) 1994-2005 The Free Software Foundation, Inc.
  4. # This program is free software; you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation; either version 2, or (at your option)
  7. # any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. ###############################################################################
  14. ###############################################################################
  15. ###############################################################################
  16. #
  17. # THIS SCRIPT IS PROBABLY BROKEN. REMOVING THE -T SWITCH ON THE #! LINE ABOVE
  18. # WOULD FIX IT, BUT THIS IS INSECURE. WE RECOMMEND FIXING THE ERRORS WHICH THE
  19. # -T SWITCH WILL CAUSE PERL TO REPORT BEFORE RUNNING THIS SCRIPT FROM A CVS
  20. # SERVER TRIGGER. PLEASE SEND PATCHES CONTAINING THE CHANGES YOU FIND
  21. # NECESSARY TO RUN THIS SCRIPT WITH THE TAINT-CHECKING ENABLED BACK TO THE
  22. # <@PACKAGE_BUGREPORT@> MAILING LIST.
  23. #
  24. # For more on general Perl security and taint-checking, please try running the
  25. # `perldoc perlsec' command.
  26. #
  27. ###############################################################################
  28. ###############################################################################
  29. ###############################################################################
  30. # Author: John Rouillard (rouilj@cs.umb.edu)
  31. # Supported: Yeah right. (Well what do you expect for 2 hours work?)
  32. # Blame-to: rouilj@cs.umb.edu
  33. # Complaints to: Anybody except Brian Berliner, he's blameless for
  34. # this script.
  35. # Acknowlegements: The base code for this script has been acquired
  36. # from the log.pl script.
  37. # rcslock.pl - A program to prevent commits when a file to be ckecked
  38. # in is locked in the repository.
  39. # There are times when you need exclusive access to a file. This
  40. # often occurs when binaries are checked into the repository, since
  41. # cvs's (actually rcs's) text based merging mechanism won't work. This
  42. # script allows you to use the rcs lock mechanism (rcs -l) to make
  43. # sure that no changes to a repository are able to be committed if
  44. # those changes would result in a locked file being changed.
  45. # WARNING:
  46. # This script will work only if locking is set to strict.
  47. #
  48. # Setup:
  49. # Add the following line to the commitinfo file:
  50. # ALL /local/location/for/script/lockcheck [options]
  51. # Where ALL is replaced by any suitable regular expression.
  52. # Options are -v for verbose info, or -d for debugging info.
  53. # The %s will provide the repository directory name and the names of
  54. # all changed files.
  55. # Use:
  56. # When a developer needs exclusive access to a version of a file, s/he
  57. # should use "rcs -l" in the repository tree to lock the version they
  58. # are working on. CVS will automagically release the lock when the
  59. # commit is performed.
  60. # Method:
  61. # An "rlog -h" is exec'ed to give info on all about to be
  62. # committed files. This (header) information is parsed to determine
  63. # if any locks are outstanding and what versions of the file are
  64. # locked. This filename, version number info is used to index an
  65. # associative array. All of the files to be committed are checked to
  66. # see if any locks are outstanding. If locks are outstanding, the
  67. # version number of the current file (taken from the CVS/Entries
  68. # subdirectory) is used in the key to determine if that version is
  69. # locked. If the file being checked in is locked by the person doing
  70. # the checkin, the commit is allowed, but if the lock is held on that
  71. # version of a file by another person, the commit is not allowed.
  72. $ext = ",v"; # The extension on your rcs files.
  73. $\="\n"; # I hate having to put \n's at the end of my print statements
  74. $,=' '; # Spaces should occur between arguments to print when printed
  75. # turn off setgid
  76. #
  77. $) = $(;
  78. #
  79. # parse command line arguments
  80. #
  81. require 'getopts.pl';
  82. &Getopts("vd"); # verbose or debugging
  83. # Verbose is useful when debugging
  84. $opt_v = $opt_d if defined $opt_d;
  85. # $files[0] is really the name of the subdirectory.
  86. # @files = split(/ /,$ARGV[0]);
  87. @files = @ARGV[0..$#ARGV];
  88. $cvsroot = $ENV{'CVSROOT'};
  89. #
  90. # get login name
  91. #
  92. $login = getlogin || (getpwuid($<))[0] || "nobody";
  93. #
  94. # save the current directory since we have to return here to parse the
  95. # CVS/Entries file if a lock is found.
  96. #
  97. $pwd = `/bin/pwd`;
  98. chop $pwd;
  99. print "Starting directory is $pwd" if defined $opt_d ;
  100. #
  101. # cd to the repository directory and check on the files.
  102. #
  103. print "Checking directory ", $files[0] if defined $opt_v ;
  104. if ( $files[0] =~ /^\// )
  105. {
  106. print "Directory path is $files[0]" if defined $opt_d ;
  107. chdir $files[0] || die "Can't change to repository directory $files[0]" ;
  108. }
  109. else
  110. {
  111. print "Directory path is $cvsroot/$files[0]" if defined $opt_d ;
  112. chdir ($cvsroot . "/" . $files[0]) ||
  113. die "Can't change to repository directory $files[0] in $cvsroot" ;
  114. }
  115. # Open the rlog process and apss all of the file names to that one
  116. # process to cut down on exec overhead. This may backfire if there
  117. # are too many files for the system buffer to handle, but if there are
  118. # that many files, chances are that the cvs repository is not set up
  119. # cleanly.
  120. print "opening rlog -h @files[1..$#files] |" if defined $opt_d;
  121. open( RLOG, "rlog -h @files[1..$#files] |") || die "Can't run rlog command" ;
  122. # Create the locks associative array. The elements in the array are
  123. # of two types:
  124. #
  125. # The name of the RCS file with a value of the total number of locks found
  126. # for that file,
  127. # or
  128. #
  129. # The name of the rcs file concatenated with the version number of the lock.
  130. # The value of this element is the name of the locker.
  131. # The regular expressions used to split the rcs info may have to be changed.
  132. # The current ones work for rcs 5.6.
  133. $lock = 0;
  134. while (<RLOG>)
  135. {
  136. chop;
  137. next if /^$/; # ditch blank lines
  138. if ( $_ =~ /^RCS file: (.*)$/ )
  139. {
  140. $curfile = $1;
  141. next;
  142. }
  143. if ( $_ =~ /^locks: strict$/ )
  144. {
  145. $lock = 1 ;
  146. next;
  147. }
  148. if ( $lock )
  149. {
  150. # access list: is the line immediately following the list of locks.
  151. if ( /^access list:/ )
  152. { # we are done getting lock info for this file.
  153. $lock = 0;
  154. }
  155. else
  156. { # We are accumulating lock info.
  157. # increment the lock count
  158. $locks{$curfile}++;
  159. # save the info on the version that is locked. $2 is the
  160. # version number $1 is the name of the locker.
  161. $locks{"$curfile" . "$2"} = $1
  162. if /[ ]*([a-zA-Z._]*): ([0-9.]*)$/;
  163. print "lock by $1 found on $curfile version $2" if defined $opt_d;
  164. }
  165. }
  166. }
  167. # Lets go back to the starting directory and see if any locked files
  168. # are ones we are interested in.
  169. chdir $pwd;
  170. # fo all of the file names (remember $files[0] is the directory name
  171. foreach $i (@files[1..$#files])
  172. {
  173. if ( defined $locks{$i . $ext} )
  174. { # well the file has at least one lock outstanding
  175. # find the base version number of our file
  176. &parse_cvs_entry($i,*entry);
  177. # is our version of this file locked?
  178. if ( defined $locks{$i . $ext . $entry{"version"}} )
  179. { # if so, it is by us?
  180. if ( $login ne ($by = $locks{$i . $ext . $entry{"version"}}) )
  181. {# crud somebody else has it locked.
  182. $outstanding_lock++ ;
  183. print "$by has file $i locked for version " , $entry{"version"};
  184. }
  185. else
  186. { # yeah I have it locked.
  187. print "You have a lock on file $i for version " , $entry{"version"}
  188. if defined $opt_v;
  189. }
  190. }
  191. }
  192. }
  193. exit $outstanding_lock;
  194. ### End of main program
  195. sub parse_cvs_entry
  196. { # a very simple minded hack at parsing an entries file.
  197. local ( $file, *entry ) = @_;
  198. local ( @pp );
  199. open(ENTRIES, "< CVS/Entries") || die "Can't open entries file";
  200. while (<ENTRIES>)
  201. {
  202. if ( $_ =~ /^\/$file\// )
  203. {
  204. @pp = split('/');
  205. $entry{"name"} = $pp[1];
  206. $entry{"version"} = $pp[2];
  207. $entry{"dates"} = $pp[3];
  208. $entry{"name"} = $pp[4];
  209. $entry{"name"} = $pp[5];
  210. $entry{"sticky"} = $pp[6];
  211. return;
  212. }
  213. }
  214. }