#!/usr/bin/perl -w
#
# Script to print out "shared, shared with exemptions and unshared" files in VSS
# Uses VSS OLE Automation
# Documentation on VSS Object Model can be found at:
# http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvss/html/msdn_vssole.asp
#
# Written by Robert Cowham (rc@vaccaperna.co.uk)
# Usual disclaimers apply!
# Unshared and Shared Exempt options added + minor syntax error corrected by Nic Morling (23 Feb 05)
require 5.0;
use strict;
use integer;
use Time::Local;
use Win32::OLE;
use Win32::OLE qw(in);
use Win32::OLE::Const;
use Win32::OLE::Variant;
my $USAGE = "VSS Path argument required: [vssdir]\ne.g.\n $0 \"\$/Project 1/subdir\" Note Case sensitive\n";
my $root = $ARGV[0];
die($USAGE) if !(defined($root));
# Load up VSS Ole Automation
my $VSSDB = Win32::OLE->new('SourceSafe', 'Quit');
my $consts = Win32::OLE::Const->Load($VSSDB);
# Declare the Username, password and SourceSafe path variables
# For now these are hardcoded
my $UserName = "";
my $Password = "";
my $SrcSafeIni = "U:\\SourceSafe\\SRCSAFE.INI";
my $ShowLinked = "True"; #set to True or "" for unlinked files : Added by Nic Morling
my $ExemptLink = ""; # set to string to exempt or "" for all links: Added by Nic Morling
if (! $ShowLinked) { $ExemptLink = undef;} # ExemptLink must be undef if showing unlinked files
$VSSDB->Open($SrcSafeIni, $UserName, $Password);
my $VSSRoot = $VSSDB->VSSItem($root, 0);
if (!$VSSRoot) {
die "Error finding directory \"$root\"\n";
}
&vss_dir_tree($root);
# Recurse down the list of VSS directories looking for linked files
sub vss_dir_tree
{
my $rt = shift;
my $root = $VSSDB->VSSItem($rt, 0);
if (!$root) {
print "Error checking directory: $rt\n";
return;
}
my $items = $root->Items(0);
my $item;
my $dir;
foreach $item (in $items) {
if ($item->Type == $consts->{VSSITEM_PROJECT}) {
$dir = $item->Name;
&vss_dir_tree("$rt/$dir");
}
else {
&linked_file("$rt/".$item->Name);
}
}
}
# File Version Info
sub linked_file
{
my $file = shift;
my $item = $VSSDB->VSSItem($file, 0);
if (!$item) {
print "Error Checking $file\n";
return;
}
my $versions = $item->Versions;
my $link;
my @links;
foreach $link (in $item->Links) {
if ($link->Spec ne $item->Spec) { # Every item is linked to itself
if (! $ExemptLink) { # use this loop if we want all links: Added by Nic Morling
push @links, $link->Spec;
} else { # use this loop if we want to exempt some links: Added by Nic Morling
$_=$link->Spec;
if (! /$ExemptLink/i) {
push @links, $link->Spec;
}
}
}
}
# Amended by Nic Morling to display linked or unlinked files
if ($ShowLinked) {
if (@links > 0) {
print "File: ".$item->Spec." linked to:\n";
foreach $link (@links) {
print " $link\n";
}
print "\n";
}
} else {
if (! @links > 0) { # only output the current file if it is not shared
print "Unlinked file = ".$item->Spec."\n";
}
}
}