Friday, February 05, 2010

Getting Erlang crypto to work on windows

Had a bit of trouble getting Webmachine to work on a windows box. Kept on running into this error -
=ERROR REPORT==== 5-Feb-2010::22:29:24 ===
Unable to load crypto_drv. Failed with error:
"The specified module could not be found."
OpenSSL might not be installed on this system.
{"init terminating in do_boot",{{case_clause,{error,{shutdown,{crypto_app,start,[normal,[]]}}}},[{webmstn,ensure_started,1},{webmstn,start,0},{init,start_it,1},{init,start_em,1}]}}
And being the smart ass that I am, I went searching on the net instead of simply installing OpenSSL.

Here's a very educational post I found on finding if a specific module is installed and loading its DLLs with erlang. This guy had the same problem as me and he finally solved it by installing OpenSSL for Win32! Surprise!

---- Quoting ----
I have a problem with trying to use the mysql driver available on google code (http://code.google.com/p/erlang-mysql-driver/)

I have the windows installation of erlang (tried both with R12B-5 and R13A) on my PC running on Windows XP.

When try to connect to my database it fails.
I have searched the web for hints and found others with similar problems. It seems that the crypto driver is not compiled or linked properly for my machine.

Somewhere on the web I found the following test to verify if crypto works:

4> crypto:start(),
4> crypto:sha("abc").

=PROGRESS REPORT==== 20-Mar-2009::10:14:01 ===
supervisor: {local,crypto_sup}
started: [{pid,<0.61.0>},
{name,crypto_server},
{mfa,{crypto_server,start_link,[]}},
{restart_type,permanent},
{shutdown,2000},
{child_type,worker}]

=PROGRESS REPORT==== 20-Mar-2009::10:14:01 ===
application: crypto
started_at: nonode@nohost
<<169,153,62,54,71,6,129,106,186,62,37,113,120,80,194,108,
156,208,216,157>>

On my machine I get the following:

13> crypto:start(),
13> crypto:sha("abc").

=INFO REPORT==== 19-Mar-2009::21:38:13 ===
application: crypto
exited: {shutdown,{crypto_app,start,[normal,[]]}}
type: temporary
** exception error: bad argument
in function port_control/3
called as port_control(crypto_drv02,5,"abc")
in call from crypto:control/2
14>

I found some other information on the web on how to check if the crypto_drv.dll was loaded properly.

7> erl_ddll:start(),
7>
7> PrivDir = code:priv_dir(crypto),
7>
7> LibDir1 = filename:join([PrivDir, "lib"]),
7>
7> ls(LibDir1).
crypto_drv.dll
ok
8>
8> Mess = erl_ddll:load_driver(LibDir1, crypto_drv).
{error,{open_error,-136}}
9>
9> {_, Err} = Mess.
{error,{open_error,-136}}
10>
10> erl_ddll:format_error( Err).
"The specified module could not be found."
11>

Looking at this is looks like the file location is correct but the file can not be loaded.

Any suggestions what to do?
Is the crypto_drv.dll not correct linked/compiled for my machine?
If so where can I find a new?
---- End Quoting ----

Well at least it was educational...

Bash! You are killing me! How to escape spaces in filenames being passed to tar


Bash can be really frustrating!

I'm trying to take all the files that match a pattern and put them in a tar.gz file. Sounds simple?
aj@aj-laptop:/home/aj$ find . -name "*tips*"
./data/DRAFT/tips and tricks.doc
./data/DRAFT/tips new.doc

Looks okay till here. But -

aj@aj-laptop:/home/aj$ find . -name "*tips*" | xargs tar czvvf tips.tar.gz
tar: ./data/DRAFT/tips: Cannot stat: No such file or directory
tar: and: Cannot stat: No such file or directory
tar: tricks.doc: Cannot stat: No such file or directory
tar: ./data/DRAFT/tips: Cannot stat: No such file or directory
tar: new.doc: Cannot stat: No such file or directory
tar: Error exit delayed from previous errors
aj@aj-laptop:/home/aj$
Apparently it would not work fine when your filenames have spaces in them because then it would tokenise them with spaces and hence break up the file names.

So I search around on the web and find a bunch of things to try on a stackoverflow thread.

And here's the solution that worked -
aj@aj-laptop:/home/aj$ find . -name "*tips*" -print0 | xargs -0 tar czvvf tips.tar.gz
-rwx------ aj/aj 31232 2010-01-12 19:23 ./data/DRAFT/tips and tricks.doc
-rwx------ aj/aj 30208 2008-10-08 16:57 ./data/DRAFT/tips new.doc
aj@aj-laptop:/home/aj$
Basically adding -print0 to the find command makes it separate strings by NULLs (\0s) which can never be a part of the filenames and can never cause problems.Note that you also need to tell xargs to separate strings by NULLs by passing the -0 flag.

But now since I couldn't find any such flags for other standard linux commands like grep, this solution is only useful when I need to pass the output from find straight into tar. For example I cannot do find . -name "*tips*" -print0 | grep 'tricks' | xargs -0 tar czvvf tips_and_tricks.tar.gz !

Sad! But I am done for the day with this problem. Please let me know in the comments if there is a general solution to this.

Wednesday, February 03, 2010

How to escape the Matrix (a.k.a. Escaping the '#' hash character in a wget commandline)


I have a file "ftp://ftpserver/applicationdocs/detail#1" which I need to retrieve using wget but the # character is proving impossible!

Wget tries to retrieve a file with the name "detail" instead of "detail#1". I get the same results with all of the following -

wget ftp://ftpserver/applicationdocs/detail#1
wget ftp://ftpserver/applicationdocs/detail\#1
wget 'ftp://ftpserver/applicationdocs/detail#1'
wget "ftp://ftpserver/applicationdocs/detail#1"

I noticed that echo 'ftp://ftpserver/applicationdocs/detail#1' gives the expected output so I also tried the following -

echo 'ftp://ftpserver/applicationdocs/detail#1' | wget -i -

but to no avail. Sucks.

But then! Inspiration strikes!

%23 is hex code of #. And very surprisingly, this works -

wget ftp://ftpserver/applicationdocs/detail%231

A quick post to the ILUGD list verifies that this is the only quick solution commonly known.