@ -1,5 +1,5 @@
/ *
/ *
* Copyright ( C ) 2008 - 2009 , Google Inc .
* Copyright ( C ) 2008 - 201 0 , Google Inc .
* Copyright ( C ) 2008 , Marek Zawirski < marek . zawirski @gmail.com >
* Copyright ( C ) 2008 , Marek Zawirski < marek . zawirski @gmail.com >
* Copyright ( C ) 2008 , Robin Rosenberg < robin . rosenberg @dewire.com >
* Copyright ( C ) 2008 , Robin Rosenberg < robin . rosenberg @dewire.com >
* Copyright ( C ) 2008 , Shawn O . Pearce < spearce @spearce.org >
* Copyright ( C ) 2008 , Shawn O . Pearce < spearce @spearce.org >
@ -127,13 +127,7 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
cmd . append ( QuotedString . BOURNE . quote ( val ) ) ;
cmd . append ( QuotedString . BOURNE . quote ( val ) ) ;
}
}
private String commandFor ( final String exe ) {
ChannelExec exec ( final String exe ) throws TransportException {
initSession ( ) ;
final int tms = getTimeout ( ) > 0 ? getTimeout ( ) * 1000 : 0 ;
try {
final ChannelExec channel = ( ChannelExec ) sock . openChannel ( "exec" ) ;
String path = uri . getPath ( ) ;
String path = uri . getPath ( ) ;
if ( uri . getScheme ( ) ! = null & & uri . getPath ( ) . startsWith ( "/~" ) )
if ( uri . getScheme ( ) ! = null & & uri . getPath ( ) . startsWith ( "/~" ) )
path = ( uri . getPath ( ) . substring ( 1 ) ) ;
path = ( uri . getPath ( ) . substring ( 1 ) ) ;
@ -148,7 +142,16 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
sqMinimal ( cmd , exe ) ;
sqMinimal ( cmd , exe ) ;
cmd . append ( ' ' ) ;
cmd . append ( ' ' ) ;
sqAlways ( cmd , path ) ;
sqAlways ( cmd , path ) ;
channel . setCommand ( cmd . toString ( ) ) ;
return cmd . toString ( ) ;
}
ChannelExec exec ( final String exe ) throws TransportException {
initSession ( ) ;
final int tms = getTimeout ( ) > 0 ? getTimeout ( ) * 1000 : 0 ;
try {
final ChannelExec channel = ( ChannelExec ) sock . openChannel ( "exec" ) ;
channel . setCommand ( commandFor ( exe ) ) ;
errStream = createErrorStream ( ) ;
errStream = createErrorStream ( ) ;
channel . setErrStream ( errStream , true ) ;
channel . setErrStream ( errStream , true ) ;
channel . connect ( tms ) ;
channel . connect ( tms ) ;
@ -158,6 +161,17 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
}
}
}
}
void checkExecFailure ( int status , String exe ) throws TransportException {
if ( status = = 127 ) {
String why = errStream . toString ( ) ;
IOException cause = null ;
if ( why ! = null & & why . length ( ) > 0 )
cause = new IOException ( why ) ;
throw new TransportException ( uri , "cannot execute: "
+ commandFor ( exe ) , cause ) ;
}
}
/ * *
/ * *
* @return the error stream for the channel , the stream is used to detect
* @return the error stream for the channel , the stream is used to detect
* specific error reasons for exceptions .
* specific error reasons for exceptions .
@ -305,6 +319,8 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
class SshFetchConnection extends BasePackFetchConnection {
class SshFetchConnection extends BasePackFetchConnection {
private ChannelExec channel ;
private ChannelExec channel ;
private int exitStatus ;
SshFetchConnection ( ) throws TransportException {
SshFetchConnection ( ) throws TransportException {
super ( TransportGitSsh . this ) ;
super ( TransportGitSsh . this ) ;
try {
try {
@ -327,6 +343,8 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
try {
try {
readAdvertisedRefs ( ) ;
readAdvertisedRefs ( ) ;
} catch ( NoRemoteRepositoryException notFound ) {
} catch ( NoRemoteRepositoryException notFound ) {
close ( ) ;
checkExecFailure ( exitStatus , getOptionUploadPack ( ) ) ;
throw cleanNotFound ( notFound ) ;
throw cleanNotFound ( notFound ) ;
}
}
}
}
@ -337,6 +355,7 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
if ( channel ! = null ) {
if ( channel ! = null ) {
try {
try {
exitStatus = channel . getExitStatus ( ) ;
if ( channel . isConnected ( ) )
if ( channel . isConnected ( ) )
channel . disconnect ( ) ;
channel . disconnect ( ) ;
} finally {
} finally {
@ -349,6 +368,8 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
class SshPushConnection extends BasePackPushConnection {
class SshPushConnection extends BasePackPushConnection {
private ChannelExec channel ;
private ChannelExec channel ;
private int exitStatus ;
SshPushConnection ( ) throws TransportException {
SshPushConnection ( ) throws TransportException {
super ( TransportGitSsh . this ) ;
super ( TransportGitSsh . this ) ;
try {
try {
@ -371,6 +392,8 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
try {
try {
readAdvertisedRefs ( ) ;
readAdvertisedRefs ( ) ;
} catch ( NoRemoteRepositoryException notFound ) {
} catch ( NoRemoteRepositoryException notFound ) {
close ( ) ;
checkExecFailure ( exitStatus , getOptionReceivePack ( ) ) ;
throw cleanNotFound ( notFound ) ;
throw cleanNotFound ( notFound ) ;
}
}
}
}
@ -381,6 +404,7 @@ public class TransportGitSsh extends SshTransport implements PackTransport {
if ( channel ! = null ) {
if ( channel ! = null ) {
try {
try {
exitStatus = channel . getExitStatus ( ) ;
if ( channel . isConnected ( ) )
if ( channel . isConnected ( ) )
channel . disconnect ( ) ;
channel . disconnect ( ) ;
} finally {
} finally {