<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Krzysztof Kowalczyk blog</title><link href="http://blog.kowalczyk.info/atom.xml" rel="alternate"></link><id>http://blog.kowalczyk.info/atom.xml</id><updated>2009-06-23T02:37:12Z</updated><entry><title>15minutes for mac now available</title><link href="http://blog.kowalczyk.info/article/15minutes-for-mac-now-available.html" rel="alternate"></link><updated>2009-06-23T02:37:12Z</updated><id>tag:blog.kowalczyk.info,2009-06-23:/article/15minutes-for-mac-now-available.html</id><summary type="html">&lt;p&gt;My simple productivity application &lt;a href="http://blog.kowalczyk.info/software/15minutes/"&gt;15minutes&lt;/a&gt; used to only run on Windows. I just finished writing Mac OS X version so a blog post announcing it seems appropriate.&lt;/p&gt;</summary></entry><entry><title>Cocoa and Objective-C reference</title><link href="http://blog.kowalczyk.info/article/Cocoa-and-Objective-C-reference.html" rel="alternate"></link><updated>2009-06-15T03:00:14Z</updated><id>tag:blog.kowalczyk.info,2009-06-15:/article/Cocoa-and-Objective-C-reference.html</id><summary type="html">&lt;p&gt;I&amp;#8217;ve started programming in Cocoa again. I&amp;#8217;m only an advanced beginner in that framework so I often have to look up how to achieve even simple things. To make programming a little bit faster, I started working on a &lt;a href="/articles/cocoa-reference.html"&gt;Cocoa quick reference&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It lists the most frequently used methods and classes in Cocoa, with links to official Apple docs.&lt;/p&gt;

&lt;p&gt;On a side note, I think that existing quick reference guides on the web aren&amp;#8217;t very good. I have a few ideas on how they could be improved and hope to use those ideas in my Cocoa reference.&lt;/p&gt;</summary></entry><entry><title>Shared http caching</title><link href="http://blog.kowalczyk.info/article/Shared-http-caching.html" rel="alternate"></link><updated>2009-06-13T21:27:24Z</updated><id>tag:blog.kowalczyk.info,2009-06-13:/article/Shared-http-caching.html</id><summary type="html">&lt;p&gt;In March I &lt;a href="/article/How-content-based-addressing-can-help-web-perfor.html"&gt;wrote&lt;/a&gt; about an idea for tagging links with their sha1 checksum for better caching in web browser. Now I&amp;#8217;m &lt;a href="http://bouncybouncy.net/ramblings/posts/shared_http_caching/"&gt;not alone&lt;/a&gt;.&lt;/p&gt;</summary></entry><entry><title>Network drives, .net, security and virtualbox</title><link href="http://blog.kowalczyk.info/article/Network-drives-net-security-and-virtualbox.html" rel="alternate"></link><updated>2009-06-05T06:28:28Z</updated><id>tag:blog.kowalczyk.info,2009-06-05:/article/Network-drives-net-security-and-virtualbox.html</id><summary type="html">&lt;p&gt;I have Windows 7 installed on my MacBook under VirtualBox. To keep things simple, I keep my code on mac side, sharing the directory with Windows side.&lt;/p&gt;

&lt;p&gt;Tip #1: VirtualBox 2.2.4 has weak implementation of shared folders. For example, Visual Studio 2008 sees the files on shared drive as write-protected (even though other applications don&amp;#8217;t). Visual Studio 2010 doesn&amp;#8217;t have this problem, but it can&amp;#8217;t finish compilation, complaining it cannot write some intermediary build files to a shared folder. Also, trying to mark shared folder as trustworthy for .NET doesn&amp;#8217;t seem to work (see below).&lt;/p&gt;

&lt;p&gt;Solution: use Mac&amp;#8217;s built-in file sharing instead and shared things out using built-in samba (smb) sharing in System Preferences/Sharing.&lt;/p&gt;

&lt;p&gt;Another problem is that .NET by default doesn&amp;#8217;t trust code on network drives and Visual Studio will tell you that &amp;#8220;The Project Location is Not Trusted&amp;#8221; if you open a project from a network drive. The magic incantation to make a given shared folder (in my case it&amp;#8217;s drive z:) trusted is:&lt;/p&gt;

&lt;p&gt;&lt;pre class="prettyprint"&gt;
caspol -q -machine -addgroup 1.2 -url file://z:/* FullTrust&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;This command has to be executed as Administrator.&lt;/p&gt;

&lt;p&gt;One way to have &lt;code&gt;caspol.exe&lt;/code&gt; available in the &lt;span&gt;&lt;span class="caps"&gt;PATH&lt;/span&gt;&lt;/span&gt; is to start Visual Studio cmd-line (shortcut is installed in Start menu).&lt;/p&gt;</summary></entry><entry><title>Setting unicode rtf text in rich edit control</title><link href="http://blog.kowalczyk.info/article/Setting-unicode-rtf-text-in-rich-edit-control.html" rel="alternate"></link><updated>2009-04-15T06:36:41Z</updated><id>tag:blog.kowalczyk.info,2009-04-15:/article/Setting-unicode-rtf-text-in-rich-edit-control.html</id><summary type="html">&lt;p&gt;Despite being around for thousands of years, win32 &lt;span class="caps"&gt;API&lt;/span&gt; is poorly documented in many areas.&lt;/p&gt;

&lt;p&gt;Today I spent an hour battling a baffling problem with rich edit control.&lt;/p&gt;

&lt;p&gt;I was setting rtf-formatted text using &lt;code&gt;WM_SETTEXT&lt;/code&gt; message.&lt;/p&gt;

&lt;p&gt;In non-unicode build, where text was ansi, it worked and the text showed up nicely formatted.&lt;/p&gt;

&lt;p&gt;In unicode build, however, the text wasn&amp;#8217;t parsed as rtf and showed verbatim.&lt;/p&gt;

&lt;p&gt;An hour of trying various ways to make it work ended with me finding a working work-around: using &lt;code&gt;EM_SETTEXTEX&lt;/code&gt; and utf-8 encoded text with &lt;code&gt;CP_UTF8&lt;/code&gt; code-page. I&amp;#8217;m using &lt;span class="caps"&gt;WTL&lt;/span&gt; so the code ended up being:&lt;/p&gt;

&lt;p&gt;&lt;pre class="prettyprint"&gt;
#ifdef UNICODE
		// Don't know why I have to do this, but SetWindowText() with unicode
		// doesn't work (rtf codes are not being recognized)
		const char *sUtf = WstrToUtf8(s);
		m_statusMsgEdit.SetTextEx((LPCTSTR)sUtf, ST_DEFAULT, CP_UTF8);
#else
		m_statusMsgEdit.SetWindowText(s);
#endif&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="caps"&gt;MSDN&lt;/span&gt; &lt;a href="http://msdn.microsoft.com/en-us/library/bb774284.aspx"&gt;claims&lt;/a&gt; I could have used code-page 1200 for unicode text, but that didn&amp;#8217;t work either.&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s quite possible I&amp;#8217;ve botched something somewhere in my code and this work-around isn&amp;#8217;t needed but I can hardly think of anything. If you ever run into problem like this, the above is one thing to try.&lt;/p&gt;</summary></entry><entry><title>Accessing Mac file shares from Windows 7</title><link href="http://blog.kowalczyk.info/article/Accessing-Mac-file-shares-from-Windows-7.html" rel="alternate"></link><updated>2009-04-11T22:40:54Z</updated><id>tag:blog.kowalczyk.info,2009-04-11:/article/Accessing-Mac-file-shares-from-Windows-7.html</id><summary type="html">&lt;p&gt;Windows 7 beta 7000 can&amp;#8217;t access files shared from Mac through built-in samba file sharing out of the box. It&amp;#8217;s rather infuriating, because XP has no such problem and the error message given by windows when you try to navigate to a folder shared from mac is cryptic and not helpful at all. Turns out the culprit is purely how Windows 7 security is configured by default. Good news is it can be fixed via configuration tweaks as &lt;a href="http://www.pronetworks.org/forums/windows-7-and-mac-os-x-sharing-t104898.html"&gt;described here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In case this post goes away, here&amp;#8217;s what it says:&lt;/p&gt;

