Sunday, July 5, 2009

Haskell telnet client to run a command on a remote system

I've written a very simple little program using the Haskell Network.Socket library, that logs in to a remote system via telnet and runs a single command. It's the first Haskell that I've written in quite a long time, and it's nothing very impressive. In fact the hard part was getting the Socket library built on Windows Vista, it was all quite simple on Ubuntu.

Anyway, here's the current version of the code:

module Main where
import Control.Concurrent
import Data.Char
import Network
import Network.Socket
import System.IO
import System(getArgs)

telnetIAC :: Int
telnetIAC = 255

telnetWONT :: Int
telnetWONT = 252

newtype Credentials = Credential (String, String)

password :: Handle -> String -> IO ()
password h pwd = do
char <- hGetChar h
case char of
':' -> do hPutStrLn h pwd
hFlush h
otherwise -> password h pwd


login :: Handle -> Credentials -> IO ()
login h c@(Credential (user, pwd)) = do
hPutStrLn h user
hFlush h
password h pwd
putStrLn "Logged in"


declineHandshakeOption :: Handle -> Credentials -> IO ()
declineHandshakeOption h c = do
ignoreChar <- hGetChar h
optionChar <- hGetChar h
hPutChar h $ chr telnetIAC
hPutChar h $ chr telnetWONT
hPutChar h $ optionChar
hFlush h
handshakeAndLogin h c

handleHandshakeInput :: Handle -> Char -> Credentials -> IO()
handleHandshakeInput h char credentials
| ord char == telnetIAC = declineHandshakeOption h credentials
| char == ':' = login h credentials
| otherwise = handshakeAndLogin h credentials


handshakeAndLogin :: Handle -> Credentials -> IO ()
handshakeAndLogin h credentials = do
char <- hGetChar h
handleHandshakeInput h char credentials

main :: IO ()
main = withSocketsDo $ do
args <- getArgs
addrinfos <- getAddrInfo Nothing (Just (args !! 0)) (Just "23")
let serveraddr = head addrinfos
sock <- socket (addrFamily serveraddr) Stream defaultProtocol
connect sock (addrAddress serveraddr)
putStrLn "Connected"
h <- socketToHandle sock ReadWriteMode
hSetBuffering h (BlockBuffering Nothing)
handshakeAndLogin h $ Credential (args !! 1, args !! 2)
hPutStrLn h (args !! 3)
hFlush h
putStrLn "Command sent"
threadDelay 1000000
To compile:
ghc -package network -o TelnetClient TelnetClient.hs

To run:
./TelnetClient localhost username password "./command.sh"

Problems building Haskell packages on Windows

I made a silly mistake today, and wasted quite a long time trying to build the Haskell network package using "cabal install" via cygwin. I eventually found out that in most cases you should use MingW and MSYS rather than cygwin (http://haskell.org/haskellwiki/Windows).

Sunday, June 14, 2009

Where does Eclipse store its launch configurations?

It's a simple question, and the answer is out there on the net, but it took me awhile to find it. Eclipse launch configurations at the workspace level are stored in .metadata\.plugins\org.eclipse.debug.core\.launches.

I had assumed they were in org.eclipse.jdt.core and completely bypassed the debug package while searching around for it on my filesystem. Obviously that was a mistake!

Note that this refers to launch configurations saved by Eclipse as you work. You can also save your configurations to an external file, using the "common" tab of the run dialog, and saving to a "shared file".

Wednesday, June 3, 2009

Firefox 3 crashing when using jQuery 1.3+ and ASP.Net

Well, I had a very interesting problem today. I upgraded from jQuery 1.2.6 to 1.3.2, to fix some problems using jQuery in IE8. The 1.2.x series of jQuery does browser sniffing to determine how to do certain things, and since IE8 is now "more standards-compliant", some of these hacks do not work unless the "compatibility view" is used.

jQuery 1.3.x fixed all of this by using JavaScript object detection rather than browser sniffing, so that's great.

However.. due to the design of the buttons in our application, they are in fact a div that contain both text and an ASP.Net image button. The onclick handler for the div locates the image button using a jQuery selector and clicks it via javascript.

With jQuery 1.3.2 and Firefox 3, this causes a browser crash that can't be recovered from, you have to kill the browser in task manager. The interesting thing is, the postback does occur, my ASP.Net event handler runs, but the browser crashes completely, hogging the CPU until you have to kill it. Lovely!

What I found is that if you call .click() on the DOM element directly, the problem is solved -- I was calling .click() on the collection returned by the jQuery selector.

Changed from this: $('#saveButton').click()
To this: $('#saveButton')[0].click()

phew, problem solved!

Tuesday, May 26, 2009

SQL tuning training slides

I'm writing this post so I can share the slides for a training session I gave to some colleagues last year about SQL statement and performance tuning.

Unfortunately the examples are missing, which includes the most useful part of the presentation -- particularly, how to generate and interpret MySQL explain plans.

However, somebody might still find this useful one day.


Sunday, April 5, 2009

No protocol binding matches the given address

If you see the following error when trying to call a WCF web service in the ASP.Net Development Web Server...

System.ServiceModel.ServiceActivationException: No protocol binding matches the given address 'http://0.0.0.0:2825/Services/Blah.svc/jsdebug'. Protocol bindings are configured at the Site level in IIS or WAS configuration. ---> System.InvalidOperationException: No protocol binding matches the given address 'http://0.0.0.0:2825/Services/Blah.svc/jsdebug'. Protocol bindings are configured at the Site level in IIS or WAS configuration.
--- End of inner exception stack trace ---
at System.ServiceModel.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.ExecuteSynchronous(HttpApplication context, Boolean flowContext)
at System.ServiceModel.Activation.HttpHandler.ProcessRequest(HttpContext context)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)


Try rebooting your machine. Yes, seriously. I found no other information to help me solve this problem, and a simple reboot fixed it. A colleague of mine has also had the same problem before, with the same "fix".

I miss Java.

Sunday, August 31, 2008

Maven Jetty Plugin - Embedded error: Bad temp directory

For the record, this error is caused by running mvn jetty:run-war from the top-level directory of a modular project, rather than your web project directory.

http://markmail.org/message/ubjlpzebsgv5idxz