Index: gs2-extensions/parallel-building/trunk/src/perllib/FileUtils/HDThriftFS.pm
===================================================================
--- gs2-extensions/parallel-building/trunk/src/perllib/FileUtils/HDThriftFS.pm	(revision 27423)
+++ gs2-extensions/parallel-building/trunk/src/perllib/FileUtils/HDThriftFS.pm	(revision 27424)
@@ -69,4 +69,5 @@
 my $host = "localhost";
 my $port = 58660;
+my $debug = 0;
 my $debug_encoding = 0;
 
@@ -108,5 +109,5 @@
     if ($@)
     {
-      &_printError('Unable to connect: ' . $@->{message}, 1);
+      &FileUtils::printError('Unable to connect: ' . $@->{message}, 1);
     }
   }
@@ -135,4 +136,17 @@
 ## _generateHDFSPath()
 
+
+## @function _printDebug()
+#
+sub _printDebug
+{
+  my ($msg) = @_;
+  if ($debug)
+  {
+    my ($package, $filename, $line, $function) = caller(1);
+    print STDERR '[DEBUG] ' . $function . ': ' . $msg . "\n";
+  }
+}
+## _printDebug()
 
 ################################################################################
@@ -141,4 +155,98 @@
 
 
+## @function canRead()
+#
+sub canRead
+{
+  my $path = shift(@_);
+  return &checkPermission($path, 'r', @_);
+}
+## canRead()
+
+
+## @function checkPermission()
+#
+sub checkPermission
+{
+  my ($path, $mode, $username, $usergroup) = @_;
+  my $offsets = {'r' => 0, 'w' => 1, 'x' => 2};
+  # - ensure we have a connection to the thrift server
+  &_establishClient();
+  # - convert the path into a proper thrift path object
+  $path = &_generateHDFSPath($path);
+  # - determine the user (defaults to current user)
+  if (!defined $username)
+  {
+    if ($ENV{'GSDLOS'} =~ /^windows$/i)
+    {
+      require Win32;
+      $username = Win32::LoginName();
+    }
+    else
+    {
+      $username = getlogin || getpwuid($<);
+    }
+  }
+  # - determine the group
+  my $usergroups = {};
+  if (defined $usergroup)
+  {
+    $usergroups = (ref $usergroup eq "HASH") ? $usergroup : {$usergroup => 1};
+  }
+  else
+  {
+    if ($ENV{'GSDLOS'} =~ /^windows$/i)
+    {
+      # dunno
+    }
+    else
+    {
+      my $raw_groups = `groups`;
+      foreach my $group ( split(/\s/, $raw_groups))
+      {
+        $usergroups->{$group} = 1;
+      }
+    }
+  }
+  # Retrieve details from the file
+  my $file_stat = $thrift_client->stat($path);
+  my $owner = $file_stat->{'owner'};
+  my $group = $file_stat->{'group'};
+  my $permissions = $file_stat->{'permission'};
+  # Begin the cascade of tests to determine if the identified user belonging to
+  # the identified group can perform 'mode' access to the file.
+  my $has_permission = 0;
+  # - start with [u]ser permission
+  if (defined $owner && $username eq $owner)
+  {
+    my $target_char = substr($permissions, $offsets->{$mode}, 1);
+    if ($mode eq $target_char)
+    {
+      $has_permission = 1;
+    }
+  }
+  # - failing that, try [g]roup level permissions
+  if (!$has_permission && defined $group && defined $usergroups->{$group})
+  {
+    my $target_char = substr($permissions, 3 + $offsets->{$mode}, 1);
+    if ($mode eq $target_char)
+    {
+      $has_permission = 1;
+    }
+  }
+  # - and finally try [o]ther level permission
+  if (!$has_permission)
+  {
+    my $target_char = substr($permissions, 6 + $offsets->{$mode}, 1);
+    if ($mode eq $target_char)
+    {
+      $has_permission = 1;
+    }
+  }
+  return $has_permission;
+}
+## checkPermission
+
+
 ## @function closeFileHandle()
 #
@@ -146,4 +254,5 @@
 {
   my $fh_ref = shift(@_);
+  &_printDebug('');
   close($$fh_ref);
   untie($$fh_ref);
@@ -238,4 +347,14 @@
 
 
+## @function isFilenameAbsolute()
+#
+sub isFilenameAbsolute
+{
+  # File paths against HDFS must be.
+  return 1;
+}
+# isFilenameAbsolute()
+
+
 ## @function makeDirectory()
 #
@@ -279,4 +398,5 @@
 {
   my ($raw_path, $mode, $fh_ref) = @_;
+  &_printDebug('path: ' . $raw_path . ', mode: ' . $mode . ', fh_ref');
   # ensure we have a connection to the thrift server
   &_establishClient();
