aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrowanbeentje <rowan@beent.je>2009-06-21 22:32:06 +0000
committerrowanbeentje <rowan@beent.je>2009-06-21 22:32:06 +0000
commit859ca6771c479475ed454a4dbc61131fad30b492 (patch)
tree72af0608e7c9505a2f5fc5e3fa57c326c5691791
parente0b11c990a8c561e49b2148ea7208785ad6d0bd1 (diff)
downloadsequelpro-859ca6771c479475ed454a4dbc61131fad30b492.tar.gz
sequelpro-859ca6771c479475ed454a4dbc61131fad30b492.tar.bz2
sequelpro-859ca6771c479475ed454a4dbc61131fad30b492.zip
- Allow connections via SSH tunnels to reattempt using the specified host if 127.0.0.1 was retried automatically.
- Store the SSH debug logs and allow viewing on connection error - Clean up CMMCPConnections on connection failure - Fix connection keepalive instantiation
-rw-r--r--Interfaces/English.lproj/DBView.xib307
-rw-r--r--Source/CMMCPConnection.h1
-rw-r--r--Source/CMMCPConnection.m23
-rw-r--r--Source/SPSSHTunnel.h8
-rw-r--r--Source/SPSSHTunnel.m62
-rw-r--r--Source/TableDocument.h4
-rw-r--r--Source/TableDocument.m54
7 files changed, 418 insertions, 41 deletions
diff --git a/Interfaces/English.lproj/DBView.xib b/Interfaces/English.lproj/DBView.xib
index c53bdce5..89201d7e 100644
--- a/Interfaces/English.lproj/DBView.xib
+++ b/Interfaces/English.lproj/DBView.xib
@@ -8,7 +8,6 @@
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="673"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -80,6 +79,7 @@
<int key="NSvFlags">4352</int>
<string key="NSFrameSize">{214, 395}</string>
<reference key="NSSuperview" ref="73685676"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="_NSCornerView" key="NSCornerView">
<nil key="NSNextResponder"/>
@@ -176,6 +176,7 @@
</object>
<string key="NSFrameSize">{214, 395}</string>
<reference key="NSSuperview" ref="233472824"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="251040077"/>
<reference key="NSDocView" ref="251040077"/>
<object class="NSColor" key="NSBGColor" id="1024678221">
@@ -191,6 +192,7 @@
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{175, 1}, {15, 481}}</string>
<reference key="NSSuperview" ref="233472824"/>
+ <reference key="NSWindow"/>
<reference key="NSTarget" ref="233472824"/>
<string key="NSAction">_doScroller:</string>
<double key="NSPercent">9.979253e-01</double>
@@ -200,6 +202,7 @@
<int key="NSvFlags">256</int>
<string key="NSFrame">{{-100, -100}, {141, 11}}</string>
<reference key="NSSuperview" ref="233472824"/>
+ <reference key="NSWindow"/>
<int key="NSsFlags">257</int>
<reference key="NSTarget" ref="233472824"/>
<string key="NSAction">_doScroller:</string>
@@ -208,6 +211,7 @@
</object>
<string key="NSFrameSize">{214, 395}</string>
<reference key="NSSuperview" ref="355288374"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="73685676"/>
<int key="NSsFlags">528</int>
<reference key="NSVScroller" ref="693168867"/>
@@ -230,6 +234,7 @@
<int key="NSvFlags">4352</int>
<string key="NSFrameSize">{214, 125}</string>
<reference key="NSSuperview" ref="685057119"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="_NSCornerView" key="NSCornerView">
<nil key="NSNextResponder"/>
@@ -293,6 +298,7 @@
</object>
<string key="NSFrameSize">{214, 125}</string>
<reference key="NSSuperview" ref="298226231"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="347093764"/>
<reference key="NSDocView" ref="347093764"/>
<reference key="NSBGColor" ref="1024678221"/>
@@ -303,6 +309,7 @@
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{175, 1}, {15, 481}}</string>
<reference key="NSSuperview" ref="298226231"/>
+ <reference key="NSWindow"/>
<reference key="NSTarget" ref="298226231"/>
<string key="NSAction">_doScroller:</string>
<double key="NSPercent">9.979253e-01</double>
@@ -312,6 +319,7 @@
<int key="NSvFlags">256</int>
<string key="NSFrame">{{-100, -100}, {141, 11}}</string>
<reference key="NSSuperview" ref="298226231"/>
+ <reference key="NSWindow"/>
<int key="NSsFlags">257</int>
<reference key="NSTarget" ref="298226231"/>
<string key="NSAction">_doScroller:</string>
@@ -320,6 +328,7 @@
</object>
<string key="NSFrame">{{0, 404}, {214, 125}}</string>
<reference key="NSSuperview" ref="355288374"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="685057119"/>
<int key="NSsFlags">528</int>
<reference key="NSVScroller" ref="245346414"/>
@@ -330,12 +339,14 @@
</object>
<string key="NSFrame">{{-1, 22}, {214, 529}}</string>
<reference key="NSSuperview" ref="372294785"/>
+ <reference key="NSWindow"/>
</object>
<object class="NSButton" id="644515521">
<reference key="NSNextResponder" ref="372294785"/>
<int key="NSvFlags">292</int>
<string key="NSFrame">{{0, -1}, {32, 25}}</string>
<reference key="NSSuperview" ref="372294785"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="492393561">
<int key="NSCellFlags">-2080244224</int>
@@ -364,6 +375,7 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{20, 0}, {46, 25}}</string>
<reference key="NSSuperview" ref="372294785"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSPopUpButtonCell" key="NSCell" id="753352469">
<int key="NSCellFlags">-2076049856</int>
@@ -387,10 +399,7 @@
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
- <object class="NSCustomResource" key="NSImage" id="321905421">
- <string key="NSClassName">NSImage</string>
- <string key="NSResourceName">button_action</string>
- </object>
+ <reference key="NSImage" ref="197220008"/>
<string key="NSAction">_popUpItemAction:</string>
<reference key="NSTarget" ref="753352469"/>
</object>
@@ -483,6 +492,7 @@
</object>
<string key="NSFrame">{{197, 0}, {15, 23}}</string>
<reference key="NSSuperview" ref="372294785"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSImageCell" key="NSCell" id="875296521">
<int key="NSCellFlags">130560</int>
@@ -515,6 +525,7 @@
</object>
<string key="NSFrame">{{93, 0}, {104, 23}}</string>
<reference key="NSSuperview" ref="372294785"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSImageCell" key="NSCell" id="761703901">
<int key="NSCellFlags">130560</int>
@@ -535,6 +546,7 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{61, -1}, {32, 25}}</string>
<reference key="NSSuperview" ref="372294785"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="529591350">
<int key="NSCellFlags">-2080244224</int>
@@ -557,6 +569,7 @@
</object>
<string key="NSFrameSize">{212, 550}</string>
<reference key="NSSuperview" ref="937377983"/>
+ <reference key="NSWindow"/>
<string key="NSClassName">NSView</string>
</object>
<object class="NSCustomView" id="604818293">
@@ -569,6 +582,7 @@
<int key="NSvFlags">274</int>
<string key="NSFrame">{{-7, -10}, {735, 564}}</string>
<reference key="NSSuperview" ref="604818293"/>
+ <reference key="NSWindow"/>
<object class="NSMutableArray" key="NSTabViewItems">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSTabViewItem" id="831053945">
@@ -603,12 +617,14 @@
<int key="NSvFlags">4352</int>
<string key="NSFrameSize">{688, 289}</string>
<reference key="NSSuperview" ref="16936123"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTableHeaderView" key="NSHeaderView" id="926883367">
<reference key="NSNextResponder" ref="639957061"/>
<int key="NSvFlags">256</int>
<string key="NSFrameSize">{688, 17}</string>
<reference key="NSSuperview" ref="639957061"/>
+ <reference key="NSWindow"/>
<reference key="NSTableView" ref="715508012"/>
</object>
<object class="_NSCornerView" key="NSCornerView" id="868771861">
@@ -616,6 +632,7 @@
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{-26, 0}, {16, 17}}</string>
<reference key="NSSuperview" ref="22340145"/>
+ <reference key="NSWindow"/>
</object>
<object class="NSMutableArray" key="NSTableColumns">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -1148,6 +1165,7 @@
</object>
<string key="NSFrame">{{1, 17}, {688, 289}}</string>
<reference key="NSSuperview" ref="22340145"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="715508012"/>
<reference key="NSDocView" ref="715508012"/>
<reference key="NSBGColor" ref="1024678221"/>
@@ -1158,6 +1176,7 @@
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{611, 17}, {15, 274}}</string>
<reference key="NSSuperview" ref="22340145"/>
+ <reference key="NSWindow"/>
<reference key="NSTarget" ref="22340145"/>
<string key="NSAction">_doScroller:</string>
<double key="NSPercent">9.858657e-01</double>
@@ -1167,6 +1186,7 @@
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{1, 291}, {610, 15}}</string>
<reference key="NSSuperview" ref="22340145"/>
+ <reference key="NSWindow"/>
<int key="NSsFlags">1</int>
<reference key="NSTarget" ref="22340145"/>
<string key="NSAction">_doScroller:</string>
@@ -1181,6 +1201,7 @@
</object>
<string key="NSFrame">{{1, 0}, {688, 17}}</string>
<reference key="NSSuperview" ref="22340145"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="926883367"/>
<reference key="NSDocView" ref="926883367"/>
<reference key="NSBGColor" ref="1024678221"/>
@@ -1190,6 +1211,7 @@
</object>
<string key="NSFrame">{{-1, 22}, {690, 307}}</string>
<reference key="NSSuperview" ref="220777809"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="16936123"/>
<int key="NSsFlags">562</int>
<reference key="NSVScroller" ref="943144555"/>
@@ -1204,6 +1226,7 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{-1, -1}, {32, 25}}</string>
<reference key="NSSuperview" ref="220777809"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="413143172">
<int key="NSCellFlags">-1543373312</int>
@@ -1225,6 +1248,7 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{93, -1}, {32, 25}}</string>
<reference key="NSSuperview" ref="220777809"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="917381158">
<int key="NSCellFlags">-2080244224</int>
@@ -1246,6 +1270,7 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{30, -1}, {32, 25}}</string>
<reference key="NSSuperview" ref="220777809"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="578226656">
<int key="NSCellFlags">-1543373312</int>
@@ -1270,6 +1295,7 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{61, -1}, {32, 25}}</string>
<reference key="NSSuperview" ref="220777809"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="626480887">
<int key="NSCellFlags">-1543373312</int>
@@ -1306,6 +1332,7 @@
</object>
<string key="NSFrame">{{125, 0}, {532, 23}}</string>
<reference key="NSSuperview" ref="220777809"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSImageCell" key="NSCell" id="4715">
<int key="NSCellFlags">130560</int>
@@ -1323,6 +1350,7 @@
<int key="NSvFlags">289</int>
<string key="NSFrame">{{657, -1}, {32, 25}}</string>
<reference key="NSSuperview" ref="220777809"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="1072754876">
<int key="NSCellFlags">-1543373312</int>
@@ -1345,6 +1373,7 @@
</object>
<string key="NSFrameSize">{689, 329}</string>
<reference key="NSSuperview" ref="628830973"/>
+ <reference key="NSWindow"/>
<string key="NSClassName">NSView</string>
</object>
<object class="NSCustomView" id="1063281455">
@@ -1357,6 +1386,7 @@
<int key="NSvFlags">264</int>
<string key="NSFrame">{{7, 183}, {46, 14}}</string>
<reference key="NSSuperview" ref="1063281455"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="749773740">
<int key="NSCellFlags">67239424</int>
@@ -1383,12 +1413,14 @@
<int key="NSvFlags">4352</int>
<string key="NSFrameSize">{688, 141}</string>
<reference key="NSSuperview" ref="794929378"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTableHeaderView" key="NSHeaderView" id="459548655">
<reference key="NSNextResponder" ref="1038672854"/>
<int key="NSvFlags">256</int>
<string key="NSFrameSize">{688, 17}</string>
<reference key="NSSuperview" ref="1038672854"/>
+ <reference key="NSWindow"/>
<reference key="NSTableView" ref="584834515"/>
</object>
<object class="_NSCornerView" key="NSCornerView" id="476444025">
@@ -1396,6 +1428,7 @@
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{-26, 0}, {16, 17}}</string>
<reference key="NSSuperview" ref="376224367"/>
+ <reference key="NSWindow"/>
</object>
<object class="NSMutableArray" key="NSTableColumns">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -1648,6 +1681,7 @@
</object>
<string key="NSFrame">{{1, 17}, {688, 141}}</string>
<reference key="NSSuperview" ref="376224367"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="584834515"/>
<reference key="NSDocView" ref="584834515"/>
<reference key="NSBGColor" ref="1024678221"/>
@@ -1658,6 +1692,7 @@
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{611, 17}, {15, 126}}</string>
<reference key="NSSuperview" ref="376224367"/>
+ <reference key="NSWindow"/>
<reference key="NSTarget" ref="376224367"/>
<string key="NSAction">_doScroller:</string>
<double key="NSPercent">8.936170e-01</double>
@@ -1667,6 +1702,7 @@
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{1, 143}, {610, 15}}</string>
<reference key="NSSuperview" ref="376224367"/>
+ <reference key="NSWindow"/>
<int key="NSsFlags">1</int>
<reference key="NSTarget" ref="376224367"/>
<string key="NSAction">_doScroller:</string>
@@ -1681,6 +1717,7 @@
</object>
<string key="NSFrame">{{1, 0}, {688, 17}}</string>
<reference key="NSSuperview" ref="376224367"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="459548655"/>
<reference key="NSDocView" ref="459548655"/>
<reference key="NSBGColor" ref="1024678221"/>
@@ -1690,6 +1727,7 @@
</object>
<string key="NSFrame">{{-1, 22}, {690, 159}}</string>
<reference key="NSSuperview" ref="1063281455"/>
+ <reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="794929378"/>
<int key="NSsFlags">562</int>
<reference key="NSVScroller" ref="1019209947"/>
@@ -1704,6 +1742,7 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{-1, -1}, {32, 25}}</string>
<reference key="NSSuperview" ref="1063281455"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="326048025">
<int key="NSCellFlags">-1543373312</int>
@@ -1725,6 +1764,7 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{61, -1}, {32, 25}}</string>
<reference key="NSSuperview" ref="1063281455"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="153146827">
<int key="NSCellFlags">-2080244224</int>
@@ -1746,6 +1786,7 @@
<int key="NSvFlags">292</int>
<string key="NSFrame">{{30, -1}, {32, 25}}</string>
<reference key="NSSuperview" ref="1063281455"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="345927225">
<int key="NSCellFlags">-1543373312</int>
@@ -1779,6 +1820,7 @@
</object>
<string key="NSFrame">{{670, 183}, {10, 13}}</string>
<reference key="NSSuperview" ref="1063281455"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSImageCell" key="NSCell" id="545156725">
<int key="NSCellFlags">130560</int>
@@ -1811,6 +1853,7 @@
</object>
<string key="NSFrame">{{93, 0}, {596, 23}}</string>
<reference key="NSSuperview" ref="1063281455"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSImageCell" key="NSCell" id="372723860">
<int key="NSCellFlags">130560</int>
@@ -1826,16 +1869,19 @@
</object>
<string key="NSFrame">{{0, 330}, {689, 201}}</string>
<reference key="NSSuperview" ref="628830973"/>
+ <reference key="NSWindow"/>
<string key="NSClassName">NSView</string>
</object>
</object>
<string key="NSFrame">{{7, 10}, {689, 531}}</string>
<reference key="NSSuperview" ref="461236772"/>
+ <reference key="NSWindow"/>
<int key="NSDividerStyle">2</int>
</object>
</object>
<string key="NSFrame">{{10, 7}, {700, 544}}</string>
<reference key="NSSuperview" ref="714795046"/>
+ <reference key="NSWindow"/>
</object>
<string key="NSLabel">Structure</string>
<reference key="NSColor" ref="62854682"/>
@@ -2873,7 +2919,7 @@
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
- <reference key="NSImage" ref="321905421"/>
+ <reference key="NSImage" ref="197220008"/>
<string key="NSAction">_popUpItemAction:</string>
<reference key="NSTarget" ref="984501775"/>
</object>
@@ -4301,17 +4347,20 @@
</object>
<string key="NSFrame">{{221, 0}, {723, 550}}</string>
<reference key="NSSuperview" ref="937377983"/>
+ <reference key="NSWindow"/>
<string key="NSClassName">NSView</string>
</object>
</object>
<string key="NSFrameSize">{944, 550}</string>
<reference key="NSSuperview" ref="579726586"/>
+ <reference key="NSWindow"/>
<bool key="NSIsVertical">YES</bool>
<string key="NSAutosaveName">DBViewSplitter</string>
</object>
</object>
<string key="NSFrameSize">{944, 550}</string>
<reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
<string key="NSMinSize">{780, 502}</string>
@@ -5332,7 +5381,7 @@
</object>
<object class="NSMutableArray" key="NSAttributes">
<bool key="EncodedWithXMLCoder">YES</bool>
- <object class="NSDictionary">
+ <object class="NSDictionary" id="948448827">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -5455,7 +5504,7 @@
</object>
</object>
</object>
- <object class="NSDictionary">
+ <object class="NSDictionary" id="866150120">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -5569,7 +5618,6 @@
</object>
<string key="NSFrameSize">{588, 316}</string>
<reference key="NSSuperview" ref="541887300"/>
- <reference key="NSNextKeyView" ref="798764405"/>
<reference key="NSDocView" ref="798764405"/>
<object class="NSColor" key="NSBGColor">
<int key="NSColorSpace">1</int>
@@ -5601,7 +5649,6 @@
</object>
<string key="NSFrame">{{0, 34}, {588, 316}}</string>
<reference key="NSSuperview" ref="661948784"/>
- <reference key="NSNextKeyView" ref="593223452"/>
<int key="NSsFlags">528</int>
<reference key="NSVScroller" ref="142711676"/>
<reference key="NSHScroller" ref="705947940"/>
@@ -10060,6 +10107,146 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8</string>
<string key="NSMinSize">{260, 134}</string>
<string key="NSMaxSize">{600, 134}</string>
</object>
+ <object class="NSWindowTemplate" id="975000620">
+ <int key="NSWindowStyleMask">8223</int>
+ <int key="NSWindowBacking">2</int>
+ <string key="NSWindowRect">{{439, 103}, {736, 508}}</string>
+ <int key="NSWTFlags">-469762048</int>
+ <string key="NSWindowTitle">Error Detail</string>
+ <string key="NSWindowClass">NSPanel</string>
+ <nil key="NSViewClass"/>
+ <string key="NSWindowContentMaxSize">{3.40282e+38, 3.40282e+38}</string>
+ <object class="NSView" key="NSWindowView" id="893535515">
+ <nil key="NSNextResponder"/>
+ <int key="NSvFlags">256</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSScrollView" id="354268322">
+ <reference key="NSNextResponder" ref="893535515"/>
+ <int key="NSvFlags">274</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSClipView" id="231365684">
+ <reference key="NSNextResponder" ref="354268322"/>
+ <int key="NSvFlags">2304</int>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSTextView" id="105927324">
+ <reference key="NSNextResponder" ref="231365684"/>
+ <int key="NSvFlags">2322</int>
+ <string key="NSFrameSize">{736, 60}</string>
+ <reference key="NSSuperview" ref="231365684"/>
+ <object class="NSTextContainer" key="NSTextContainer" id="722035520">
+ <object class="NSLayoutManager" key="NSLayoutManager">
+ <object class="NSTextStorage" key="NSTextStorage">
+ <object class="NSMutableString" key="NSString">
+ <characters key="NS.bytes">Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum Et harumd und lookum like Greek to me, dereud facilis est er expedit distinct. Nam liber te conscient to factor tum poen legum odioque civiuda</characters>
+ </object>
+ <object class="NSMutableArray" key="NSAttributes">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="948448827"/>
+ <reference ref="866150120"/>
+ </object>
+ <object class="NSMutableData" key="NSAttributeInfo">
+ <bytes key="NS.bytes">GQAEAQgADAEiAAcBhAQAA</bytes>
+ </object>
+ <nil key="NSDelegate"/>
+ </object>
+ <object class="NSMutableArray" key="NSTextContainers">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="722035520"/>
+ </object>
+ <int key="NSLMFlags">6</int>
+ <nil key="NSDelegate"/>
+ </object>
+ <reference key="NSTextView" ref="105927324"/>
+ <double key="NSWidth">7.360000e+02</double>
+ <int key="NSTCFlags">1</int>
+ </object>
+ <object class="NSTextViewSharedData" key="NSSharedData">
+ <int key="NSFlags">2049</int>
+ <reference key="NSBackgroundColor" ref="449903125"/>
+ <reference key="NSInsertionColor" ref="885278162"/>
+ <object class="NSDictionary" key="NSSelectedAttributes">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>NSBackgroundColor</string>
+ <string>NSColor</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="905060551"/>
+ <reference ref="63182758"/>
+ </object>
+ </object>
+ <nil key="NSMarkedAttributes"/>
+ <object class="NSDictionary" key="NSLinkAttributes">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSMutableArray" key="dict.sortedKeys">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <string>NSColor</string>
+ <string>NSUnderline</string>
+ </object>
+ <object class="NSMutableArray" key="dict.values">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="114422645"/>
+ <reference ref="9"/>
+ </object>
+ </object>
+ <nil key="NSDefaultParagraphStyle"/>
+ </object>
+ <int key="NSTVFlags">6</int>
+ <string key="NSMaxSize">{1176, 1e+07}</string>
+ <string key="NSMinize">{83, 0}</string>
+ <nil key="NSDelegate"/>
+ </object>
+ </object>
+ <string key="NSFrameSize">{736, 488}</string>
+ <reference key="NSSuperview" ref="354268322"/>
+ <reference key="NSDocView" ref="105927324"/>
+ <object class="NSColor" key="NSBGColor">
+ <int key="NSColorSpace">1</int>
+ <bytes key="NSRGB">MSAxIDEgMC45NDk5OTk5OQA</bytes>
+ </object>
+ <reference key="NSCursor" ref="32917531"/>
+ <int key="NScvFlags">6</int>
+ </object>
+ <object class="NSScroller" id="589641065">
+ <reference key="NSNextResponder" ref="354268322"/>
+ <int key="NSvFlags">-2147483392</int>
+ <string key="NSFrame">{{573, 0}, {15, 316}}</string>
+ <reference key="NSSuperview" ref="354268322"/>
+ <reference key="NSTarget" ref="354268322"/>
+ <string key="NSAction">_doScroller:</string>
+ <double key="NSPercent">3.877301e-01</double>
+ </object>
+ <object class="NSScroller" id="747613041">
+ <reference key="NSNextResponder" ref="354268322"/>
+ <int key="NSvFlags">256</int>
+ <string key="NSFrame">{{-100, -100}, {87, 18}}</string>
+ <reference key="NSSuperview" ref="354268322"/>
+ <int key="NSsFlags">1</int>
+ <reference key="NSTarget" ref="354268322"/>
+ <string key="NSAction">_doScroller:</string>
+ <double key="NSCurValue">1.000000e+00</double>
+ <double key="NSPercent">9.456522e-01</double>
+ </object>
+ </object>
+ <string key="NSFrame">{{0, 20}, {736, 488}}</string>
+ <reference key="NSSuperview" ref="893535515"/>
+ <int key="NSsFlags">528</int>
+ <reference key="NSVScroller" ref="589641065"/>
+ <reference key="NSHScroller" ref="747613041"/>
+ <reference key="NSContentView" ref="231365684"/>
+ </object>
+ </object>
+ <string key="NSFrameSize">{736, 508}</string>
+ </object>
+ <string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
+ <string key="NSMaxSize">{3.40282e+38, 3.40282e+38}</string>
+ <string key="NSFrameAutosaveName"/>
+ </object>
<object class="NSCustomView" id="139279766">
<nil key="NSNextResponder"/>
<int key="NSvFlags">256</int>
@@ -16043,6 +16230,22 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8</string>
</object>
<int key="connectionID">6012</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">errorDetailWindow</string>
+ <reference key="source" ref="427689665"/>
+ <reference key="destination" ref="975000620"/>
+ </object>
+ <int key="connectionID">6021</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">errorDetailText</string>
+ <reference key="source" ref="427689665"/>
+ <reference key="destination" ref="105927324"/>
+ </object>
+ <int key="connectionID">6022</int>
+ </object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -22677,6 +22880,52 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8</string>
<reference key="object" ref="1072754876"/>
<reference key="parent" ref="507448309"/>
</object>
+ <object class="IBObjectRecord">
+ <int key="objectID">6013</int>
+ <reference key="object" ref="975000620"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="893535515"/>
+ </object>
+ <reference key="parent" ref="1043842561"/>
+ <string key="objectName">errorDetailWindow</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">6014</int>
+ <reference key="object" ref="893535515"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="354268322"/>
+ </object>
+ <reference key="parent" ref="975000620"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">6016</int>
+ <reference key="object" ref="354268322"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="105927324"/>
+ <reference ref="747613041"/>
+ <reference ref="589641065"/>
+ </object>
+ <reference key="parent" ref="893535515"/>
+ <string key="objectName">SyntaxView</string>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">6017</int>
+ <reference key="object" ref="105927324"/>
+ <reference key="parent" ref="354268322"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">6018</int>
+ <reference key="object" ref="747613041"/>
+ <reference key="parent" ref="354268322"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">6019</int>
+ <reference key="object" ref="589641065"/>
+ <reference key="parent" ref="354268322"/>
+ </object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
@@ -24027,6 +24276,22 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8</string>
<string>6009.IBAttributePlaceholdersKey</string>
<string>6009.IBPluginDependency</string>
<string>6010.IBPluginDependency</string>
+ <string>6013.IBEditorWindowLastContentRect</string>
+ <string>6013.IBWindowTemplateEditedContentRect</string>
+ <string>6013.NSWindowTemplate.visibleAtLaunch</string>
+ <string>6013.editorWindowContentRectSynchronizationRect</string>
+ <string>6013.windowTemplate.hasMaxSize</string>
+ <string>6013.windowTemplate.maxSize</string>
+ <string>6014.IBPluginDependency</string>
+ <string>6016.IBPluginDependency</string>
+ <string>6016.IBViewIntegration.shadowBlurRadius</string>
+ <string>6016.IBViewIntegration.shadowColor</string>
+ <string>6016.IBViewIntegration.shadowOffsetHeight</string>
+ <string>6016.IBViewIntegration.shadowOffsetWidth</string>
+ <string>6016.editorWindowContentRectSynchronizationRect</string>
+ <string>6017.IBPluginDependency</string>
+ <string>6018.IBPluginDependency</string>
+ <string>6019.IBPluginDependency</string>
<string>604.IBEditorWindowLastContentRect</string>
<string>604.IBWindowTemplateEditedContentRect</string>
<string>604.ImportedFromIB2</string>
@@ -25933,6 +26198,22 @@ aGUgYWN0aXZlIHNlbGVjdGlvbiAo4oyl4oyYUik</string>
</object>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>{{218, 200}, {736, 508}}</string>
+ <string>{{218, 200}, {736, 508}}</string>
+ <reference ref="8"/>
+ <string>{{115, 214}, {588, 350}}</string>
+ <reference ref="8"/>
+ <string>{3.40282e+38, 3.40282e+38}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <reference ref="8"/>
+ <reference ref="304829493"/>
+ <reference ref="8"/>
+ <reference ref="8"/>
+ <string>{{343, 395}, {320, 180}}</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{67, 340}, {667, 416}}</string>
<string>{{67, 340}, {667, 416}}</string>
<reference ref="9"/>
@@ -26185,7 +26466,7 @@ Y2hhbmdlIHRoZSBvcmRlcg</string>
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">6012</int>
+ <int key="maxID">6022</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -27027,6 +27308,8 @@ Y2hhbmdlIHRoZSBvcmRlcg</string>
<string>databaseNameField</string>
<string>databaseSheet</string>
<string>dbTablesTableView</string>
+ <string>errorDetailText</string>
+ <string>errorDetailWindow</string>
<string>extendedTableInfoInstance</string>
<string>favoritesButton</string>
<string>favoritesController</string>
@@ -27080,6 +27363,8 @@ Y2hhbmdlIHRoZSBvcmRlcg</string>
<string>id</string>
<string>id</string>
<string>NSTableView</string>
+ <string>NSTextView</string>
+ <string>NSWindow</string>
<string>id</string>
<string>id</string>
<string>NSArrayController</string>
diff --git a/Source/CMMCPConnection.h b/Source/CMMCPConnection.h
index 81b25535..5d9f98c1 100644
--- a/Source/CMMCPConnection.h
+++ b/Source/CMMCPConnection.h
@@ -91,6 +91,7 @@
- (id) initToHost:(NSString *) host withLogin:(NSString *) login usingPort:(int) port;
- (id) initToSocket:(NSString *) socket withLogin:(NSString *) login;
- (void) initSPExtensions;
+- (BOOL) setPort:(int) thePort;
- (BOOL) setPassword:(NSString *)thePassword;
- (BOOL) setPasswordKeychainName:(NSString *)theName account:(NSString *)theAccount;
- (BOOL) setSSHTunnel:(SPSSHTunnel *)theTunnel;
diff --git a/Source/CMMCPConnection.m b/Source/CMMCPConnection.m
index 60b8d2da..e31b9765 100644
--- a/Source/CMMCPConnection.m
+++ b/Source/CMMCPConnection.m
@@ -182,6 +182,15 @@ static void forcePingTimeout(int signalNumber);
return YES;
}
+/*
+ * Sets or updates the connection port - for use with tunnels.
+ */
+- (BOOL) setPort:(int) thePort
+{
+ connectionPort = thePort;
+
+ return YES;
+}
/*
* Set a SSH tunnel object to connect through. This object will be retained locally,
@@ -215,9 +224,6 @@ static void forcePingTimeout(int signalNumber);
// Ensure that a password method has been provided
if (connectionKeychainName == nil && connectionPassword == nil) return NO;
- // Start the keepalive timer
- [self startKeepAliveTimerResettingState:YES];
-
// Disconnect if a connection is already active
if (mConnected) {
[self disconnect];
@@ -259,10 +265,6 @@ static void forcePingTimeout(int signalNumber);
thePass = NULL;
if (theRet != mConnection) {
[self setLastErrorMessage:nil];
- if (connectionTunnel) {
- [connectionTunnel disconnect];
- [delegate setStatusIconToImageWithName:@"ssh-disconnected"];
- }
return mConnected = NO;
}
@@ -275,10 +277,6 @@ static void forcePingTimeout(int signalNumber);
if (![self fetchMaxAllowedPacket]) {
[self setLastErrorMessage:nil];
- if (connectionTunnel) {
- [connectionTunnel disconnect];
- [delegate setStatusIconToImageWithName:@"ssh-disconnected"];
- }
return mConnected = NO;
}
@@ -291,6 +289,9 @@ static void forcePingTimeout(int signalNumber);
// Init 'consoleLoggingEnabled'
consoleLoggingEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:@"ConsoleEnableLogging"];
+
+ // Start the keepalive timer
+ [self startKeepAliveTimerResettingState:YES];
return mConnected;
}
diff --git a/Source/SPSSHTunnel.h b/Source/SPSSHTunnel.h
index 0c34f4f9..db01c98e 100644
--- a/Source/SPSSHTunnel.h
+++ b/Source/SPSSHTunnel.h
@@ -5,7 +5,8 @@ enum spsshtunnel_states
SPSSH_STATE_IDLE = 0,
SPSSH_STATE_CONNECTING = 1,
SPSSH_STATE_WAITING_FOR_AUTH = 2,
- SPSSH_STATE_CONNECTED = 3
+ SPSSH_STATE_CONNECTED = 3,
+ SPSSH_STATE_FORWARDING_FAILED = 4
};
enum spsshtunnel_password_modes
@@ -40,11 +41,14 @@ enum spsshtunnel_password_modes
NSString *keychainName;
NSString *keychainAccount;
NSString *requestedPassphrase;
+ NSMutableArray *debugMessages;
+ BOOL useHostFallback;
BOOL requestedResponse;
BOOL passwordInKeychain;
int sshPort;
int remotePort;
int localPort;
+ int localPortFallback;
int connectionState;
}
@@ -55,7 +59,9 @@ enum spsshtunnel_password_modes
- (BOOL) setPassword:(NSString *)thePassword;
- (int) state;
- (NSString *) lastError;
+- (NSString *) debugMessages;
- (int) localPort;
+- (int) localPortFallback;
- (void) connect;
- (void) launchTask:(id) dummy;
- (void) disconnect;
diff --git a/Source/SPSSHTunnel.m b/Source/SPSSHTunnel.m
index 6df20d2e..a0a3bdd7 100644
--- a/Source/SPSSHTunnel.m
+++ b/Source/SPSSHTunnel.m
@@ -45,15 +45,13 @@
sshHost = [[NSString alloc] initWithString:theHost];
sshLogin = [[NSString alloc] initWithString:(theLogin?theLogin:@"")];
sshPort = thePort;
- if ([theHost isEqualToString:targetHost]) {
- remoteHost = [[NSString alloc] initWithString:@"127.0.0.1"];
- } else {
- remoteHost = [[NSString alloc] initWithString:targetHost];
- }
+ useHostFallback = [theHost isEqualToString:targetHost];
+ remoteHost = [[NSString alloc] initWithString:targetHost];
remotePort = targetPort;
delegate = nil;
stateChangeSelector = nil;
lastError = nil;
+ debugMessages = [[NSMutableArray alloc] init];
// Set up a connection for use by the tunnel process
tunnelConnectionName = [[NSString alloc] initWithFormat:@"SequelPro-%f", [[NSString stringWithFormat:@"%f", [[NSDate date] timeIntervalSince1970]] hash]];
@@ -149,11 +147,20 @@
}
/*
+ * Returns all the debug text for this tunnel as a string, separated
+ * by line endings.
+ */
+- (NSString *) debugMessages {
+ return [debugMessages componentsJoinedByString:@"\n"];
+}
+
+/*
* Initiate the SSH tunnel connection, launching the task in a background thread.
*/
- (void) connect
{
localPort = 0;
+ [debugMessages removeAllObjects];
if (connectionState != SPSSH_STATE_IDLE || (!passwordInKeychain && !password)) return;
[NSThread detachNewThreadSelector:@selector(launchTask:) toTarget: self withObject: nil ];
}
@@ -208,8 +215,24 @@
close(tempSocket);
}
+ if (useHostFallback) {
+ if((tempSocket = socket(AF_INET, SOCK_STREAM, 0)) > 0) {
+ memset(&tempSocketAddress, 0, sizeof(tempSocketAddress));
+ tempSocketAddress.sin_family = AF_INET;
+ tempSocketAddress.sin_addr.s_addr = htonl(INADDR_ANY);
+ tempSocketAddress.sin_port = 0;
+ if (bind(tempSocket, (struct sockaddr *)&tempSocketAddress, addressLength) >= 0) {
+ if (getsockname(tempSocket, (struct sockaddr *)&tempSocketAddress, (uint32_t *)&addressLength) >= 0) {
+ localPortFallback = ntohs(tempSocketAddress.sin_port);
+ }
+ }
+ close(tempSocket);
+ }
+
+ }
+
// Abort if no local free port could be allocated
- if (!localPort) {
+ if (!localPort || (useHostFallback && !localPortFallback)) {
connectionState = SPSSH_STATE_IDLE;
if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO];
if (lastError) [lastError release];
@@ -242,7 +265,12 @@
} else {
[taskArguments addObject:sshHost];
}
- [taskArguments addObject:[NSString stringWithFormat:@"-L %i/%@/%i", localPort, remoteHost, remotePort]];
+ if (useHostFallback) {
+ [taskArguments addObject:[NSString stringWithFormat:@"-L %i/127.0.0.1/%i", localPort, remotePort]];
+ [taskArguments addObject:[NSString stringWithFormat:@"-L %i/%@/%i", localPortFallback, remoteHost, remotePort]];
+ } else {
+ [taskArguments addObject:[NSString stringWithFormat:@"-L %i/%@/%i", localPort, remoteHost, remotePort]];
+ }
[task setArguments:taskArguments];
// Set up the environment for the task
@@ -337,7 +365,9 @@
if ([notificationText length]) {
messages = [notificationText componentsSeparatedByString:@"\n"];
enumerator = [messages objectEnumerator];
- while (message = [enumerator nextObject]) {
+ while (message = [[enumerator nextObject] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]) {
+ if (![message length]) continue;
+ [debugMessages addObject:[NSString stringWithString:message]];
if ([message rangeOfString:@"Entering interactive session."].location != NSNotFound) {
connectionState = SPSSH_STATE_CONNECTED;
@@ -363,6 +393,11 @@
lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel could not authenticate with the remote host. Please check your password and ensure you still have access.", @"SSH tunnel authentication failed message")];
if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO];
}
+ if ([message rangeOfString:@"connect failed: Connection refused" ].location != NSNotFound) {
+ connectionState = SPSSH_STATE_FORWARDING_FAILED;
+ if (lastError) [lastError release];
+ lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel was established successfully, but could not forward data to the remote port as the remote port refused the connection.", @"SSH tunnel forwarding port connection refused message")];
+ }
if ([message rangeOfString:@"Operation timed out" ].location != NSNotFound) {
connectionState = SPSSH_STATE_IDLE;
[task terminate];
@@ -389,6 +424,15 @@
}
/*
+ * Returns the local port assigned for fallback use by the tunnel, if any
+ */
+- (int) localPortFallback
+{
+ if (!useHostFallback) return 0;
+ return localPortFallback;
+}
+
+/*
* Method to request the password for the current connection, as used by TunnelPassphraseRequester;
* called with a verification hash to check against the stored hash, to provide basic security. Note
* that this is easily bypassed, but if bypassed the password can already easily be retrieved in the same way.
@@ -519,12 +563,14 @@
- (void)dealloc
{
+ if (connectionState != SPSSH_STATE_IDLE) [self disconnect];
[sshHost release];
[sshLogin release];
[remoteHost release];
[tunnelConnectionName release];
[tunnelConnectionVerifyHash release];
[tunnelConnection release];
+ [debugMessages release];
if (password) [password release];
if (keychainName) [keychainName release];
if (keychainAccount) [keychainAccount release];
diff --git a/Source/TableDocument.h b/Source/TableDocument.h
index 946b2492..6b6ad5f8 100644
--- a/Source/TableDocument.h
+++ b/Source/TableDocument.h
@@ -73,6 +73,8 @@
IBOutlet id sshUserField;
IBOutlet id sshPasswordField;
IBOutlet id sshPortField;
+ IBOutlet NSWindow *errorDetailWindow;
+ IBOutlet NSTextView *errorDetailText;
IBOutlet NSProgressIndicator *connectProgressBar;
IBOutlet NSTextField *connectProgressStatusText;
@@ -128,7 +130,7 @@
- (void)initiateSSHTunnelConnection;
- (void)sshTunnelCallback:(SPSSHTunnel *)theTunnel;
- (void)initiateMySQLConnection;
-- (void)failConnectionWithErrorMessage:(NSString *)theErrorMessage;
+- (void)failConnectionWithErrorMessage:(NSString *)theErrorMessage withDetail:(NSString *)errorDetail;
- (IBAction)cancelConnectSheet:(id)sender;
- (IBAction)closeSheet:(id)sender;
- (IBAction)chooseFavorite:(id)sender;
diff --git a/Source/TableDocument.m b/Source/TableDocument.m
index 52dbc229..efb2aee7 100644
--- a/Source/TableDocument.m
+++ b/Source/TableDocument.m
@@ -280,6 +280,7 @@ NSString *TableDocumentFavoritesControllerSelectionIndexDidChange = @"TableDocum
*/
- (IBAction)connectToDB:(id)sender
{
+ [self clearStatusIcon];
// load the details of the currently selected favorite into the text boxes in connect sheet
[self chooseFavorite:self];
@@ -312,11 +313,11 @@ NSString *TableDocumentFavoritesControllerSelectionIndexDidChange = @"TableDocum
// Error-check required fields before starting a connection
if (![[hostField stringValue] length] && ![[socketField stringValue] length]) {
- [self failConnectionWithErrorMessage:NSLocalizedString(@"Insufficient details provided to establish a connection. Please provide at least a host or socket.", @"insufficient details informative message")];
+ [self failConnectionWithErrorMessage:NSLocalizedString(@"Insufficient details provided to establish a connection. Please provide at least a host or socket.", @"insufficient details informative message") withDetail:nil];
return;
}
if ([sshCheckbox state] == NSOnState && ![[sshHostField stringValue] length]) {
- [self failConnectionWithErrorMessage:NSLocalizedString(@"Please enter the hostname for the SSH Tunnel, or disable the SSH Tunnel.", @"message of panel when ssh details are incomplete")];
+ [self failConnectionWithErrorMessage:NSLocalizedString(@"Please enter the hostname for the SSH Tunnel, or disable the SSH Tunnel.", @"message of panel when ssh details are incomplete") withDetail:nil];
return;
}
@@ -397,7 +398,7 @@ NSString *TableDocumentFavoritesControllerSelectionIndexDidChange = @"TableDocum
if (newState == SPSSH_STATE_IDLE) {
[self setStatusIconToImageWithName:@"ssh-disconnected"];
- [self failConnectionWithErrorMessage:[theTunnel lastError]];
+ [self failConnectionWithErrorMessage:[theTunnel lastError] withDetail:[sshTunnel debugMessages]];
} else if (newState == SPSSH_STATE_CONNECTED) {
[self setStatusIconToImageWithName:@"ssh-connected"];
[self initiateMySQLConnection];
@@ -435,7 +436,6 @@ NSString *TableDocumentFavoritesControllerSelectionIndexDidChange = @"TableDocum
withLogin:[userField stringValue]
usingPort:[sshTunnel localPort]];
[mySQLConnection setSSHTunnel:sshTunnel];
- [sshTunnel release], sshTunnel = nil;
} else {
mySQLConnection = [[CMMCPConnection alloc] initToHost:[hostField stringValue]
withLogin:[userField stringValue]
@@ -455,15 +455,45 @@ NSString *TableDocumentFavoritesControllerSelectionIndexDidChange = @"TableDocum
[mySQLConnection connect];
if (![mySQLConnection isConnected]) {
- [self failConnectionWithErrorMessage:[NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@, or the request timed out.\n\nBe sure that the address is correct and that you have the necessary privileges, or try increasing the connection timeout (currently %i seconds).\n\nMySQL said: %@", @"message of panel when connection to host failed"), [hostField stringValue], [[prefs objectForKey:@"ConnectionTimeoutValue"] intValue], [mySQLConnection getLastErrorMessage]]];
- return;
+ if (sshTunnel) {
+
+ // If an SSH tunnel is running, temporarily block to allow the tunnel to register changes in state
+ [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
+
+ // If the state is connection refused, attempt the MySQL connection again with the host using the hostfield value.
+ if ([sshTunnel state] == SPSSH_STATE_FORWARDING_FAILED) {
+ if ([sshTunnel localPortFallback]) {
+ [mySQLConnection setPort:[sshTunnel localPortFallback]];
+ [mySQLConnection connect];
+ if (![mySQLConnection isConnected]) {
+ [[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
+ }
+ }
+ }
+ }
+
+ if (![mySQLConnection isConnected]) {
+ NSString *errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@, or the request timed out.\n\nBe sure that the address is correct and that you have the necessary privileges, or try increasing the connection timeout (currently %i seconds).\n\nMySQL said: %@", @"message of panel when connection to host failed"), [hostField stringValue], [[prefs objectForKey:@"ConnectionTimeoutValue"] intValue], [mySQLConnection getLastErrorMessage]];
+ if (sshTunnel && [sshTunnel state] == SPSSH_STATE_FORWARDING_FAILED) {
+ errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@ because the port connection via SSH was refused.\n\nPlease ensure that your MySQL host is set up to allow TCP/IP connections (no --skip-networking) and is configured to allow connections from the host you are tunnelling via.\n\nYou may also want to check the port is correct and that you have the necessary privileges.\n\nChecking the error detail will show the SSH debug log which may provide more details.\n\nMySQL said: %@", @"message of panel when SSH port forwarding failed"), [hostField stringValue], [mySQLConnection getLastErrorMessage]];
+ [self failConnectionWithErrorMessage:errorMessage withDetail:[sshTunnel debugMessages]];
+ } else {
+ [self failConnectionWithErrorMessage:errorMessage withDetail:nil];
+ }
+
+ if (sshTunnel) [sshTunnel release], sshTunnel = nil;
+ [mySQLConnection release], mySQLConnection = nil;
+ return;
+ }
}
if (![[databaseField stringValue] isEqualToString:@""]) {
if ([mySQLConnection selectDB:[databaseField stringValue]]) {
if (selectedDatabase) [selectedDatabase release], selectedDatabase = nil;
selectedDatabase = [[databaseField stringValue] retain];
} else {
- [self failConnectionWithErrorMessage:[NSString stringWithFormat:NSLocalizedString(@"Connected to host, but unable to connect to database %@.\n\nBe sure that the database exists and that you have the necessary privileges.\n\nMySQL said: %@", @"message of panel when connection to db failed"), [databaseField stringValue], [mySQLConnection getLastErrorMessage]]];
+ [self failConnectionWithErrorMessage:[NSString stringWithFormat:NSLocalizedString(@"Connected to host, but unable to connect to database %@.\n\nBe sure that the database exists and that you have the necessary privileges.\n\nMySQL said: %@", @"message of panel when connection to db failed"), [databaseField stringValue], [mySQLConnection getLastErrorMessage]] withDetail:nil];
+ if (sshTunnel) [sshTunnel release], sshTunnel = nil;
+ [mySQLConnection release], mySQLConnection = nil;
return;
}
}
@@ -477,6 +507,9 @@ NSString *TableDocumentFavoritesControllerSelectionIndexDidChange = @"TableDocum
// Set up the connection.
// Register as a delegate
[mySQLConnection setDelegate:self];
+
+ // Release the tunnel if set - will now be retained by the connection
+ if (sshTunnel) [sshTunnel release], sshTunnel = nil;
// Set encoding
NSString *encodingName = [prefs objectForKey:@"DefaultEncoding"];
@@ -529,7 +562,7 @@ NSString *TableDocumentFavoritesControllerSelectionIndexDidChange = @"TableDocum
* message. The button on the error message will open the connection
* sheet again with the failed details.
*/
-- (void)failConnectionWithErrorMessage:(NSString *)theErrorMessage
+- (void)failConnectionWithErrorMessage:(NSString *)theErrorMessage withDetail:(NSString *)errorDetail
{
// Clean up the interface
[connectProgressBar stopAnimation:self];
@@ -543,9 +576,11 @@ NSString *TableDocumentFavoritesControllerSelectionIndexDidChange = @"TableDocum
// Release as appropriate
if (sshTunnel) [sshTunnel disconnect], [sshTunnel release], sshTunnel = nil;
+
+ if (errorDetail) [errorDetailText setString:errorDetail];
// Display the connection error message
- NSBeginAlertSheet(NSLocalizedString(@"Connection failed!", @"connection failed title"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, @selector(sheetDidEnd:returnCode:contextInfo:), @"connect", theErrorMessage);
+ NSBeginAlertSheet(NSLocalizedString(@"Connection failed!", @"connection failed title"), NSLocalizedString(@"OK", @"OK button"), errorDetail?NSLocalizedString(@"Show detail", @"Show detail button"):nil, nil, tableWindow, self, nil, @selector(sheetDidEnd:returnCode:contextInfo:), @"connect", theErrorMessage);
}
- (IBAction)cancelConnectSheet:(id)sender
@@ -728,6 +763,7 @@ NSString *TableDocumentFavoritesControllerSelectionIndexDidChange = @"TableDocum
{
if ([contextInfo isEqualToString:@"connect"]) {
[sheet orderOut:self];
+ if (returnCode == NSAlertAlternateReturn) [errorDetailWindow makeKeyAndOrderFront:self];
// Restore the passwords from keychain for editing if appropriate
if (connectionKeychainItemName) {