What a tool

I really like to photograph. I do so since I was a child. Then I bought my Canon ixus 500, which reawakened this old passion of mine. About a week ago or so, I bought O’Reillys Digital Photography Hacks and read through it, which was quite fun – it’s an excellent piece of work. Easy to read while still providing you with quite some knowledge.

You should defintiely read the book too, if you are interested in digital photography (some hacks apply to the old fashioned analog one too)

One thing, I noticed when reading through: There is quite a lot of stuff that can’t be done using those compact cameras. Many hacks just begin with “if you have feature X, you can…”

The feature list of this baby actually contains all those Xes from the book. Wow. That looks nice (besides being written in light-gray on white ;-) ). Expensive, but nice.

99 little emails

pilif@galadriel ~ % cat ebinerv.php
<?
 for ($i = 0; $i < 100; $i++){
   mail('xxx@sensational.ch', 'Gnegg', 'Gnegg!', 'From: xxx@xxx.ch');
   echo "rSent Mail $i";
 }
 echo "nDone!n";
?>

In principle I’m long ahead such little toys. But Ebi had this special configuration where each email that arrives at his mailbox is forwarded as an SMS to his very old mobile phone. And the phone has that nasty bug (or some may call it strange behaviour) where the “Delete all”-function does not really do it’s task.

In the end it was quite funny to see ebi manually delete neary each and every SMS he got because of my script. Maybe he will now buy a better phone or fix his configuration? We’ll see.

Copying with MOVE? Moving with copy?

Today I came across the situation where I had to copy – using delphi – some chunck of memory from one place to another. I nevery did that before (using OOP techniques gets you around that most of the time – at least in Delphi), so I had no idea how to do it. What I knew is that in C, I’d do that with memcpy. As a convinced fan of Pascals intuitive API notation, I looked in the help for MemCopy or CopyMem. Nothing (which is strange, considering things like AllocMem actually exist).

Some googling around turned out the name of the function: it’s

procedure Move(const Source; var Dest; Count: Integer);

Move? That can’t be. Can it? I want to copy, not to move. A quick glance at the help file revealed that it’s the truth: Move actually copies…

Move copies Count bytes from Source to Dest. No range checking is performed. Move compensates for overlaps between the source and destination blocks.

Descriptive procedure names? Usually, yes. But this can only be described as way beyond the optimum ;-)

Oh… on another note: What do you think, Copy does? Copying memory? No way:

function Copy(S; Index, Count: Integer): string;

function Copy(S; Index, Count: Integer): array;

S is an expression of a string or dynamic-array type. Index and Count are integer-type expressions. Copy returns a substring or subarray containing Count characters or elements starting at S[Index]. The substring or subarray is a unique copy (that is, it does not share memory with S, although if the elements of the array are pointers or objects, these are not copied as well.)

If Index is larger than the length of S, Copy returns an empty string or array.

If Count specifies more characters or array elements than are available, only the characters or elements from S[Index] to the end of S are returned.

Yeah!. Right.

Oh and on second thought: The move-thing may have its roots in the assembler language, where MOV actually copies the data too – at least I think so. But anyway: If even C got it right, why has my beloved Pascal to fail in such an easy case?

Strange preconfiguration

Ever since I’ve updated our in-office Gentoo-Box to Samba 3, I had very bad performance (throughput wise). And with bad performance I mean at most 200 KBytes/s on a 100MBit network.

For quite some time I thought that it must be my client machine, so I rested the case. Till today, where someone else complained about really bad performance. So I began investigating.

At first I had one of our ultra-cheap switches in mind, so I tested the performance using FTP. Too bad: full speed there, so it must be a Samba problem.

What was really strange: Write performance to the server was great. It was just reading that took so incredibly long. So, armed with this information I did some googling and found … only vague stuff. While there are some people with the same problem as myself, they are always told that it must be a hardware or windows problem (the two easy solutions) and there was no further discussion in all cases.

Somewhere I found the tip to set the following in smb.conf for maximum performance:

socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192

I went and looked, but the setting was already there. Too bad. The next thing I did was to comment the line out and restart samba:

#socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192

And you will not believe it, but it helped. The server is back to its old performance with 8 Mbytes per second which is a good value considering the cheap equipement involved.