&lt;p&gt;Windows 7 will not work with Mac OS X Windows file sharing support by default. If you attempt to access a folder shared from Mac OS X, Vista will display a logon error repeatedly. The problem is that Vista, by default, will only use NTLMv2 for authentication, which is not supported by Mac OS X&amp;#8217;s Windows Sharing service. The other problem is the Minimum Session Security for &lt;span class="caps"&gt;NTVLM&lt;/span&gt; &lt;span class="caps"&gt;SSP&lt;/span&gt; based Clients.&lt;br /&gt;
To get around this:&lt;/p&gt;

&lt;p&gt;1. In Vista, open the Control Panel&lt;br /&gt;
2. Switch to &amp;#8220;Classic&amp;#8221; view&lt;br /&gt;
3. Double-click Administration Tools&lt;br /&gt;
4. Double-click Local Security Policy&lt;br /&gt;
5. Or Secpol.msc&lt;br /&gt;
6. Expand &amp;#8220;Local Policies&amp;#8221; and select &amp;#8220;Security Options&amp;#8221;&lt;br /&gt;
7. Alternate : Type secpol.msc to get editor up then&lt;br /&gt;
8. Locate &amp;#8220;Network Security: &lt;span class="caps"&gt;LAN&lt;/span&gt; Manager Authentication Level&amp;#8221; in the list and double-click it.&lt;br /&gt;
9. Change the setting from &amp;#8220;Send NTMLv2 response only&amp;#8221; to &amp;#8220;Send LM &amp;amp; &lt;span class="caps"&gt;NTLM&lt;/span&gt; &amp;#8211; use NTLMv2 session if negotiated&amp;#8221;&lt;br /&gt;
10. Network Security: Minimum session security for &lt;span class="caps"&gt;NTLM&lt;/span&gt; &lt;span class="caps"&gt;SSP&lt;/span&gt; Based (including secure &lt;span class="caps"&gt;RPC&lt;/span&gt;) Clients&lt;br /&gt;
11. Change the setting from &amp;#8220;require 128 bit&amp;#8221; to unchecked (No Minimum)&lt;br /&gt;
12. Click OK&lt;/p&gt;

&lt;p&gt;the real difference between vista and windows 7 procedure is 10 and 11&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s rather evil for Microsoft to choose defaults that make file sharing not interoperable with latest Mac OS X. It&amp;#8217;s not like they didn&amp;#8217;t test it so it must have been a conscious decision to screw with Mac users.&lt;/p&gt;</summary></entry><entry><title>15minutes - a simple productivity tool</title><link href="http://blog.kowalczyk.info/article/15minutes-a-simple-productivity-tool.html" rel="alternate"></link><updated>2009-04-09T05:48:04Z</updated><id>tag:blog.kowalczyk.info,2009-04-09:/article/15minutes-a-simple-productivity-tool.html</id><summary type="html">&lt;p&gt;&lt;img src="http://blog.kowalczyk.info/static/gfx/15minutes.png" alt="" /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.kowalczyk.info/software/15minutes/"&gt;15minutes&lt;/a&gt; is a simple productivity tool I wrote.&lt;/p&gt;

&lt;p&gt;One of productivity techniques is &lt;a href="http://www.davecheong.com/2006/07/26/time-boxing-is-an-effective-getting-things-done-strategy/"&gt;time boxing&lt;/a&gt;. &lt;a href="http://www.pomodorotechnique.com/"&gt;Pomodoro technique&lt;/a&gt; is a similar idea.&lt;/p&gt;

&lt;p&gt;Procrastination is avoiding work. To avoid procrastination you just have to start working.&lt;/p&gt;

&lt;p&gt;One reason we avoid work is because the tasks seem big and overwhelming. Time boxing is a mental trick &amp;#8211; instead of thinking about doing the whole task, we focus about working on a task for a fixed, short period of time.&lt;/p&gt;

&lt;p&gt;To implement time boxing you need a timer which will alert you about the end of time boxing period.&lt;/p&gt;

&lt;p&gt;Any timer will do &amp;#8211; a physical timer, iPhone&amp;#8217;s built-in clock etc.&lt;/p&gt;

&lt;p&gt;I wrote a small application to do it, since most of my work is done on a computer. &lt;a href="http://blog.kowalczyk.info/software/15minutes/"&gt;15minutes&lt;/a&gt; is that application.&lt;/p&gt;</summary></entry><entry><title>Recent mupdf work</title><link href="http://blog.kowalczyk.info/article/Recent-mupdf-work.html" rel="alternate"></link><updated>2009-04-06T05:21:28Z</updated><id>tag:blog.kowalczyk.info,2009-04-06:/article/Recent-mupdf-work.html</id><summary type="html">&lt;p&gt;I&amp;#8217;ve been working a little bit on Sumatra and mupdf recently. The result of which are &lt;a href="http://bugs.ghostscript.com/buglist.cgi?bug_status=NEW&amp;amp;bug_status=ASSIGNED&amp;amp;bug_status=REOPENED&amp;amp;email1=kkowalczyk%40gmail.com&amp;amp;emailtype1=exact&amp;amp;emailassigned_to1=1&amp;amp;emailreporter1=1"&gt;9 patches&lt;/a&gt; submitted to mupdf upstream.&lt;/p&gt;</summary></entry><entry><title>Valgrind on mac</title><link href="http://blog.kowalczyk.info/article/Valgrind-on-mac.html" rel="alternate"></link><updated>2009-03-28T04:04:36Z</updated><id>tag:blog.kowalczyk.info,2009-03-28:/article/Valgrind-on-mac.html</id><summary type="html">&lt;p&gt;As of Mar 27 2009 Valgrind doesn&amp;#8217;t officially support mac but a port that is good enough is in progress. You can learn more and monitor the progress by reading &lt;a href="http://blog.mozilla.com/nnethercote/"&gt;Nicholas Nethercote&amp;#8217;s blog&lt;/a&gt; (main person working on Valgrind mac port).&lt;/p&gt;

&lt;p&gt;This post is a summary of how I built Valgrind on Mac (OS X 10.5.6).&lt;/p&gt;

&lt;p&gt;Since this involves compiling, you probably need developer tools. I have both XCode and a healthy does of &lt;a href="http://www.macports.org/"&gt;MacPorts&lt;/a&gt; dev packages installed. I&amp;#8217;m not sure how much you need, but I&amp;#8217;m guessing at least gcc, make, autotools.&lt;/p&gt;

&lt;p&gt;&lt;pre class="prettyprint"&gt;
svn co svn://svn.valgrind.org/valgrind/trunk valgrind
cd valgrind
./autogen.sh
./configure
make
sudo make install&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;So far I&amp;#8217;ve only tried Valgrind on mupdf and it worked, so this is very promising. Valgrind is invaluable tool for C/C++ memory leak detection, detecting memory mismanagement issues and profiling the code.&lt;/p&gt;

&lt;p&gt;An unfortunate deficiency is lack of a &lt;span class="caps"&gt;GUI&lt;/span&gt; for inspecting callgrind results (i.e. &lt;code&gt;kcachegrind&lt;/code&gt; equivalent on mac). Maybe the cheapest way to get that would be to convert callgrind results to shark format so that shark tools can be used. Should be possible &amp;#8211; I believe WebKit&amp;#8217;s JavaScript implementation saves profiling results in shark format, so there is code that could be used as a template for that.&lt;/p&gt;</summary></entry><entry><title>Unladden-swallow - making Python faster</title><link href="http://blog.kowalczyk.info/article/Unladden-swallow-making-Python-faster.html" rel="alternate"></link><updated>2009-03-28T03:02:47Z</updated><id>tag:blog.kowalczyk.info,2009-03-28:/article/Unladden-swallow-making-Python-faster.html</id><summary type="html">&lt;p&gt;When I&amp;#8217;m right, I&amp;#8217;m right. About a year ago &lt;a href="article/Why-Google-should-sponsor-a-faster-Python-VM.html"&gt;I said&lt;/a&gt; that Google should sponsor faster Python VM. And that&amp;#8217;s &lt;a href="http://code.google.com/p/unladen-swallow"&gt;exactly what they did&lt;/a&gt; by having 2 full time engineers &lt;a href="http://code.google.com/p/unladen-swallow/wiki/FAQ"&gt;working on unladden-swallow&lt;/a&gt;, a project to make Python much faster, with full intention to get all their improvements into mainline Python.&lt;/p&gt;

