Files
2016-09-15 10:13:52 -05:00

157 lines
4.2 KiB
Objective-C
Executable File

//
// sshOperator.m
// sshtest
//
// Created by Daniel Finneran on 23/10/2011.
// Copyright 2011 Home. All rights reserved.
//
#import "DFSSHOperator.h"
#import "libssh2.h"
LIBSSH2_CHANNEL *channel;
unsigned long rc;
int exitcode;
@implementation DFSSHOperator
- (id)init
{
self = [super init];
if (self) {
// Initialization code here.
}
return self;
}
static int waitsocket(int socket_fd, LIBSSH2_SESSION *session)
{
// Variable Declarations
struct timeval timeout;
fd_set fd;
fd_set *writefd = NULL;
fd_set *readfd = NULL;
int rc;
int dir;
// Wait time in Seconds
timeout.tv_sec = 0;
// Wait time in Microseconds... (really need that level of granularity :/ )
timeout.tv_usec = 500000;
FD_ZERO(&fd);
FD_SET(socket_fd, &fd);
/* now make sure we wait in the correct direction */
dir = libssh2_session_block_directions(session);
if(dir & LIBSSH2_SESSION_BLOCK_INBOUND)
readfd = &fd;
if(dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
writefd = &fd;
rc = select(socket_fd + 1, readfd, writefd, NULL, &timeout);
return rc;
}
// Timer driven exec
+(NSString*) execCommand:(NSString *)commandline server:(DFSSHServer*)server {
return [self execCommand:commandline server:server timeout:[NSNumber numberWithDouble:1]];
}
// from libssh2 example - ssh2_exec.c
+(NSString*) execCommand:(NSString *)commandline server:(DFSSHServer*)server timeout:(NSNumber *)timeout {
int bytecount = 0; /*wrap up in a function*/
CFAbsoluteTime time;
time = CFAbsoluteTimeGetCurrent() + [timeout doubleValue];
if (![server connectionStatus])
return @"No Connection";
const char * cmd = [commandline UTF8String];
if (!cmd)
return @"";
char buffer[0x4000];
//Clear buffer
memset(buffer, 0, 0x4000);
/* Exec non-blocking on the remote host */
channel = libssh2_channel_open_session([server session]);
int sessionError = libssh2_session_last_error([server session],NULL,NULL,0);
while( channel == NULL && sessionError == LIBSSH2_ERROR_EAGAIN )
{
waitsocket([server sock], [server session]);
// Testing Methods
if (time < CFAbsoluteTimeGetCurrent())
break;
// NSLog(@"%d", sessionError);
channel = libssh2_channel_open_session([server session]);
sessionError = libssh2_session_last_error([server session],NULL,NULL,0);
}
if( channel == NULL )
{
NSLog(@"Error Channel is incorrect");
NSLog(@"Returning empty string");
return @"";
//exit( 1 );
}
while( (rc = libssh2_channel_exec(channel, cmd)) == LIBSSH2_ERROR_EAGAIN )
{
waitsocket([server sock], [server session]);
}
if( rc != 0 )
{
NSLog(@"Error, return value is wrong rc = %ld\n", rc);
NSLog(@"Returning empty string");
return @"";
}
for( ;; )
{
/* loop until we block */
long rc1;
if (time < CFAbsoluteTimeGetCurrent())
break;
do {
rc1 = libssh2_channel_read( channel, buffer, (sizeof(buffer)));
if( rc1 > 0 )
bytecount += rc1;
//else
//NSLog(@"libssh2_channel_read returned %ld", rc1);
}
while( rc1 > 0 );
/* this is due to blocking that would occur otherwise so we loop on
this condition */
if( rc1 == LIBSSH2_ERROR_EAGAIN ) {
waitsocket([server sock], [server session]);
}
else
break;
}
exitcode = 127;
while( (rc = libssh2_channel_close(channel)) == LIBSSH2_ERROR_EAGAIN )
waitsocket([server sock], [server session]);
if( rc == 0 )
{
exitcode = libssh2_channel_get_exit_status( channel );
}
//NSLog(@"Number of bytes :%d", bytecount);
if (sizeof(buffer) > bytecount)
buffer[(bytecount+1)] = 0;
//NSLog(@"\nEXIT: %d bytecount: %d", exitcode, bytecount);
libssh2_channel_free(channel);
channel = NULL;
//Depricated but needed :/
if (bytecount == 0)
return @"";
return [NSString stringWithCString:buffer encoding:NSASCIIStringEncoding];
}
@end