#!/usr/bin/perl -w # #Copyright (c) 2009, Perforce Software, Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #******************************************************************************* # #Author: Stephen Moon # #Program: symCheck.pl # This is a sample symlink detection script which accounts for a submission of file which # creates a directory that is the same name as the symoblic link at the same # tree depth. # #Trigger table entry: # # symCheck change-submit //depot/... "/path/to/your/script/symCheck.pl %change% %user% %serverport% %client%" # use strict; my $cl = $ARGV[0]; my $user = $ARGV[1]; my $serverPort = $ARGV[2]; my $client = $ARGV[3]; my $debug = 1; #change it to "1" if you want to see debug output if(-f "symcheck.log") { unlink "symcheck.log"; } my $p4 = "p4 -u $user -p $serverPort -c $client"; foreach(`$p4 opened -c $cl`) { chomp; if(/^(\/\/\w+)\/(.*)\/(.*)\/(.*)\#([0-9]*) - (add|branch|import) .* \((.*)\) .*$/) { my $depot = $1; #depot name including "//" my $file_path = "$2/$3"; #filepath before the filename my $file_name = $4; my $file_rev = $5; my $file_action = $6; my $file_type = $7; my @tokens = split/\//,$file_path; my $count = 0; foreach my $eachToken (@tokens) { if($debug == 1) { print "$file_name: $eachToken "; } $count += 1; $depot = &process_files($eachToken,$depot,$count,\@tokens,$1,$file_type,$file_name); } } } sub process_files { my $path = shift; #each token of the filepath my $depot = shift; #new filepath my $count = shift; #count of tokenizing my $tokens_ref = shift; #reference to tokenized strings of the filepath my $cdepot = shift; #static depot path my $file_type = shift; my $file_name = shift; my $cpath = ""; #directory path to compare against symbolic link of same name if($debug == 1) { print "\nPATH: $depot\/$path\n"; } my $ncount = 0; foreach my $eachToken (@$tokens_ref) { chomp; print "$ncount: $eachToken\n"; if($count+1 > $ncount) { $cpath .= "/" . $eachToken; $ncount += 1; } } #checks for the case where file being added is a symbolic link and a directory #which is the same name as the symbolic link file which is present. if($file_type eq "symlink") { foreach(`$p4 dirs $depot/$path/* 2>> symcheck.log`) { chomp; if($debug == 1) { print "dirs: $_\n"; print "depot: $depot, path: $path, cpath: $cpath\n"; } &check_dir($_,$cdepot . $cpath . "/" . $file_name); } } #checks to see whether a directory which is the same name as the symbolic link is #being created. foreach(`$p4 files $depot/$path/* 2>>symcheck.log`) { chomp; &check_symlink($_,$cdepot . $cpath); } $depot = $depot . '/' . $path; #p4 depot appended with each directory token return $depot; } sub check_symlink { my $eachFile = shift; #output of "p4 files" for each tree level my $dir_path = shift; #corresponding dir_path for the file being submitted if($eachFile =~ /^(.*)\/(.*)\#([0-9]*) .* \((symlink)\)$/) { if($debug == 1) { print "Full_path: $eachFile\n"; print "Path: $1\n"; print "File: $2\n"; print "Revision: $3\n"; print "FileType: $4\n"; } my $symlink = $1 . "/" . $2; if($debug == 1) { print "symlink: $symlink\n"; print "dirpath: $dir_path\n"; } if($dir_path eq $symlink) { print "\"$2\" directory name being created for the submission of $symlink" . "\n"; print "is the same name as \"$2\" which is a $4 for file $symlink\n"; exit 1; } } } sub check_dir { my $symlink = shift; #output of "p4 dirs" for each path my $dir_path = shift; #symbolic link filename which is being submitted if($debug == 1) { print "symlink: $symlink\n"; print "dirpath: $dir_path\n"; } if($dir_path eq $symlink) { print "\"$dir_path\" file name being created for the submission of $dir_path" . "\n"; print "is the same name as \"$symlink\" which is a directory\n"; exit 1; } }