&lt;p&gt;The project looks very promising.&lt;/p&gt;

&lt;p&gt;It also shows that small teams can do great things. 2 people team is as small as it gets and if they manage to achieve their goal, they&amp;#8217;ll make a big difference in many programmer&amp;#8217;s lives.&lt;/p&gt;</summary></entry><entry><title>Interesting mac source code</title><link href="http://blog.kowalczyk.info/article/Interesting-mac-source-code.html" rel="alternate"></link><updated>2009-03-16T03:06:44Z</updated><id>tag:blog.kowalczyk.info,2009-03-16:/article/Interesting-mac-source-code.html</id><summary type="html">&lt;p&gt;Interesting mac sourcecode:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://code.google.com/p/understudy/"&gt;Understudy&lt;/a&gt; &amp;#8211; &lt;span class="caps"&gt;GPL&lt;/span&gt;, front row plugin that adds support for Hulu, Netflix, YouTube.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ditchnet.org/httpclient/"&gt;&lt;span class="caps"&gt;HTTP&lt;/span&gt; Client&lt;/a&gt; &amp;#8211; &lt;span class="caps"&gt;BSD&lt;/span&gt;, UI for sending &lt;span class="caps"&gt;HTTP&lt;/span&gt; requests and inspecting &lt;span class="caps"&gt;HTTP&lt;/span&gt; requests/responses&lt;/p&gt;

&lt;p&gt;&lt;a href="http://code.google.com/p/macshark/"&gt;MacShark&lt;/a&gt;, network sniffer, nmap, dig, whois etc., New &lt;span class="caps"&gt;BSD&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://code.google.com/p/eavesdrop/"&gt;Eavesdrop&lt;/a&gt;, GPLv2, network sniffer&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ridiculousfish.com/hexfiend/"&gt;hexfiend&lt;/a&gt;, &lt;span class="caps"&gt;BSD&lt;/span&gt;, hex editor&lt;/p&gt;

&lt;p&gt;&lt;a href="http://code.google.com/p/sourcelist/"&gt;iLife 08-like source list&lt;/a&gt;, New &lt;span class="caps"&gt;BSD&lt;/span&gt;, ui widget&lt;/p&gt;

&lt;p&gt;&lt;a href="http://code.google.com/p/apphider/"&gt;AppHider&lt;/a&gt; &amp;#8211; moves apps from doc to menubar&lt;/p&gt;

&lt;p&gt;&lt;a href="http://code.google.com/p/roaringdiff/"&gt;RoaringDiff&lt;/a&gt; &amp;#8211; graphical diff&lt;/p&gt;

&lt;p&gt;&lt;a href="http://code.google.com/p/readernotifier/"&gt;ReaderNotifier&lt;/a&gt; &amp;#8211; shows Google Reader status in menu bar&lt;/p&gt;