Problem solved. Culprit: Strange preconfiguration by Gentoo. Why this helped? No idea! Why the wrong setting in the first place? No idea either. Why the wrong tip to put this option into smb.conf? Don’t ask me. I’m just happy, it works again.

Fun with a tablet pc

I laughed at them. Just like everyone did. I mean: Why on earth should I pay more to get less? Tablet PCs usually have a much too small monitor and are much too powerless – not to speak about resolution (I’m quite the screen resolution guy anway, considering that I’m seriously thinking about buying myself a T42p with the cool 1600×1200 resoulution, just because of that. But then: Have you ever really used Delphi? If yes, you know what I mean). And on top of that: Why on earth should I rely on handwriting recognition when everyone knows that this doesn’t work?

Then, I got a panel on my table to evaluate it’s potential as mobile device running our PopScan. While it’s not important what brand the thing actually was from (Acer in this case) and while I certainly did not have the opportunitiy to really test the thing like I did with my T40, one thing I’ve seen: Tablet PC’s are cool. Really cool.

For one there is that extremely powerful handwriting recognition engine. In contrast to all other engines I’ve seen, the one running on the tablets really works. Without training or getting used to on my part, I had a recognition rate of about 95% with the exceptions being some non-words anyway (like gnegg or “Sauklaue” which actually got recognized as Saddam [Sauklaue is what you call a really terrible handwriting in German]). The engine is so good that it actually can serve as a keyboard replacement – at least if you’re not writing too long texts (like this entry here ;-) )

But the real killer application of that thing is the included Microsoft Journal: A digital notepad (the name notepad was already taken for something… else… in Windows). You just make your notes, which goes very well using the pressure sensitive pen and because you can rest your hand on the display while writing – the tablet reacts to the pen only. Then, when you are done, you can draw a circle around the text you want to have recognized. Journal will do as you ask and replace your writing with a common text-box, leaving your drawings in place.

This is perfectly adapted for my workflow. I usually have a piece of paper lying on my desk, serving as container for all that small stuff I have to keep in mind. Line numbers, small concepts, interface definitions – quite a lot of stuff actually. Then, when the paper gets full, I usually throw it away and take a new one.

If I could do those notes on a Tablet PC, I could actually conserve them. But not only that, I could search for them – in full text (recognition is done in the background)! And it does not stop there: When I actually wrote down program code in those notes, I could immediatly reuse it, instead of manually retyping it

All this potential is realized with the really great UI the Journal has: You can insert space everywhere you want, pushing down the content below (and doing that quite intelligently), you can copy and paste your drwaings (sometimes I really whished I could do that on paper) and all that with a really simple UI. This is so incredibly great.

So to all those people laughing about the Tablet PC’s: Try them! Maybe you will be quite surprised. I for myself am quite sorry, I had to send the thing back.

Responding to search-strings (II)

While looking through the logfile analysis of gnegg.ch I saw that someone came to this site searching with

set ie proxy delphi

so I deceided that it’s time for anther episode of “Responding to search-strings” (the other being here). This time it’s about setting the IE’s proxy server from a delphi application.

When you do it manually, you access the proxy server settings from Tools / Internet Options / Connections in Internet Explorer. Whatever you change there, is used not only by IE, but by every application on your system using the WinInet API function InternetOpen with the flag INTERNET_OPEN_TYPE_PRECONFIG set. Additionally, many applications use the WinInet-API to get the Proxy Server settings and then use their own routines to actually connect to the server via the proxy they got before

So, if you want to change the Internet Explorer Proxy settings, you actually change it for the bigger part of the wohle system

When you go to Tools / Internet Options / Connections, you will immediately see that setting the proxy is going to be quite a task: You don’t just set one proxy server, you actually set one for LAN-Connections and one for each dialup connection that is installed on your system. Finally the proxy being used depends on the state of the radio buttons you see in the middle of the dialog because they define whether IE should even bother connecting to the LAN or just call one of the connections defined.

But it gets even more complicated: The proxy settings provided changed for each version of Internet Explorer. As always, it was an evolutionary process getting more complex in every iteration, so you will have to cope with that too.

But now to the details: While the settings are stored in the Registry, this is not the recommended way for changing them. Microsoft has created some API functions specifically for that, so you should use them as this is the only way guaranteed to be portable even for future versions of Windows.

