%PDF- %PDF-
| Direktori : /proc/self/root/data/old/home/stash/bin/git-hooks/ |
| Current File : //proc/self/root/data/old/home/stash/bin/git-hooks/hook-callback.pl |
#!/usr/bin/env perl
#>*******************************************************
# THIS FILE WAS AUTO-GENERATED BY ATLASSIAN STASH.
# IT CONTAINS NO USER-SERVICEABLE PARTS.
#>*******************************************************
# Perl script should be placed in ${stash.home}/bin/git-hooks. This script opens a socket connection to Stash and
# facilitates RPC for hook callbacks.
#
# When Stash calls out to the SCM, it sets the following environment variables:
# - STASH_HOOK_ADDRESS: which IP address Stash is listening on (specific address for these callbacks)
# - STASH_HOOK_PORT: which port Stash is listening on (specific port for these callbacks)
# - STASH_HOOK_REQUEST_ID: an identifier that Stash can use to determine which request the callback applies to
use IO::Socket;
use Encode;
# Utility functions to match the Java counterparts on DataInputStream and DataOutputStream
sub writeUnsignedShort {
my ($out, $short) = @_;
my $packed = pack('n', $short);
print $out $packed;
}
sub writeUTF {
my ($out, $chunk) = @_;
my $packed = Encode::encode_utf8($chunk);
writeUnsignedShort($out, length($packed));
print $out $packed;
}
sub readUnsignedShort {
my ($in) = @_;
read($in, my $packed, 2);
return unpack('n', $packed);
}
sub readUTF {
my ($in) = @_;
my $length = readUnsignedShort($in);
read($in, my $packed, $length);
my $unpacked = Encode::decode_utf8($packed);
return $unpacked;
}
# Open a socket back to the Stash server. This will be used to send and receive information about
# the hook via a channel based protocol
my $socket = new IO::Socket::INET (
PeerAddr => $ENV{'STASH_HOOK_ADDRESS'},
PeerPort => $ENV{'STASH_HOOK_PORT'},
Proto => 'tcp');
die "Could not create socket to ping Stash: $!\n" unless $socket;
# Write inputs over socket.
# Ensure raw (binary) output
binmode($socket, ':raw');
# first write the REQUEST ID
print $socket 'X';
writeUTF($socket, $ENV{'STASH_HOOK_REQUEST_ID'});
# then write the hook type
print $socket 'T';
writeUTF($socket, $ARGV[0]);
shift @ARGV;
# then write the args
foreach (@ARGV) {
# don't be lame, give $_ a name
local $arg = $_;
print $socket 'A';
writeUTF($socket, $arg);
}
# then copy STDIN to the socket, ensuring UTF8 encoding is used
my ($stdInChunk, $n);
binmode(STDIN, ":utf8");
while (($n = read(STDIN, $stdInChunk, 8192)) != 0) {
print $socket 'I';
writeUTF($socket, $stdInChunk);
}
# Signify that this is the end of the clients communication
print $socket 'E';
# Read channels from socket
# Ensure UTF8 on stdout/err
binmode(STDOUT, ":utf8");
binmode(STDERR, ":utf8");
my $exitCode = 0;
while (True) {
read($socket, my $c, 1);
if ($c eq "O") {
# STDOUT channel. Read the next chunk and write it to STDOUT
print STDOUT readUTF($socket);
next;
} elsif ($c eq "E") {
# STDERR channel. Read the next chunk and write it to STDERR
print STDERR readUTF($socket);
next;
} elsif ($c eq "X") {
# Exit code channel. Read short and use it to exit
$exitCode = readUnsignedShort($socket);
last;
} else {
# The server isn't giving back valid data. Bail
print STDOUT "Communication breakdown with Stash.\n";
$exitCode = 1;
last;
}
}
# close the socket
close($socket);
# finally exit with the correct status code
exit $exitCode