#!/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;
}
}