The problem: The API is very painful to use – even more so because it is somewhat different for each version of IE (getting more complex along the proxy feature itself). Oh, and please don’t ask me how to get the version of the installed IE – that I do not know.

All is about InternetSetOption and InternetQueryOption respectivly. Both require a parameter to tell them which option you are interested in. Have a look at INTERNET_OPTION_PER_CONNECTION_OPTION (for IE5 and later), INTERNET_OPTION_PROXY and INTERNET_PER_CONN_OPTION

In the end, you will be calling InternetQueryOption quite a lot of times and change some settings with InternetSetOption, but you will soon see that it’s not actually worth it: There is always the possiblity that you have not anticipated some obscure setting a user may have which will distrub your application greatly

And additionally, changing the proxy server settings is a task for an adminitrator, not for a simple application. Before asking the question “How can I change the proxy server?”, the question should be “Do I really have to change the proxy server? Isn’t there a better way?”

Vendor lock-in

But, as Tom Kyte points out in his latest book, Effective Oracle by Design (Oracle Press), database dependence should be your real goal because you maximize your investment in that technology. If you make generic access to Oracle, whether through ODBC or Perl’s DBI library, you’ll miss out on features other databases don’t have. What’s more, optimizing queries is different in each database.

Needless to say on what vendors webpage I’ve seen the article the quote is coming from. One thing you learn in the practical live is that it’s extremely difficult to switch databases one you begin using the proprietary features. And you will have to switch. Sooner or later. Be it unsufficient functionality (as I’ve seen it with MySQL. I am still cursing the day when I began using SETs) or vendors going out of service or even political reasons.

While I certainly see some value in using proprietary features, let me tell you: Use them with care. Always be on the lookout for the availability of different approaches to do the same thing. If there are none, don’t do it (don’t use SETs in MySQL for example).

And if you can only get the full performance out of your RDBMS by relying on proprietary features, don’t use the RDBMS at all as it’s quite obviously not the right system. Performance must be available without being forced to use proprietary features. At least without relying on features in the query language itself – optimizations in the backend are ok for me.

This is one of the reasons I don’t use oracle, by the way. The other being this ;-)

Gentoo and Jabber

Already in 2002 I did my first experiments with jabber and I really liked what I saw when still reading the documentation. Setting up the server was a real pain, but eventually I got it working.

Then came the thing with our server and having in mind the hard work needed for setting up jabber, I deceided not to rebuild the jabber-configuration – even more so because aim-transport still does not support those fancy iChat-AIM-Accounts while Trillian does.

But today after having seen that iChat in Tiger is going to support jabber, I finally deceided that adding my beloved server back would be a cool thing…

And the whole adventure turned out to be another point where Gentoo shines above all other distributions: The ebuilds for jabber and the two transports I am using (AIM and ICQ) where already beautifully preconfigured. And not only that: They where current too (hint to debian… ;-) )

One thing did not work at the beginning: I could not register with the AIM-Transport. A quick glance at the configuration file of aim-t showed me that the preconfigured config file uses another port (5233) than the recommended settings in the main configuration file (5223).

All in all it took me about 10 minutes to get my old jabber installation back. With current versions of all the tools involved and without writing own startup scripts or other fancy stuff. This is one of the reasons I really like Gentoo

Oh… and in case you ask: My Jabber-ID is pilif@chat.sensational.ch. It’s not listed in the global user directory.

And if you’re asking what client I’m using: Though its interface may need some improvement, jajc is in my oppinion the best client you can get if you are using windows

Refactoring – It’s worth it

Just shortly after complaining about not having time to do some refactoring, I reached a place in my code where it was absolutely impossible to add feature x without cleaning up the mess I created three years ago. And – what’s even better: I had the time do really fix it. Cleanly

What I did was to sit down and recreate the whole module in a new Delphi project. I knew what features I wanted to have when finished and I somewhat knew the interface I had to comply to. The latter proofed inpractical, so I did some modifications to the interface itself (the thing was hacky too). Redoing the whole module took about a week (it’s about downloading stuff, exctracting and then XML-parsing it – everything in a thread while still providing feedback to the main thread), but it was absolutely worth it:

  • The code is clean. And with clean I mean so clean that adding further features will still be clean, depite not being needed as the new framework I’ve created is extremely powerful.
  • The thing is fast. Twelve times faster than the old version. I’m processing 7000 datasets in just 20 seconds now (including time needed for downloading and decompressing) which took me four minutes before.
  • The thing is more usable. Status reporting to the end user went from nearly nothing to everything the user may need. And she can now cancel the process – of course.