&lt;p&gt;&lt;a href="http://code.google.com/p/qsb-mac/"&gt;Quick Search Box&lt;/a&gt; &amp;#8211; from Google&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.ragingmenace.com/software/menumeters/"&gt;MenuMeters&lt;/a&gt; &amp;#8211; &lt;span class="caps"&gt;GPL&lt;/span&gt;, shows stuff in menu bar&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.cocoadev.com/index.pl?HTTPFileUploadSample"&gt;Http upload sample&lt;/a&gt;&lt;/p&gt;</summary></entry><entry><title>Silverlight info</title><link href="http://blog.kowalczyk.info/article/Silverlight-info.html" rel="alternate"></link><updated>2009-03-14T23:16:43Z</updated><id>tag:blog.kowalczyk.info,2009-03-14:/article/Silverlight-info.html</id><summary type="html">&lt;p&gt;&lt;a href="http://blogs.msdn.com/jstegman/archive/2008/04/21/dynamic-image-generation-in-silverlight.aspx"&gt;http://blogs.msdn.com/jstegman/archive/2008/04/21/dynamic-image-generation-in-silverlight.aspx&lt;/a&gt; has code to dynamically generate bitmaps in Silverlight.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://code.google.com/p/fjcore/"&gt;FJCore&lt;/a&gt; &amp;#8211; Jpeg decoder and encoder + resizing, in just C#&lt;/p&gt;</summary></entry><entry><title>Interesting win32 source code</title><link href="http://blog.kowalczyk.info/article/Interesting-win32-source-code.html" rel="alternate"></link><updated>2009-03-14T23:14:12Z</updated><id>tag:blog.kowalczyk.info,2009-03-14:/article/Interesting-win32-source-code.html</id><summary type="html">&lt;p&gt;Interesting win32 source code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/puttycyg/"&gt;puttycyg&lt;/a&gt; &amp;#8211; cygwin terminal, putty modified to also be a cygwin terminal, &lt;span class="caps"&gt;MIT&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/"&gt;putty&lt;/a&gt;, &lt;span class="caps"&gt;MIT&lt;/span&gt;, &lt;a href="http://www.xs4all.nl/~whaa/putty/"&gt;putty Tray&lt;/a&gt;, enhancements to Putty&lt;/li&gt;
&lt;li&gt;&lt;a href="http://fabrice.bellard.free.fr/qemacs/"&gt;qemacs&lt;/a&gt;, &lt;span class="caps"&gt;LGPL&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://wtl.sourceforge.net/"&gt;&lt;span class="caps"&gt;WTL&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cockos.com/wdl/"&gt;&lt;span class="caps"&gt;WDL&lt;/span&gt;&lt;/a&gt; &amp;#8211; Justin Frankel&amp;#8217;s library for win32 &amp;amp; win32 emulation for mac, &lt;span class="caps"&gt;BSD&lt;/span&gt;-like&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.ntwind.com/software/taskswitchxp/download.html"&gt;TaskSwitchXP&lt;/a&gt; &amp;#8211; &lt;span class="caps"&gt;BSD&lt;/span&gt;-like (?)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/stb-imv/"&gt;stb-img&lt;/a&gt;, &lt;span class="caps"&gt;GPL&lt;/span&gt; with parts in public domain (zlib, png, jpeg decompressors)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/qsniffer/"&gt;qsniffer&lt;/a&gt;, GPLv2, network sniffer in qt, cross-platforms&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/msnwcrec/"&gt;msnwcrec&lt;/a&gt; &amp;#8211; msn webcam recorder, GPLv2&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/orionsniffer/"&gt;orionsniffer&lt;/a&gt;, tcp/ip packet sniffer, GPLv2, uses winpcap&lt;/li&gt;
&lt;li&gt;&lt;a href="http://gynvael.coldwind.pl/?id=130&amp;amp;lang=en"&gt;ansi codes in cmd.exe&lt;/a&gt;, article with source code about patching cmd.exe&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codersnotes.com/sleepy/"&gt;very sleepy&lt;/a&gt;, &lt;span class="caps"&gt;GPL&lt;/span&gt;, simple profiler for windows&lt;/li&gt;
&lt;li&gt;&lt;a href="http://filezilla-project.org/"&gt;FileZill&lt;/a&gt;, &lt;span class="caps"&gt;GPL&lt;/span&gt;, C++&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Debugging/rec-related code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/opendbg/"&gt;opendbg&lt;/a&gt;, GPLv3&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/leaktrap/"&gt;leaktrap&lt;/a&gt;, &lt;span class="caps"&gt;GPL&lt;/span&gt;, gdi/user handle leak tracking and analysis, hooks win32 apis&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/cdbg/"&gt;cdbg&lt;/a&gt;, GPLv3, console user-mode debugger&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/ngdbg/"&gt;ngdbg&lt;/a&gt;, GPLv3, live kernel-mode debugger&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/openrce-snippets/"&gt;openrce-snippets&lt;/a&gt;, &lt;span class="caps"&gt;MIT&lt;/span&gt;, &lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/pefile/"&gt;pefile&lt;/a&gt;, &lt;span class="caps"&gt;MIT&lt;/span&gt;, Python library to work with pe format&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/paimei/"&gt;paimei&lt;/a&gt;, GPLv2, reverse engineering framework in pyton&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.paulsprojects.net/vmachine/vmachine.html"&gt;vmachine&lt;/a&gt;, PC emulator&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Debugging,rec tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.peid.info/"&gt;peid&lt;/a&gt;, unpacker, decryptor of pe files for win, also has process viewer, pe details, disassembler etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;span class="caps"&gt;PDF&lt;/span&gt;-related source code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/openjpeg/"&gt;openjpeg&lt;/a&gt;, New &lt;span class="caps"&gt;BSD&lt;/span&gt;, &lt;span class="caps"&gt;JPEG&lt;/span&gt; 2000 in C&lt;/li&gt;
&lt;/ul&gt;</summary></entry><entry><title>Forcing basic http authentication for HttpWebRequest (in .NET/C#)</title><link href="http://blog.kowalczyk.info/article/Forcing-basic-http-authentication-for-HttpWebReq.html" rel="alternate"></link><updated>2009-03-14T23:12:55Z</updated><id>tag:blog.kowalczyk.info,2009-03-14:/article/Forcing-basic-http-authentication-for-HttpWebReq.html</id><summary type="html">&lt;p&gt;HttpWebRequest is a handy .NET class for doing &lt;span class="caps"&gt;HTTP&lt;/span&gt; requests. It has built-in support for &lt;span class="caps"&gt;HTTP&lt;/span&gt; basic authentication via credentials. However, it doesn&amp;#8217;t work the way I expected: supplying credentials doesn&amp;#8217;t send Authorization &lt;span class="caps"&gt;HTTP&lt;/span&gt; header with the request but only in response to server&amp;#8217;s challenge. It often breaks in real world, where servers might not issue a challenge and simply not authenticate a request.&lt;/p&gt;

&lt;p&gt;Fortunately fixing it by manually adding Authorization &lt;span class="caps"&gt;HTTP&lt;/span&gt; header to the request is simple and this code snippet shows how to do it:&lt;/p&gt;

&lt;p&gt;&lt;pre class="prettyprint"&gt;
public void SetBasicAuthHeader(WebRequest req, String userName, String userPassword)
{
    string authInfo = userName + ":" + userPassword;
    authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
    req.Headers["Authorization"] = "Basic " + authInfo;
}&lt;/pre&gt;&lt;/p&gt;</summary></entry><entry><title>WTL resources</title><link href="http://blog.kowalczyk.info/article/WTL-resources.html" rel="alternate"></link><updated>2009-03-14T22:56:22Z</updated><id>tag:blog.kowalczyk.info,2009-03-14:/article/WTL-resources.html</id><summary type="html">&lt;p&gt;&lt;span class="caps"&gt;WTL&lt;/span&gt; programming resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/"&gt;&lt;span class="caps"&gt;WTL&lt;/span&gt; articles on codeproject.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/wtlthreads.aspx"&gt;Threads for &lt;span class="caps"&gt;WTL&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/wtlinet.aspx"&gt;&lt;span class="caps"&gt;INET&lt;/span&gt; for &lt;span class="caps"&gt;WTL&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/wtl4mfc1.aspx"&gt;&lt;span class="caps"&gt;WTL&lt;/span&gt; for &lt;span class="caps"&gt;MFC&lt;/span&gt;: &lt;span class="caps"&gt;ATL&lt;/span&gt; &lt;span class="caps"&gt;GUI&lt;/span&gt; Classes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/wtl4mfc2.aspx"&gt;&lt;span class="caps"&gt;WTL&lt;/span&gt; for &lt;span class="caps"&gt;MFC&lt;/span&gt;: &lt;span class="caps"&gt;WTL&lt;/span&gt; &lt;span class="caps"&gt;GUI&lt;/span&gt; Base Classes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/wtl4mfc3.aspx"&gt;&lt;span class="caps"&gt;WTL&lt;/span&gt; for &lt;span class="caps"&gt;MFC&lt;/span&gt;: toolbars and status bars&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/wtl4mfc4.aspx"&gt;&lt;span class="caps"&gt;WTL&lt;/span&gt; for &lt;span class="caps"&gt;MFC&lt;/span&gt;: dialogs and controls&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/wtl4mfc5.aspx"&gt;&lt;span class="caps"&gt;WTL&lt;/span&gt; for &lt;span class="caps"&gt;MFC&lt;/span&gt;: advanced dialog ui classes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/wtl4mfc6.aspx"&gt;&lt;span class="caps"&gt;WTL&lt;/span&gt; for &lt;span class="caps"&gt;MFC&lt;/span&gt;: Hosting ActiveX controls&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/wtl4mfc7.aspx"&gt;&lt;span class="caps"&gt;WTL&lt;/span&gt; for &lt;span class="caps"&gt;MFC&lt;/span&gt;: Splitter Windows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/wtl4mfc8.aspx"&gt;&lt;span class="caps"&gt;WTL&lt;/span&gt; for &lt;span class="caps"&gt;MFC&lt;/span&gt;: Property Sheets and Wizards&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/wtl4mfc9.aspx"&gt;&lt;span class="caps"&gt;WTL&lt;/span&gt; for &lt;span class="caps"&gt;MFC&lt;/span&gt;: &lt;span class="caps"&gt;GDI&lt;/span&gt; Classes, common dialogs and utility classes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/wtl4mfc10.aspx"&gt;&lt;span class="caps"&gt;WTL&lt;/span&gt; for &lt;span class="caps"&gt;MFC&lt;/span&gt;: drag &amp;amp; drop source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/wtldlgresize.aspx"&gt;Using &lt;span class="caps"&gt;WTL&lt;/span&gt;&amp;#8216;s Built-in Dialog Resizing Class&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/tips.aspx"&gt;10 &lt;span class="caps"&gt;WTL&lt;/span&gt; tips&lt;/a&gt; (window creation size, centering a window, setting min/max size of a window, dialog text and background color, dynamically swap buttons, default font)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/resourcelessdialogtoolkit.aspx"&gt;Creating dialogs at runtime&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/regst.aspx"&gt;Saving window state&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/wtl/sizingframework.aspx"&gt;Sizing framework&lt;/a&gt; based on &lt;a href="http://msdn.microsoft.com/en-us/magazine/cc302145.aspx"&gt;WinMgr sizing article&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</summary></entry><entry><title>scdiff update (Windows git/subversion/cvs gui diff previewer)</title><link href="http://blog.kowalczyk.info/article/scdiff-update-Windows-gitsubversioncvs-gui-diff-.html" rel="alternate"></link><updated>2009-03-12T04:40:44Z</updated><id>tag:blog.kowalczyk.info,2009-03-12:/article/scdiff-update-Windows-gitsubversioncvs-gui-diff-.html</id><summary type="html">&lt;p&gt;I&amp;#8217;ve updated my little &lt;a href="/software/scdiff/index.html"&gt;scdiff&lt;/a&gt; program and added git support.&lt;/p&gt;

&lt;p&gt;If you work with git, Subversion or &lt;span class="caps"&gt;CVS&lt;/span&gt; from command line, scdiff is a handy program to preview your changes before committing them.&lt;/p&gt;

&lt;p&gt;It works by creating before/after files in a temporary directory and launching a diff viewer (WinDiff by default, but can be configured) to show the diffs.&lt;/p&gt;

&lt;p&gt;It auto-detects which scm is being used in a given directory, so you launch it by simply typing &lt;code&gt;scdiff&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It requires git/svn/cvs executable be in the path. There still is no decent windows build of git, so I use cygwin to get git.&lt;/p&gt;</summary></entry><entry><title>Parsing s3 log files in python</title><link href="http://blog.kowalczyk.info/article/Parsing-s3-log-files-in-python.html" rel="alternate"></link><updated>2009-03-08T23:54:37Z</updated><id>tag:blog.kowalczyk.info,2009-03-08:/article/Parsing-s3-log-files-in-python.html</id><summary type="html">&lt;p&gt;After we &lt;a href="/article/Compacting-s3-aws-logs.html"&gt;took care of compacting s3 logs&lt;/a&gt;, it&amp;#8217;s time to parse them. s3 log format is &lt;a href="http://docs.amazonwebservices.com/AmazonS3/latest/index.html?LogFormat.html"&gt;well documented&lt;/a&gt; and can be parsed with a simple regular expression.&lt;/p&gt;

&lt;p&gt;It took me some time to craft it, so here it is. You can also view the source &lt;a href="http://code.google.com/p/kjk/source/browse/trunk/scripts/test_parse_s3_log.py"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;pre class="prettyprint"&gt;
#!/usr/bin/env python
import re

s3_line_logpats  = r'(\S+) (\S+) \[(.*?)\] (\S+) (\S+) ' \
           r'(\S+) (\S+) (\S+) "([^"]+)" ' \
           r'(\S+) (\S+) (\S+) (\S+) (\S+) (\S+) ' \
           r'"([^"]+)" "([^"]+)"'

s3_line_logpat = re.compile(s3_line_logpats)

(S3_LOG_BUCKET_OWNER, S3_LOG_BUCKET, S3_LOG_DATETIME, S3_LOG_IP,
S3_LOG_REQUESTOR_ID, S3_LOG_REQUEST_ID, S3_LOG_OPERATION, S3_LOG_KEY,
S3_LOG_HTTP_METHOD_URI_PROTO, S3_LOG_HTTP_STATUS, S3_LOG_S3_ERROR,
S3_LOG_BYTES_SENT, S3_LOG_OBJECT_SIZE, S3_LOG_TOTAL_TIME,
S3_LOG_TURN_AROUND_TIME, S3_LOG_REFERER, S3_LOG_USER_AGENT) = range(17)

s3_names = ("bucket_owner", "bucket", "datetime", "ip", "requestor_id", 
"request_id", "operation", "key", "http_method_uri_proto", "http_status", 
"s3_error", "bytes_sent", "object_size", "total_time", "turn_around_time",
"referer", "user_agent")

def parse_s3_log_line(line):
    match = s3_line_logpat.match(line)
    result = [match.group(1+n) for n in range(17)]
    return result

def dump_parsed_s3_line(parsed):
    for (name, val) in zip(s3_names, parsed):
        print("%s: %s" % (name, val))

def test():
    l = r'607c4573f2972c26aff39f7e56ff0490881a35c19b9bf94072cbab8c3219f948 kjkpub [06/Mar/2009:23:13:28 +0000] 41.221.20.231 65a011a29cdf8ec533ec3d1ccaae921c C46E93FF2E865AC1 REST.GET.OBJECT sumatrapdf/rel/SumatraPDF-0.9.1.zip "GET /sumatrapdf/rel/SumatraPDF-0.9.1.zip HTTP/1.1" 206 - 43457 1003293 697 611 "http://kjkpub.s3.amazonaws.com/sumatrapdf/rel/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"'
    parsed = parse_s3_log_line(l)
    dump_parsed_s3_line(parsed)

if __name__ == "__main__":
    test()&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;This snippet only shows how to break one s3 log line into its components (&lt;code&gt;parse_s3_log_line&lt;/code&gt;). Some work is needed to build upon this for parsing log files and extracting useful information out of them. For doing that, I recommend techniques described in &lt;a href="http://www.dabeaz.com/generators-uk/"&gt;Generator Tricks for Systems Programmers&lt;/a&gt;&lt;/p&gt;</summary></entry><entry><title>Compacting s3 aws logs</title><link href="http://blog.kowalczyk.info/article/Compacting-s3-aws-logs.html" rel="alternate"></link><updated>2009-03-08T02:39:07Z</updated><id>tag:blog.kowalczyk.info,2009-03-08:/article/Compacting-s3-aws-logs.html</id><summary type="html">&lt;p&gt;Amazon&amp;#8217;s s3 can serve the files via &lt;span class="caps"&gt;HTTP&lt;/span&gt; protocol, so it can be used as an &lt;span class="caps"&gt;HTTP&lt;/span&gt; server for static files. With a little effort you can configure a given s3 bucket to save access log files to a different s3 bucket. This is useful if you&amp;#8217;re interested e.g. in figuring out how often a given file is being downloaded. Logging doesn&amp;#8217;t happen automatically. To set it up, carefully follow &lt;a href="http://docs.amazonwebservices.com/AmazonS3/latest/index.html?ServerLogs.html"&gt;this official document&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately, standard s3 logs have a problem: they&amp;#8217;re split among lots of files. Around 200 log files are generated for one day which leads to enormous number of files stored on s3 (e.g. merely 6 months of logs generated ~35k of log files).&lt;/p&gt;

&lt;p&gt;To fix that I wrote a python script that compacts the logs so that we only get one file per day, which is a more reasonable number (35k files shrank to only 171 for me). As a bonus, it also compresses the log. Given very repetitive nature of log files, it&amp;#8217;s a big win (the file shrinks by 94% when compressed with bzip2 algorithm).&lt;/p&gt;

&lt;p&gt;The logic of the script is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;download all the files for a given day locally&lt;/li&gt;
&lt;li&gt;create one file that is compressed concatenation of those files&lt;/li&gt;
&lt;li&gt;upload compressed file back to s3&lt;/li&gt;
&lt;li&gt;delete the original files&lt;/li&gt;
&lt;li&gt;repeat&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It took me a few hours to get right, so in the spirit of sharing, &lt;a href="http://code.google.com/p/kjk/source/browse/trunk/scripts/compact-s3-logs.py"&gt;here it is&lt;/a&gt;. You&amp;#8217;ll have to change a few things in the source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;s3 bucket name that stores the logs&lt;/li&gt;
&lt;li&gt;where the logs are downloaded locally. I preserve them although they could be deleted if you&amp;#8217;re short on space&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, the script expects a &lt;code&gt;awscreds.py&lt;/code&gt; file with access/secret key i.e.:&lt;/p&gt;

&lt;p&gt;&lt;pre class="prettyprint"&gt;
# This is awscreds.py file
access = "access key"
secret = "secret key"&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;One unexpected thing I noticed is that apparently Amazon sometimes saves the log file with screwy permissions so that it can&amp;#8217;t be read or even fixed by setting new acl (both those operations return 403 forbidden). The only operation that works is deleting the file from s3, so that&amp;#8217;s what I do (it&amp;#8217;s only a log file, after all).&lt;/p&gt;

&lt;p&gt;Another thing I noticed is that boto sometimes hangs when talking to s3 (exception on timeout would be much better). If that happens, you can kill the script and restart it &amp;#8211; it&amp;#8217;s smart enough to not re-download files and only deletes the original log files on s3 after compressed log has been saved in s3.&lt;/p&gt;

&lt;p&gt;Expected usage of the script is as a daily script followed by a script that analyzes the logs. Due to boto hanging it might not work well in such scenario, though.&lt;/p&gt;</summary></entry><entry><title>How content-based addressing can help web performance</title><link href="http://blog.kowalczyk.info/article/How-content-based-addressing-can-help-web-perfor.html" rel="alternate"></link><updated>2009-03-06T00:54:31Z</updated><id>tag:blog.kowalczyk.info,2009-03-06:/article/How-content-based-addressing-can-help-web-perfor.html</id><summary type="html">&lt;h3&gt;The problem with &lt;span class="caps"&gt;HTTP&lt;/span&gt; caching&lt;/h3&gt;

&lt;p&gt;Currently an &lt;span class="caps"&gt;HTTP&lt;/span&gt; resource (e.g. an image, a JavaScript file, a &lt;span class="caps"&gt;CSS&lt;/span&gt; script) is uniquely identified by a uri. Unfortunately a web browser doesn&amp;#8217;t know if a given resource has changed, so in the simplest case, it has to re-download it over and over again. This is very inefficient, so we came up with ways to tell the browser to avoid re-downloading content.&lt;/p&gt;

&lt;p&gt;One method is by setting Expires &lt;span class="caps"&gt;HTTP&lt;/span&gt; header by which a web server can tell the browser for how long can it cache a given resource. The problem with this approach is that if the resource is changed before the expiration date, the browser will see an outdated version.&lt;/p&gt;

&lt;p&gt;Another method is &lt;a href="http://en.wikipedia.org/wiki/HTTP_ETag"&gt;ETag&lt;/a&gt;. When returning a resource web server also returns an ETag header which uniquely identifies the resource. If subsequent response contains the same etag, the browser might skip downloading the content. This still requires making a small request.&lt;/p&gt;

&lt;p&gt;None of this methods works globally i.e. if two websites use the same version of jQuery library, even if they both instruct the browser to cache them, the browser still ends up downloading two versions. Google&amp;#8217;s &lt;a href="http://code.google.com/apis/ajaxlibs/"&gt;&lt;span class="caps"&gt;AJAX&lt;/span&gt; Libraries &lt;span class="caps"&gt;API&lt;/span&gt;&lt;/a&gt; is an attempt to solve this problem for the most popular web libraries.&lt;/p&gt;

&lt;p&gt;What if there was a backwards-compatible way, efficient way of caching popular resources that worked globally (across multiple websites)? In theory it&amp;#8217;s possible and not that hard.&lt;/p&gt;

&lt;h3&gt;Enter content-addressable resources&lt;/h3&gt;

&lt;p&gt;The idea of content-addressable data has been recently used to great benefit in e.g. &lt;a href="http://git-scm.com/"&gt;git&lt;/a&gt; or &lt;a href="http://bittorrent.org/beps/bep_0003.html"&gt;BitTorrent protocol&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The idea is simple: we can uniquely identify any piece of data by calculating sha1 (or some other cryptographically secure hash) of its content.&lt;/p&gt;

&lt;p&gt;All we need is a way to tell the browser the sha1 hash of a resource. If a resource with this hash is already cached locally, the browser doesn&amp;#8217;t need to re-download it.&lt;/p&gt;

&lt;p&gt;Compared to existing solutions, it has following advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it works globally. If 10 websites host the same version of jQuery library, the browser only need to download it once&lt;/li&gt;
&lt;li&gt;it doesn&amp;#8217;t have the &amp;#8216;oops, we set the expiration date too far into future&amp;#8217; problem that setting Expires header&lt;/li&gt;
&lt;li&gt;it&amp;#8217;s more efficient than ETag because it doesn&amp;#8217;t require making any requests&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;How to tell the browser about the hash&lt;/h3&gt;

&lt;p&gt;The simplest way would be to define another attribute e.g. sha1hash that could be added tags that refer to resources, like script, a, link etc.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m not a web technologist and I don&amp;#8217;t know this particular solution would be acceptable, but I&amp;#8217;m sure there is a way.&lt;/p&gt;</summary></entry><entry><title>HTTP info</title><link href="http://blog.kowalczyk.info/article/HTTP-info.html" rel="alternate"></link><updated>2009-02-26T08:13:33Z</updated><id>tag:blog.kowalczyk.info,2009-02-26:/article/HTTP-info.html</id><summary type="html">&lt;h3&gt;Response codes&lt;/h3&gt;

&lt;p&gt;&lt;pre class="prettyprint"&gt;
200 - OK
206 - Partial Content (if successfully returned part of the file)

301 - Moved permanently 
302 - Found (temporary redirect)
303 - See other
304 - Not Modified

400 - Bad Request
401 - Not Authorized
403 - Forbidden
404 - Not Found
405 - Method Not Allowed
406 - Not Acceptable&lt;/pre&gt;&lt;/p&gt;

&lt;h3&gt;Basic and Digest authentication&lt;/h3&gt;

&lt;p&gt;Covered by &lt;a href="http://www.ietf.org/rfc/rfc2617.txt"&gt;rfc 2617&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basic adds Authorization: header, e.g.: &lt;code&gt;Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==&lt;/code&gt; where the value after Basic is base64 encoding of string ${userid} &amp;#8221;:&amp;#8221; ${password}&lt;/p&gt;

&lt;p&gt;Digest is more complicated. Server responds with e.g.:&lt;br /&gt;
&lt;pre class="prettyprint"&gt;
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Digest
   realm="testrealm@host.com",
   qop="auth,auth-int",
   nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
   opaque="5ccc069c403ebaf9f0171e9517f40e41"&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;And client has to reply with:&lt;br /&gt;
&lt;pre class="prettyprint"&gt;
Authorization: Digest username="Mufasa",
   realm="testrealm@host.com",
   nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
   uri="/dir/index.html",
   qop=auth,
   nc=00000001,
   cnonce="0a4f113b",
   response="6629fae49393a05397450978507c4ef1",
   opaque="5ccc069c403ebaf9f0171e9517f40e41"&lt;/pre&gt;&lt;/p&gt;</summary></entry><entry><title>Essential software</title><link href="http://blog.kowalczyk.info/article/Essential-software.html" rel="alternate"></link><updated>2009-02-26T08:12:43Z</updated><id>tag:blog.kowalczyk.info,2009-02-26:/article/Essential-software.html</id><summary type="html">&lt;p&gt;Windows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://sourceinsight.com/"&gt;Source Insight&lt;/a&gt; &amp;#8211; still the best editor for C/C++ code&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.cygwin.com/"&gt;cygwin&lt;/a&gt; with &lt;a href="http://code.google.com/p/mintty/"&gt;mintty&lt;/a&gt; (run it as &lt;code&gt;C:\cygwin\bin\mintty.exe bash&amp;#8212;login -i&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mozilla.com/en-US/firefox/"&gt;firefox&lt;/a&gt; and &lt;a href="http://www.google.com/chrome"&gt;chrome&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://7-zip.org/"&gt;7-zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://winmerge.org/"&gt;WinMerge&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.flos-freeware.ch/notepad2.html"&gt;Notepad2&lt;/a&gt; and/or &lt;a href="http://notepad-plus.sourceforge.net/"&gt;Notepad++&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.wireshark.org/"&gt;WireShark&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.microsoft.com/downloads/thankyou.aspx?familyId=22e69ae4-7e40-4807-8a86-b3d36fab68d3&amp;amp;displayLang=en"&gt;Consolas font&lt;/a&gt; (if on Windows XP)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.activestate.com/store/activepython/download/"&gt;Python&lt;/a&gt; (ActivePython build)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://subversion.tigris.org/"&gt;Subversion&lt;/a&gt; (&lt;a href="http://www.sliksvn.com/en/download"&gt;SilkSVN builds&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://live.sysinternals.com/"&gt;SysInternals live&lt;/a&gt;, &lt;a href="http://technet.microsoft.com/en-us/sysinternals/default.aspx"&gt;regular&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.ntwind.com/software/taskswitchxp.html"&gt;TaskSwitchXP&lt;/a&gt; (XP only, not working and largely not needed under Vista and 7)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.digsby.com/"&gt;digsby&lt;/a&gt; for IM client&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nsis.sourceforge.net/"&gt;&lt;span class="caps"&gt;NSIS&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.slysoft.com/en/virtual-clonedrive.html"&gt;Virtual CloneDrive&lt;/a&gt; for mounting &lt;span class="caps"&gt;ISO&lt;/span&gt; images&lt;/li&gt;
&lt;li&gt;&lt;a href="http://mpc-hc.sourceforge.net/index.html"&gt;Media Player Classic &amp;#8211; HomeCinema&lt;/a&gt; (an update to &lt;a href="http://en.wikipedia.org/wiki/Media_Player_Classic"&gt;Media Player Classic&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://icofx.ro/"&gt;IcoFX&lt;/a&gt; &amp;#8211; free icon editor&lt;/li&gt;
&lt;li&gt;&lt;a href="http://greenshot.sourceforge.net/"&gt;Greenshot&lt;/a&gt; &amp;#8211; free screenshot grabber&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx"&gt;WinDBG&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Visual Studio add-ins:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.hanselman.com/blog/IntroducingRockScroll.aspx"&gt;RockScroll&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://jens-schaller.de/sonictools/sonicfilefinder/index.htm"&gt;SonicFileFinder&lt;/a&gt; &amp;#8211; a better way to switch between files, assigned to Ctrl-O to match Source Insight&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Firefox extensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/2410"&gt;Foxmarks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1419"&gt;ietab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1865"&gt;AdBlock plus&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mac:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.macports.org/"&gt;MacPorts&lt;/a&gt; (&lt;a href="/article/macports.html"&gt;MacPorts essentials&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Misc Windows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://eeng.net/htxml/Utilities.htm"&gt;another list&lt;/a&gt; of useful software&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.nirsoft.net/"&gt;nirsoft.net&lt;/a&gt; &amp;#8211; CurrPorts, SmartSniff, OpenedFilesView, WhatInStartup etc.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://filezilla-project.org/"&gt;FileZilla&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</summary></entry><entry><title>File/Directory operations in C#</title><link href="http://blog.kowalczyk.info/article/FileDirectory-operations-in-C.html" rel="alternate"></link><updated>2009-02-26T08:12:08Z</updated><id>tag:blog.kowalczyk.info,2009-02-26:/article/FileDirectory-operations-in-C.html</id><summary type="html">&lt;h3&gt;directory operations&lt;/h3&gt;

&lt;p&gt;&lt;pre class="prettyprint"&gt;
using System.IO;
bool Directory.Exists(string dirName);
Directory.CreateDirectory(string dirName);
string[] Directory.GetFiles(string dirName);
string[] Directory.GetFiles(string dirName, string fileNamePattern);&lt;/pre&gt;&lt;/p&gt;</summary></entry><entry><title>Programming in C interesting articles</title><link href="http://blog.kowalczyk.info/article/Programming-in-C-interesting-articles.html" rel="alternate"></link><updated>2009-02-24T22:34:17Z</updated><id>tag:blog.kowalczyk.info,2009-02-24:/article/Programming-in-C-interesting-articles.html</id><summary type="html">&lt;p&gt;&lt;a href="http://www.safercode.com/blog/2009/02/24/volatile-c-keyword-myths-dispelled.html"&gt;Volatile: C keyword myth dispelled&lt;/a&gt; &amp;#8211; explains the exact meaning of &lt;code&gt;volatile&lt;/code&gt; in C&lt;/p&gt;</summary></entry><entry><title>Password-less authentication with ssh</title><link href="http://blog.kowalczyk.info/article/Password-less-authentication-with-ssh.html" rel="alternate"></link><updated>2009-02-24T19:05:39Z</updated><id>tag:blog.kowalczyk.info,2009-02-24:/article/Password-less-authentication-with-ssh.html</id><summary type="html">&lt;p&gt;Short version:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;generate public and private key (e.g. with &lt;code&gt;ssh-keygen -q -f ~/.ssh/id_rsa -t rsa&lt;/code&gt;) (or &lt;code&gt;-t dsa&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;on the machine from which you connect: put private key in ~/.ssh/id_rsa (for rss key) or ~/.ssh/id_dsa (for dsa key), with 0600 permissions&lt;/li&gt;
&lt;li&gt;on the machine you connect to: append public key to &lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; (this file should also have 0600 permission)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can read &lt;a href="http://sial.org/howto/openssh/publickey-auth/"&gt;long version&lt;/a&gt;&lt;/p&gt;</summary></entry><entry><title>Where do bugs come from?</title><link href="http://blog.kowalczyk.info/article/Where-do-bugs-come-from.html" rel="alternate"></link><updated>2009-02-24T17:59:29Z</updated><id>tag:blog.kowalczyk.info,2009-02-24:/article/Where-do-bugs-come-from.html</id><summary type="html">&lt;h2&gt;Where do bugs come from?&lt;/h2&gt;

&lt;p&gt;Let&amp;#8217;s assume you know, more or less, what you want to write and are ready to start cranking the code. You&amp;#8217;ll write bugs. What&amp;#8217;s the source of those bugs and how can you avoid them?&lt;/p&gt;

&lt;h2&gt;Ignorance and carelessness&lt;/h2&gt;

&lt;p&gt;There are only 2 sources of bugs in software:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ignorance&lt;/li&gt;
&lt;li&gt;carelessness&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Many faces of ignorance&lt;/h2&gt;

&lt;p&gt;Ignorance is not knowing what you&amp;#8217;re doing. It&amp;#8217;s a broad category, so let&amp;#8217;s list some of the many ways to be ignorant.&lt;/p&gt;

&lt;h3&gt;Not knowing the language&lt;/h3&gt;

&lt;p&gt;For example, you don&amp;#8217;t know that in C you need to free() each malloc(). Or that you can&amp;#8217;t return a pointer to a local variable. Or you don&amp;#8217;t understand the difference between sizeof(TCHAR) and sizeof(TCHAR*). Or any other of the infinite number of things to know. It takes years to master a programming language.&lt;/p&gt;

&lt;h3&gt;Not knowing the language very well&lt;/h3&gt;

&lt;p&gt;Even if you&amp;#8217;re not writing outright bugs, there are still millions of ways to misuse a language. A trivial example in C might be malloc()ing a 10-byte temporary buffer in a function instead of using stack (which is faster and generates smaller code). Again, it takes years to really master a language.&lt;/p&gt;

&lt;h3&gt;Not knowing operating system and its APIs.&lt;/h3&gt;

&lt;p&gt;Windows has thousands of APIs. Mac OS has thousands of APIs. Way too much to keep details of every &lt;span class="caps"&gt;API&lt;/span&gt; call in your head. It&amp;#8217;s easy to misuse the APIs and misuse leads to bugs.&lt;/p&gt;

&lt;h3&gt;Not knowing file format/protocol/specification.&lt;/h3&gt;

&lt;p&gt;Even if you know your language and APIs, there&amp;#8217;s still plenty of sources of potential ignorance. Software doesn&amp;#8217;t live in a vacuum but in a very rich and complicated ecosystem of existing solutions that are usually poorly designed or over-complicated due to historical reasons that no longer apply. Unfortunately our software has no choice but to talk to those systems.&lt;/p&gt;

&lt;p&gt;If your software talks &lt;span class="caps"&gt;HTTP&lt;/span&gt; protocol, did you really carefully read the full &lt;span class="caps"&gt;HTTP&lt;/span&gt; 1.1 spec and made sure to handle all possible cases?&lt;/p&gt;

&lt;p&gt;If you use &lt;span class="caps"&gt;XML&lt;/span&gt;, did you take time to read and fully comprehend &lt;span class="caps"&gt;XML&lt;/span&gt; spec?&lt;/p&gt;

&lt;p&gt;If you&amp;#8217;re writing a text editor, did you research character encodings, Unicode, different line endings on various platforms?&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s easy to gain a superficial understanding of a complex system. Isn&amp;#8217;t &lt;span class="caps"&gt;XML&lt;/span&gt; just stuff inside brackets? Bugs come from missed details. In &lt;span class="caps"&gt;XML&lt;/span&gt;&amp;#8216;s case it&amp;#8217;s handling &lt;span class="caps"&gt;BOM&lt;/span&gt;, all possible encodings of &lt;span class="caps"&gt;XML&lt;/span&gt; files, entities, &lt;span class="caps"&gt;CDATA&lt;/span&gt; sections, comments, knowing which bytes cannot be put inside &lt;span class="caps"&gt;XML&lt;/span&gt; file (and more).&lt;/p&gt;

&lt;h2&gt;Inevitable mistakes&lt;/h2&gt;

&lt;p&gt;Even if we assume that we know everything, there&amp;#8217;s the issue of mistakes. Even an experienced writer cannot write few pages of text without making a grammatical mistake. Programming is no different &amp;#8211; no matter how good you are, you&amp;#8217;ll make a number of mistakes per N lines of code.&lt;/p&gt;

&lt;p&gt;The more careful you are, the less mistakes you will make, but no matter what the effort, the mistakes will be there&lt;/p&gt;

&lt;h2&gt;Avoiding bugs &amp;#8211; the art of education and compensation&lt;/h2&gt;

&lt;p&gt;Now that we know where bugs come from, what can we do to decrease the number of bugs?&lt;/p&gt;

&lt;p&gt;The methods (and apparatuses) we can use to decrease number of bugs in software fall into two categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;education&lt;/li&gt;
&lt;li&gt;compensation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We educate ourselves to minimize ignorance. We compensate for inherent fallibility of human mind to reduce number of mistakes we make or find them faster. Here&amp;#8217;s a list of some specific things you can do.&lt;/p&gt;

&lt;h3&gt;Read&lt;/h3&gt;

&lt;p&gt;Read books, papers and web articles about your language, operating system, tools etc. That&amp;#8217;s pretty obvious.&lt;/p&gt;

&lt;p&gt;Study the APIs you use. Way too often we use APIs having only partial understanding of what they do, how can they fail, what consequences do they have etc. For Windows, &lt;span class="caps"&gt;MSDN&lt;/span&gt; documents &lt;span class="caps"&gt;API&lt;/span&gt; calls in great detail. Read the whole description, including remarks, not just the &lt;span class="caps"&gt;API&lt;/span&gt; signature. A similar resource to &lt;span class="caps"&gt;MSDN&lt;/span&gt; exists for every system out there.&lt;/p&gt;

&lt;p&gt;Study the source code of other software. This is an open-source era. We have source code for thousands of systems, small and large, easily available for us to learn from. There&amp;#8217;s no excuse not to do it.&lt;/p&gt;

&lt;p&gt;You can read the source code in an exploratory way i.e. randomly browse the code fishing for nice tricks you can adopt in your own software.&lt;/p&gt;

&lt;p&gt;You can do it in a focused way e.g. if you know you need to implement hash table, you can look at source of different implementations of hash tables to learn the techniques used.&lt;/p&gt;

&lt;p&gt;Look for low-level implementation tricks and techniques as well as big picture (e.g. how the code is organized into modules).&lt;/p&gt;

&lt;p&gt;Reading code is hard and boring. Even high-level languages operate on a very low level and it&amp;#8217;s hard to see the forest because all those trees obstruct the view. It is, however, a skill that can be improved with practice.&lt;/p&gt;

&lt;p&gt;Be reflective. When you find it hard to understand the code, try to figure out why is it hard (lack of comments? confusing comments? poor structure? poor naming of variables and functions?) and avoid doing things that make the code hard to read in your own code.&lt;/p&gt;

&lt;p&gt;Conversely, when you see exceptionally well written code, try to figure out what makes it good and imitate.&lt;/p&gt;

&lt;h3&gt;Ask for code reviews&lt;/h3&gt;

&lt;p&gt;The amount of knowledge about programming is enormous. It takes years to master just one programming language or &lt;span class="caps"&gt;API&lt;/span&gt; set. Ignorance is a permanent state of being for a programmer and the worst part is that we don&amp;#8217;t know what we don&amp;#8217;t know.&lt;/p&gt;

&lt;p&gt;Wouldn&amp;#8217;t it be great if there was a magic fairy that would just tell us about the mistakes we made? No such fairy exists but the next best thing is your coworker. He might know that you should free() your malloc()s. He might know a better (simpler, faster) way to do something. He might spot a mistake. All you need to do is ask for a code review.&lt;/p&gt;

&lt;h3&gt;Talk about programming&lt;/h3&gt;

&lt;p&gt;Discuss programming topics with your peers. Ask them to teach you tricks they&amp;#8217;ve learned. Tell them about the tricks you&amp;#8217;ve learned. No matter how much you know, there&amp;#8217;s always more to learn. For example, after umpteen years of writing code I&amp;#8217;ve learned a cool linked list trick from interview with Anders Hejlsberg (it&amp;#8217;s at the very end of the interview).&lt;/p&gt;

&lt;h3&gt;Use automatic tools for finding bugs.&lt;/h3&gt;

&lt;p&gt;Static checker analyzes the source code looking for mistakes. There are static code checkers for Java (FindBugs), C# (FxCop), Python (PyLint), C/C++ (Coverity, Visual Studio 2005 Team (aka. &amp;#8220;expensive&amp;#8221;) Edition has integrated static checker) and probably other languages.&lt;/p&gt;

&lt;p&gt;There are run time tools like BoundsChecker, AppVerifier, Valgrind, AQTime and a countless number of memory debugging tools.&lt;/p&gt;

&lt;p&gt;Learn about those tools and start using them regularly.&lt;/p&gt;

&lt;h3&gt;Use assert()&lt;/h3&gt;

&lt;p&gt;In C assert() macro checks if an expression is true. If it&amp;#8217;s not, it&amp;#8217;ll do something to alert the programmer (details depend on implementation, in gcc it calls abort(), in Visual Studio it shows a dialog box that gives the programmer to break into an app and inspect the state of the program).&lt;/p&gt;

&lt;p&gt;Assert-like functionality exists in other languages as well.&lt;/p&gt;

&lt;p&gt;The idea is to add checks for situations that should never, ever happen.&lt;/p&gt;

&lt;p&gt;There&amp;#8217;s a subtle distinction between something that almost never happens but is possible and something that should never, ever happen and I&amp;#8217;ve seen asserts misused because people fail to understand that distinction (again, ignorance!).&lt;/p&gt;

&lt;p&gt;The most common example of misusing asserts is validating that malloc() didn&amp;#8217;t return &lt;span class="caps"&gt;NULL&lt;/span&gt;. While it&amp;#8217;s unlikely to happen on a desktop machine, it&amp;#8217;s a perfectly valid for malloc() to fail and return &lt;span class="caps"&gt;NULL&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;An example of a valid assert is checking that after you insert a node in a list, the length of the list will increase by one if the insert was successful.&lt;/p&gt;

&lt;p&gt;Assert impossible, not unlikely.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve learned to assert() a lot while working at Microsoft since the code I worked on was littered with asserts (an example of learning good habits by reading other people&amp;#8217;s code). Many times asserts noticed me about bugs that I would have missed and that&amp;#8217;s why I think it&amp;#8217;s worthwhile to use them.&lt;/p&gt;

&lt;h3&gt;Write unit tests.&lt;/h3&gt;

&lt;p&gt;Lots have been said on this topic since eXtreme programming became popular. I&amp;#8217;m not going to explain why it&amp;#8217;s a good thing &amp;#8211; others have done it better that I could.&lt;/p&gt;

&lt;p&gt;The reality of unit-testing is not as good as XP hype would have you believed. My random sampling of open-source projects and projects I&amp;#8217;ve seen inside companies shows that almost no-one writes unit tests&lt;/p&gt;

&lt;p&gt;Writing unit tests is difficult because it&amp;#8217;s boring. When we understand the problem, our first instinct is to dive in and code the damn thing because it&amp;#8217;s the shortest path to having things work. At the time of writing the code, it has obvious cost (time spent writing additional code for unit tests) but no obvious benefit.&lt;/p&gt;

&lt;p&gt;Unit tests do payoff in longer term when they save you from long, hair-pulling debugging sessions. Tthe longer you expect the code to live, the bigger payoff from writing unit tests.&lt;/p&gt;

&lt;p&gt;Not that everyone agrees with that&lt;/p&gt;

&lt;h3&gt;Write automated tests&lt;/h3&gt;

&lt;p&gt;Manual testing i.e. running your software and using it to see if it works as expected, is expensive. Automated testing is also expensive to setup and maintain, but it pays off in the long run.&lt;/p&gt;

&lt;p&gt;Unit tests is only one example of possible automated tests. Unit tests are usually confined to thoroughly testing a small thing: a function or a class. There are other ways to automatically test the code that are beneficial. The golden rule of testing is that the more of it you have, the more bugs it&amp;#8217;ll catch, the better the quality of your software.&lt;/p&gt;

&lt;p&gt;For example, in Mozilla project, Java Script engine has a large number of relatively small Java Script code snippets that ensure that the implementation works the way it was designed. Also in Mozilla, Gecko rendering engine has has a number of layout test cases ensuring that changes to layout engine code do not change the way &lt;span class="caps"&gt;HTML&lt;/span&gt; pages are rendered on the screen. Sqlite database engine has a battery of tests to exercise the engine.&lt;/p&gt;

&lt;p&gt;Automated tests are a rich topic. Think about ways you can automatically test your code (different strategies work for different kinds of code).&lt;/p&gt;

&lt;h3&gt;Do manual testing.&lt;/h3&gt;

&lt;p&gt;Oh yeah, just because you have automated tests doesn&amp;#8217;t mean you can skip manual testing. Let me remind you a golden rule of testing: the more of it, the better.&lt;/p&gt;</summary></entry></feed>