diff options
author | stuconnolly <stuart02@gmail.com> | 2009-08-28 18:27:36 +0000 |
---|---|---|
committer | stuconnolly <stuart02@gmail.com> | 2009-08-28 18:27:36 +0000 |
commit | aea8e96f2adc91b64e7c521f34890e93f27da36c (patch) | |
tree | cfdaf58dfe18e46c890023cbe53f17231097beb5 /Source | |
parent | 480e035307bfc2dfa5feee16dacd43150b520d6a (diff) | |
download | sequelpro-aea8e96f2adc91b64e7c521f34890e93f27da36c.tar.gz sequelpro-aea8e96f2adc91b64e7c521f34890e93f27da36c.tar.bz2 sequelpro-aea8e96f2adc91b64e7c521f34890e93f27da36c.zip |
If the SSH tunnel is unable to bind to the local port because there is already an existing tunnel, give the user the option of using a standard connection to localhost on the port that is in use in order to use the existing tunnel. Fixes issue #371.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/SPConnectionController.m | 44 | ||||
-rw-r--r-- | Source/SPSSHTunnel.m | 2 | ||||
-rw-r--r-- | Source/SPTableData.m | 7 |
3 files changed, 40 insertions, 13 deletions
diff --git a/Source/SPConnectionController.m b/Source/SPConnectionController.m index 34446959..5d93a4f4 100644 --- a/Source/SPConnectionController.m +++ b/Source/SPConnectionController.m @@ -27,6 +27,7 @@ #import "SPAppController.h" #import "SPPreferenceController.h" #import "ImageAndTextCell.h" +#import "RegexKitLite.h" @implementation SPConnectionController @@ -145,7 +146,6 @@ */ - (IBAction)initiateConnection:(id)sender { - // Ensure that host is not empty if this is a TCP/IP or SSH connection if (([self type] == SP_CONNECTION_TCPIP || [self type] == SP_CONNECTION_SSHTUNNEL) && ![[self host] length]) { NSRunAlertPanel(NSLocalizedString(@"Insufficient connection details", @"insufficient details message"), NSLocalizedString(@"Insufficient details provided to establish a connection. Please provide at least a host.", @"insufficient details informative message"), NSLocalizedString(@"OK", @"OK button"), nil, nil); @@ -260,6 +260,7 @@ [progressIndicatorText setStringValue:NSLocalizedString(@"MySQL connecting...", @"MySQL connecting very short status message")]; else [progressIndicatorText setStringValue:NSLocalizedString(@"Connecting...", @"Generic connecting very short status message")]; + [progressIndicatorText display]; // Initialise to socket if appropriate. @@ -366,6 +367,8 @@ */ - (void)failConnectionWithTitle:(NSString *)theTitle errorMessage:(NSString *)theErrorMessage detail:(NSString *)errorDetail { + BOOL isSSHTunnelBindError = NO; + // Clean up the interface [progressIndicator stopAnimation:self]; [progressIndicator display]; @@ -376,23 +379,29 @@ [tableDocument clearStatusIcon]; // Release as appropriate - if (sshTunnel) [sshTunnel disconnect], [sshTunnel release], sshTunnel = nil; + if (sshTunnel) { + [sshTunnel disconnect], [sshTunnel release], sshTunnel = nil; + + // If the SSH tunnel connection failed because the port it was trying to bind to was already in use take note + // of it so we can give the user the option of connecting via standard connection and use the existing tunnel. + if ([theErrorMessage rangeOfString:@"bind"].location != NSNotFound) { + isSSHTunnelBindError = YES; + } + } if (errorDetail) [errorDetailText setString:errorDetail]; // Display the connection error message - NSBeginAlertSheet(theTitle, NSLocalizedString(@"OK", @"OK button"), errorDetail?NSLocalizedString(@"Show detail", @"Show detail button"):nil, nil, documentWindow, self, nil, @selector(errorSheetDidEnd:returnCode:contextInfo:), @"connect", theErrorMessage); + NSBeginAlertSheet(theTitle, NSLocalizedString(@"OK", @"OK button"), (errorDetail) ? NSLocalizedString(@"Show Detail", @"Show detail button") : nil, (isSSHTunnelBindError) ? NSLocalizedString(@"Use Standard Connection", @"use standard connection button") : nil, documentWindow, self, nil, @selector(errorSheetDidEnd:returnCode:contextInfo:), @"connect", theErrorMessage); } - /** * Alert sheet callback method - invoked when an error sheet is closed. */ - (void)errorSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(NSString *)contextInfo { [sheet orderOut:self]; - if (returnCode == NSAlertAlternateReturn) [errorDetailWindow makeKeyAndOrderFront:self]; - + // Restore the passwords from keychain for editing if appropriate if (connectionKeychainItemName) { [self setPassword:[keychain getPasswordForName:connectionKeychainItemName account:connectionKeychainItemAccount]]; @@ -400,6 +409,29 @@ if (connectionSSHKeychainItemName) { [self setSshPassword:[keychain getPasswordForName:connectionSSHKeychainItemName account:connectionSSHKeychainItemAccount]]; } + + if (returnCode == NSAlertAlternateReturn) { + [errorDetailWindow makeKeyAndOrderFront:self]; + } + // Currently only SSH port bind errors offer a 3rd option in the error dialog, but if this ever changes + // this will definitely need to be updated. + else if (returnCode == NSAlertOtherReturn) { + // Extract the local port number that SSH attempted to bind to from the debug output + NSString *tunnelPort = [[[errorDetailText string] componentsMatchedByRegex:@"LOCALHOST:([0-9]+)" capture:1L] lastObject]; + + // Change the connection type to standard TCP/IP + [self setType:SP_CONNECTION_TCPIP]; + + // Change connection details + [self setPort:tunnelPort]; + [self setHost:@"127.0.0.1"]; + + // Change to standard TCP/IP connection view + [self resizeTabViewToConnectionType:SP_CONNECTION_TCPIP animating:YES]; + + // Initiate the connection after half a second to give the connection view a chance to resize + [self performSelector:@selector(initiateConnection:) withObject:self afterDelay:0.5]; + } } /** diff --git a/Source/SPSSHTunnel.m b/Source/SPSSHTunnel.m index 3623a2f2..6c5be81c 100644 --- a/Source/SPSSHTunnel.m +++ b/Source/SPSSHTunnel.m @@ -387,7 +387,7 @@ connectionState = PROXY_STATE_IDLE; [task terminate]; if (lastError) [lastError release]; - lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel was unable to bind to the local port. This error may occur if you already have an SSH connection to the same server and are using a 'LocalForward' option in your SSH configuration.", @"SSH tunnel unable to bind to local port message")]; + lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel was unable to bind to the local port. This error may occur if you already have an SSH connection to the same server and are using a 'LocalForward' setting in your SSH configuration.\n\nWould you like to fall back to a standard connection to localhost in order to use the existing tunnel?", @"SSH tunnel unable to bind to local port message")]; if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO]; } diff --git a/Source/SPTableData.m b/Source/SPTableData.m index e61eb552..083de094 100644 --- a/Source/SPTableData.m +++ b/Source/SPTableData.m @@ -433,9 +433,8 @@ int nextOffs = 12; if( [parts count] > 8 ) { - // NOTE: this won't get SET NULL | NO ACTION + // NOTE: this won't get SET NULL | NO ACTION | RESTRICT if( [[parts objectAtIndex:9] hasPrefix:@"UPDATE"] ) { - //NSLog( @"update: %@", [parts objectAtIndex:10] ); if( [NSArrayObjectAtIndex(parts, 10) hasPrefix:@"SET"] ) { [constraintDetails setObject:@"SET NULL" forKey:@"update"]; @@ -450,7 +449,6 @@ } } else if( [NSArrayObjectAtIndex(parts, 9) hasPrefix:@"DELETE"] ) { - //NSLog( @"delete: %@", [parts objectAtIndex:10] ); if( [NSArrayObjectAtIndex(parts, 10) hasPrefix:@"SET"] ) { [constraintDetails setObject:@"SET NULL" forKey:@"delete"]; @@ -467,7 +465,6 @@ } if( [parts count] > nextOffs - 1 ) { if( [NSArrayObjectAtIndex(parts, nextOffs) hasPrefix:@"UPDATE"] ) { - //NSLog( @"update: %@", [parts objectAtIndex:13] ); if( [NSArrayObjectAtIndex(parts, nextOffs+1) hasPrefix:@"SET"] ) { [constraintDetails setObject:@"SET NULL" forKey:@"update"]; @@ -480,7 +477,6 @@ } } else if( [NSArrayObjectAtIndex(parts, nextOffs) hasPrefix:@"DELETE"] ) { - //NSLog( @"delete: %@", [parts objectAtIndex:13] ); if( [NSArrayObjectAtIndex(parts, nextOffs+1) hasPrefix:@"SET"] ) { [constraintDetails setObject:@"SET NULL" forKey:@"delete"]; @@ -498,7 +494,6 @@ } // primary key else if( [NSArrayObjectAtIndex(parts, 0) hasPrefix:@"PRIMARY"] ) { - //NSLog( @"pkey is %@", [[parts objectAtIndex:2] stringByTrimmingCharactersInSet:junk] ); } // key else if( [NSArrayObjectAtIndex(parts, 0) hasPrefix:@"KEY"] ) { |