A task fully worth of undertaking. I’ve not been that pleased with my code for quite some time now

SonyEricsson, IMAP, Exchange

Since we switched to Exchange I’ve been unable to get my Email from my SonyEricsson-phones (first T610, then Z600 – talk about buying too many mobiles per time unit ;-). Every time I tried to connect, I immediatly got a Server not found

Today I’d had enough. This must be fixed, I told myself and set to fix it. And as the category for this enty is “Solutions”, I actually did solve it.

A quick check with netcat on the firewall (after turning off the port forwarding rules) revealed that it’s not actually a connection problem I was running into: The phone connected fine. So it must be something with Exchange…

The event log on the server revealed nothing at all. As always with Microsoft products. Those messages are either not there or completely ununderstandable.

Next I tried to set the server to maximum logging (Exchange-Manager, right click on your Server, Properties, Tab “Diagnostics Logging”, IMAP4Svc). The result were two entries in the event log: Client XXX connected, Client XXX disconnected. Extremely helpful. Nearly as helpful as the “Server not found” my cellphone was throwing at me (see note below).

I noticed that this isn’t getting me anywhere, so I went getting the cannon to shoot sparrows with: I’ve downloaded Ethereal and listened to the conversation my phone is having with exchange:

S: * OK Microsoft Exchange Server 2003 IMAP4rev1 server version x.x (xxx) ready.
C: A128 AUTH xxxx xxxx
S: A128 BAD Protocol Error: "Expected SPACE not found".

(I won’t ask, why the phone isn’t checking the capabilities first before logging in. This is not what I call a clean impementation)

Not very helpful either. At least for me, knowing the IMAP-RFC just enough to understand what the A128 stands for (it’s a transaction number which allows for asynchronous command execution. The server prefixes answers to commands with the number given by the client), but not much else. So I had to do something else: Logging in with Mozilla Thunderbird, where I had no problems. After one failed attempt where I forgot to turn off SSL (…), I got this:

S: * OK Microsoft Exchange Server 2003 IMAP4rev1 server version x.x (xxx) ready.
C: 1 capability
S: * CAPABILITY (...) AUTH=NTLM
S: 1 OK CAPABILITY completed.
C: 2 login "xxx\xx" "xxx"
S: 2 OK LOGIN completed.

(now that I’m reading through this (still without having read the RFC): Isn’t the server lying here: It just tells to be acceping NTLM-Auth, but Mozilla seems to ignore that and using AUTH=LOGIN to log in which the server accepts too. Enlighten me!)

Aha! We seem to be having quoting issues in the phone. Good. Even better: The issue seems to be that the phone does no quoting at all, which is fine because then we can do some quoting in the preferences-screen

After one failed attempt with two spaces after the username in the LOGIN-Line which was fixed by removing the somehow added trailing space in the phone’s username-field, I actually got it working. Yes. I’m reading my mail with the phone. It did work!

So, if you are having problems connecting to an Exchange-Server using SonyEricssons Phones, do the following:

  • Enter the username as "DOMAIN\username" (with quotes). Look that there are no spaces before the first and after the last quote.
  • Enter the password as "password". Include the quotes too and remove spaces that may linger aroung

In other words:

  • Escape -es with anoter one of them: -> \
  • Put username and Password in double quotes (“)

Dann klappt’s auch mit dem Nachbarn! (from a stupid german commercial. Forget it if you don’t understand it)

One final note: <rant>Everything would have been so much easier if only there were more usefil error messages involved. While I completly understand that the designers of the software don’t want to overwhelm their users and thus create seemingly simple messages, they should absolutely provide a “Details”-Link somewhere where the whole message can be read. Granted. Cellphones are limited, so in a way, I can accept the message I got there. What I can not accept is the way Exchange loggs the errors it occurs. Why on earth doesnt’ a protocol error getting logged when logging is set to “Maximum”?</rant>