<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>chrishowie.com</title>
	<atom:link href="http://www.chrishowie.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.chrishowie.com</link>
	<description>The best laid plans are in my other pants</description>
	<lastBuildDate>Wed, 09 May 2012 03:58:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>C++ references, continued</title>
		<link>http://www.chrishowie.com/2012/05/08/c-references-continued/</link>
		<comments>http://www.chrishowie.com/2012/05/08/c-references-continued/#comments</comments>
		<pubDate>Wed, 09 May 2012 03:53:26 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.chrishowie.com/?p=516</guid>
		<description><![CDATA[So I got some feedback about my last C++ post. The comment states that references are not pointers, they are just names for another object. Sorry for reopening a topic after nearly 6 months. But I cannot stay silent. I think you got it wrong. Completely. Although a reference might behave like &#8220;some sort&#8221; of [...]]]></description>
			<content:encoded><![CDATA[<p>So I got some feedback about <a href="http://www.chrishowie.com/2011/09/27/what-i-dislike-about-c-plus-plus-part-1-references/">my last C++ post</a>.  The comment states that references are not pointers, they are just names for another object.</p>
<blockquote><p>Sorry for reopening a topic after nearly 6 months. But I cannot stay silent.<br />
I think you got it wrong. Completely.<br />
Although a reference might behave like &#8220;some sort&#8221; of a pointer, it is *not* a pointer. Your statement: <i>&#8220;A reference is effectively a pointer, but this is hidden by the language.&#8221;</i> is completely wrong.<br />
To quote the C++ standard: <i>&#8220;A reference is an alterantive name for an object.&#8221;</i> It is just a new name for something that you’ve defined elsewhere. That’s the very reason why it cannot be null –&gt; You cannot have an alternative name for an object that you do not have yet.</p>
<p style="text-align:right;">&#8211;Willi Burkhardt</p>
</blockquote>
<p>Great, in theory.  Unfortunately, none of the compilers I have used treat references as anything other than pointers.  References are, on some level, supposed to guarantee non-null-ness as well as that they reference a valid object.  This is not true in any compiler I have ever used.</p>
<p>Take this example (<a href="http://ideone.com/Ljdqj">see it run</a>):</p>
<pre>#include &lt;iostream&gt;

static int const a_const = 5;

int const&amp; A() {
	return a_const;
}

static int const* b_ptr = 0;

int const&amp; B() {
	return *b_ptr;
}

int main() {
	int const&amp; a_ref = A();

	std::cout &lt;&lt; &quot;Called A()&quot; &lt;&lt; std::endl;
	std::cout &lt;&lt; &quot;a_ref: &quot; &lt;&lt; a_ref &lt;&lt; std::endl;

	int const&amp; b_ref = B();

	std::cout &lt;&lt; &quot;Called B()&quot; &lt;&lt; std::endl;
	std::cout &lt;&lt; &quot;b_ref: &quot; &lt;&lt; b_ref &lt;&lt; std::endl;

	return 0;
}</pre>
<p>If we are to believe that references are simply another name for an object, then converting <code>*b_ptr</code> to a reference should have caused a runtime error.  After all, we dereferenced a null pointer, right?  The compiler should emit code to prevent this, right?</p>
<p>In an ideal world, this would cause an error &#8212; but it does not.  The segmentation fault does not come until <code>b_ref</code> is used; indeed, we see &#8220;Called B()&#8221; in the program output, indicating that B() successfully returned a reference, which was stored in <code>b_ref</code>.  Obviously, at runtime there was a null pointer dereference.  But we didn&#8217;t use a pointer, I hear you saying.  We used a reference!</p>
<p>Then please explain this behavior to me.  On a language level, sure, references are &#8220;names for objects.&#8221;  But this does not change the fact that the <i>implementation</i> is done using memory addresses &#8212; which is fundamentally the same thing pointers do.  This helps to explain why we see the behavior of this sample.  As I mentioned in my last post, when you convert an expression to a reference type, it&#8217;s treated exactly as though you had converted it to a pointer type, with an implicit address-of operator (<code>&amp;</code>).  So we can rewrite this function:</p>
<pre>int const&amp; B() {
	return *b_ptr;
}</pre>
<p>Like this:</p>
<pre>int const* B() {
	return &amp;*b_ptr;
}</pre>
<p>And it becomes immediately clear why the segmentation fault did not occur here &#8212; taking the address of a dereference expression is the same thing as taking the original expression.  The <code>&amp;</code> and <code>*</code> cancel out during compilation, and we just return the pointer.  Take a look at this example, which is identical to the above example, except that <code>A()</code> is gone, and <code>B()</code> now returns a pointer, with dereferences added in the appropriate places (<a href="http://ideone.com/njpMD">see it run</a>):</p>
<pre>#include &lt;iostream&gt;

static int const* b_ptr = 0;

int const* B() {
	return &amp;*b_ptr;
}

int main() {
	int const* b_ptr = B();

	std::cout &lt;&lt; &quot;Called B()&quot; &lt;&lt; std::endl;
	std::cout &lt;&lt; &quot;b_ref: &quot; &lt;&lt; *b_ptr &lt;&lt; std::endl;

	return 0;
}</pre>
<p>Identical behavior.</p>
<p>So you can throw the spec at me all you want, but every implementation I&#8217;ve tried uses pointer-with-automatic-dereference semantics &#8212; if you convert every reference to a pointer, add an address-of operator to every assignment to a reference, and a dereference operator to every use of a reference, you will see identical behavior.</p>
<p>To preempt the &#8220;but the compiler can optimize local references&#8221; argument, the compiler can do exactly the same with pointers.</p>
<pre>// With a reference
int A() {
    int a = 5;
    int&#038; b = a;
    return b;
}

// With a pointer
int B() {
    int a = 5;
    int* b = &#038;a;
    return *b;
}</pre>
<p>I&#8217;ve heard the argument that the compiler can eliminate the reference in <code>A()</code>.  Well, it can also eliminate the pointer in <code>B()</code>.  If a local pointer is set to point at another local and the compiler can prove that it will never change, it can optimize it away just as easily as it can optimize away a local reference to a local.</p>
<p>So, this supports my original argument that references store memory addresses in the same way that pointers do, only with automatic dereferencing.  They are effectively nothing more than syntactic sugar, allowing you to forget that you&#8217;re operating on an object somewhere else in memory.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrishowie.com/2012/05/08/c-references-continued/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Database versioning and handling branching</title>
		<link>http://www.chrishowie.com/2012/03/26/database-versioning-and-handling-branching/</link>
		<comments>http://www.chrishowie.com/2012/03/26/database-versioning-and-handling-branching/#comments</comments>
		<pubDate>Mon, 26 Mar 2012 17:42:34 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.chrishowie.com/?p=501</guid>
		<description><![CDATA[It&#8217;s no secret to developers of database-driven applications that trying to version a database schema (and seed data) is a royal pain. Propagating changes from your development environment to a live environment is not something that most version control systems are well-equipped to do. This is further complicated by distributed VCSes, like Git &#8212; how [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s no secret to developers of database-driven applications that trying to version a database schema (and seed data) is a royal pain.  Propagating changes from your development environment to a live environment is not something that most version control systems are well-equipped to do.  This is further complicated by distributed VCSes, like Git &#8212; how do you prevent schema migration chaos when developers can branch on a whim?</p>
<p>I&#8217;ve been mulling this issue over for a few months now.  There are several development projects I have where database versioning is necessary.  Finally, I&#8217;ve come up with a process that is not only effective, but actually <em>really simple!</em></p>
<p>Taking a clue from Git, we can use a digest of the current <strong>schema definition file</strong> (the SQL script that will create the database structure) as the <strong>schema identity</strong>.  The schema requires a meta-table to describe the identity of the current schema &#8212; this will allow for automated schema migration, since the migration script can detect the current schema version.  (I usually have a meta-table anyway, for storing site configuration in key/value pairs.  The schema version fits in this table fairly well.)</p>
<p>So, let&#8217;s say we&#8217;re starting a new project.  We design a schema, making sure to include this meta-table as well as any seed data required for the application to function.  This excludes the &#8220;current database schema identity&#8221; row, since adding that row in the schema script will cause the identity to change!  Then we write a migration script.  This script has two functions: load the initial schema, and migrate between schema versions.  When performing the initial load, it should follow this by inserting the database schema identity into the meta-table.  The identity is of course obtained by digesting the schema file.</p>
<p>Now we are ready to make changes.  Let&#8217;s say we want to add a column to the table.  First, we note what the current schema&#8217;s identity is.  Let&#8217;s call this <code>$SCHEMA_ORIGINAL</code>. We tweak the schema definition file to include this column, and then we obtain the digest of the schema file, calling this <code>$SCHEMA_NEW</code>.  Now, we write two migration functions in the migration script: one that will migrate from <code>$SCHEMA_ORIGINAL</code> to <code>$SCHEMA_NEW</code> (an <code>ALTER TABLE ADD COLUMN</code> query) as well as one that will migrate in the opposite direction (<code>ALTER TABLE DROP COLUMN</code>).  This will allow us to roll back the database if necessary.</p>
<p>Now, when you ask the migration script to upgrade the database schema, it only has to fetch the database&#8217;s current version, digest the schema definition file, and then find a path between those versions using a breadth-first search of the available migrations, starting at the current version.</p>
<p>This technique can even account for merges!  When merging branches A and B together, you would resolve any conflicts that arise in the schema definition, and then construct four migration functions: A to merged, merged to A, B to merged, and merged to B.  The breadth-first search during migrations means that if you are then switching from branch A prior to the merge to branch B prior to the merge, it may actually be faster to migrate the database through the merge instead of backing up until the point A and B diverged.</p>
<p>It may also be useful to provide a mechanism to tag certain revisions as causing data loss (such as rolling back a column addition).  The migration script would then prefer longer migration paths that preserve data over shorter migration paths that destroy it.</p>
<p>There are some downsides to this approach.  For one, migration functions will have names that provide little meaning to humans, something like <code style="word-wrap:break-word;">migrate_0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33_to_62cdb7020ff920e5aa642c3d4066950dd1f01f4d()</code>.  And another is that the migration script will need to construct an in-memory graph of every migration so that it can perform its search.  If the only possible migration path contains a migration that will cause data loss, the script will exhaustively search the rest of the graph looking for an alternative.  There&#8217;s probably some room for optimization there.</p>
<p>I will likely be coding up an MIT-licensed Python script to implement this algorithm in the coming days, so stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrishowie.com/2012/03/26/database-versioning-and-handling-branching/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>VPS.NET experiences</title>
		<link>http://www.chrishowie.com/2011/11/15/vps-net-experiences/</link>
		<comments>http://www.chrishowie.com/2011/11/15/vps-net-experiences/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 19:54:32 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Computer]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.chrishowie.com/?p=492</guid>
		<description><![CDATA[I&#8217;ve been using VPS.NET as my hosting provider for two years now (since October 2009). Here&#8217;s my experience, the good and the bad. The building block of the VPS offering is a node: a discrete unit of CPU time, RAM, storage, and bandwidth. These nodes can be deployed as separate servers, or combined together to [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using <a href="http://bit.ly/-vps-net">VPS.NET</a> as my hosting provider for two years now (since October 2009).  Here&#8217;s my experience, the good and the bad.</p>
<p>The building block of the VPS offering is a node: a discrete unit of CPU time, RAM, storage, and bandwidth.  These nodes can be deployed as separate servers, or combined together to create a more powerful server.  Servers can be upgraded or downgraded by attaching and detaching nodes from them.  The CPU/bandwidth changes can be applied without rebooting, but to apply RAM and storage changes, the VPS needs to be rebooted so that the RAM reassignment can happen and so the VPS root volume can be rebuilt.  You can bill nodes per month or per day.  The daily option is more expensive, but allows you to throw an extra node or two at a server that&#8217;s being slashdotted until the traffic subsides &#8212; much cheaper in the long haul then monthly nodes.  Daily nodes are also a good choice for a throwaway server you&#8217;re going to test something on and then scrap.  The math suggests that if you&#8217;re going to be using the server for longer than two or three weeks, monthly nodes are a better deal.</p>
<p>To further sweeten the deal, nodes are portable across any of their data centers.  While you can&#8217;t easily migrate deployed VPSes, you can destroy a server in one data center and create a new one in another using the same node.  I look forward to the day when we&#8217;ll be able to live-migrate running VPSes across the country.  Hopefully someone at VPS.NET is working on that&#8230;</p>
<p>Initially I had one node and this blog was about the only thing running on the server.  Since then, I&#8217;ve expanded the services I host to my personal email server (hosting a few domains for friends too), a Git-based personal software forge, some services for Wikimedia, and a few odds and ends.  While not a feature unique to VPS.NET, having root on your own server is really nice.  Need some software?  Install it.  Want to tweak the firewall?  Go ahead.  I&#8217;m a hacker, so it&#8217;s nice to be able to use my server to just try stuff out and see what works.</p>
<p>Each VPS has CPU and network usage graphs so you can pinpoint busy times and optimize accordingly.  There&#8217;s also a console for each VPS that connects directly to the offline OS terminal, allowing you to recover from a botched network or ssh config without involving support.  While I&#8217;d like to claim that I&#8217;ve never had to make use of this feature, that would be a lie.  I don&#8217;t often need it, but it&#8217;s there when I do.</p>
<p>Uptime has been pretty good all-around.  I&#8217;ve had a few outages here and there: a SAN failure that the staff were not properly prepared for, causing a few hours of downtime; a bootloader issue with Debian caused by upgrading to squeeze (arguably not VPS.NET&#8217;s fault, as Debian decided to change the boot volume path); and most recently, volume corruption caused by upgrading my node, which the support staff remedied within minutes, but ideally should have never happened.  (This makes me a bit reluctant to upgrade again without someone over there babysitting the box to make sure it boots up correctly.)  However, these occurrences were not frequent.  That&#8217;s three distinct issues I can recall since late 2009, two if you attribute the bootloader problem to Debian.  This isn&#8217;t 100% uptime, but it&#8217;s pretty darn close to it, and support is usually quick to respond when problems happen.</p>
<p>I resell a few nodes to some friends and former business partners, and they&#8217;ve had very little issues getting started.  It takes about 10 minutes to go from purchasing a node to having a running server.  When a friend wants another server, I can deliver them their login credentials to a running server within about 15 minutes.  That&#8217;s pretty cool.</p>
<p>There are a few network-level filtering things one should be aware of.  VPS.NET monitors outgoing SMTP (port 25) connections and applies their own spam filtering, rejecting mail if it&#8217;s too spammy.  Some people might like this since it can protect them from being listed on a spam blacklist if their server gets compromised.  Since I run my own mail server and do my own filtering, I wasn&#8217;t pleased when this was deployed, especially since it was done so without any communication on their part.  Once I figured out what was going on, I was able to opt-out of this filtering by filing a support ticket.  I would have preferred more transparency about this change.  Finally, as with most hosts, IRC ports are filtered bidirectionally.  As I was wanting to use my VPS to run a service that collects data from Wikimedia&#8217;s real-time change notification IRC server (essentially just a data stream delivered via IRC) this was a bit of a bummer.  They will not budge on this policy, which is disappointing.</p>
<p>Overall, I am a happy customer.  Things don&#8217;t go wrong often, and when they do support is quick to respond.  I&#8217;d suggest trying a daily node or two if you want to see if they are a good fit for your hosting needs; they&#8217;re only a dollar per day.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrishowie.com/2011/11/15/vps-net-experiences/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>What I dislike about C++, part 1: References</title>
		<link>http://www.chrishowie.com/2011/09/27/what-i-dislike-about-c-plus-plus-part-1-references/</link>
		<comments>http://www.chrishowie.com/2011/09/27/what-i-dislike-about-c-plus-plus-part-1-references/#comments</comments>
		<pubDate>Tue, 27 Sep 2011 17:46:18 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.chrishowie.com/?p=468</guid>
		<description><![CDATA[I&#8217;ve started a new job, for those of you who didn&#8217;t know. I&#8217;m now coding C++ daily. My relationship with C++ has been distant, simply because I haven&#8217;t really ever had a need to use it. However, C and C# are both strong languages of mine, and C++ sits somewhere in the middle: C with [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve started a new job, for those of you who didn&#8217;t know.  I&#8217;m now coding C++ daily.  My relationship with C++ has been distant, simply because I haven&#8217;t really ever had a need to use it.  However, C and C# are both strong languages of mine, and C++ sits somewhere in the middle: C with classes, C# without garbage collection.  (These are rough approximations, and not without caveats.)</p>
<p>There are bound to be things in every programming language that get in the way of productivity.  In this post I&#8217;ll highlight one of those things in C++: references.  References are obfuscating and mostly useless.  But first, why would you use a reference?</p>
<p>A reference is effectively a pointer, but this is hidden by the language.  You use it like it&#8217;s <i>not</i> a pointer, and the compiler turns direct accesses into indirect accesses.  For example:</p>
<pre>#include &lt;iostream&gt;

int main() {
	int a = 5;
	int &amp;b = a;

	std::cout &lt;&lt; "a is " &lt;&lt; a &lt;&lt; std::endl;

	b = 6;

	std::cout &lt;&lt; "a is " &lt;&lt; a &lt;&lt; std::endl;
}</pre>
<p>The output will be:</p>
<pre>a is 5
a is 6</pre>
<p>Note that I did not say <code>*b = 6;</code>.  The reference is treated as though it were not a pointer.  Cool&#8230; but what&#8217;s the benefit?</p>
<p>The solitary benefit I&#8217;ve heard from others is that references cannot be null.  When you declare a function/method that accepts an argument typed as a reference, it&#8217;s not possible to make that reference equivalent to a null pointer.</p>
<p>Ok, so we trade a bit of clarity for a compile-time guarantee that we won&#8217;t be dereferencing a null pointer.  That&#8217;s a good trade, right?</p>
<p>Maybe.  Consider this excerpt:</p>
<pre>class Foo;

void do_something() {
    Foo *foo = new Foo();
    use_foo(*foo);
    delete foo;
}</pre>
<p>This is contrived, yes, and there&#8217;s a better way to write this code.  But I&#8217;m illustrating something here.  I&#8217;ve told you that <code>Foo</code> is a class, but I haven&#8217;t told you the prototype for <code>use_foo()</code>.  That&#8217;s on purpose.  Now, you tell me if the <code>Foo</code> instance is going to be copied.  I&#8217;ll even tell you that <code>Foo</code> doesn&#8217;t overload <code>operator*</code>.</p>
<p>Do you have your answer yet?  If you said yes &#8212; the logical choice &#8212; you&#8217;re wrong.  If you said no, you&#8217;re also wrong.  Well, actually, if you said yes or no, you <i>might</i> be wrong.  It&#8217;s impossible to tell.  If <code>use_foo()</code>&#8216;s declaration is <code>use_foo(Foo foo)</code> then a copy will be made using <code>Foo</code>&#8216;s copy constructor (if possible, otherwise it will be a compile-time error).  But if the function&#8217;s prototype is <code>use_foo(Foo &amp;foo)</code> then we are actually passing in the value stored in the <code>foo</code> variable &#8212; a memory address.  The object will not be copied.  In other words, while it looks like we are dereferencing <code>foo</code>, we are actually doing no such thing.</p>
<p>In C, you can tell pretty much everything you need to know from a call site.  In C++, you must know how the function you&#8217;re calling is defined too, simply because you have to know when things are references and when they are not.  The treatment of what is fundamentally a pointer type as a value type (at the language level) is what causes the uncertainty.  You use value-type grammar around references, even though they are not really a value type.</p>
<p>If it weren&#8217;t for the existence references, the code above would be perfectly clear.  (Well, unless you didn&#8217;t have me to tell you that <code>Foo</code> doesn&#8217;t implement <code>operator*</code>&#8230;)</p>
<p>Don&#8217;t get me wrong, C++ still has a lot of good features.  It&#8217;s just a bit irritating that because of a bad feature (and some other features too, such as some forms of operator overloading), I must know the details of every type and function on a line of code to be absolutely sure what it&#8217;s doing.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrishowie.com/2011/09/27/what-i-dislike-about-c-plus-plus-part-1-references/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Bitcoin for Humans series</title>
		<link>http://www.chrishowie.com/2011/06/09/bitcoin-for-humans-series/</link>
		<comments>http://www.chrishowie.com/2011/06/09/bitcoin-for-humans-series/#comments</comments>
		<pubDate>Thu, 09 Jun 2011 20:58:59 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Bitcoin]]></category>
		<category><![CDATA[Computer]]></category>

		<guid isPermaLink="false">http://www.chrishowie.com/?p=449</guid>
		<description><![CDATA[Anyone who&#8217;s been around me recently knows that I love Bitcoin. It&#8217;s a really neat idea, but it&#8217;s also a very complicated thing. Most people that I talk to don&#8217;t really understand how it works and why it was designed the way it was, and therefore have some incorrect ideas and criticisms of Bitcoin. So [...]]]></description>
			<content:encoded><![CDATA[<p>Anyone who&#8217;s been around me recently knows that I love <a href="http://www.bitcoin.org">Bitcoin</a>.  It&#8217;s a really neat idea, but it&#8217;s also a very complicated thing.  Most people that I talk to don&#8217;t really understand how it works and why it was designed the way it was, and therefore have some incorrect ideas and criticisms of Bitcoin.  So I am going to do a series of blog posts about it that attempt to reduce its very intricate design to simple analogies and concepts that might not be <i>completely</i> accurate, but that will help the non-technical person understand it a bit more.</p>
<p>If you don&#8217;t even know what Bitcoin is, it is a distributed and decentralized currency that operates over the Internet.  There is no central bank or issuer; there are no regulators.  The network as a whole decides what the rules are, and the source code for the official Bitcoin client is open.  You can transfer Bitcoins to anyone, anywhere in the world, in about 10 minutes &#8212; and usually for free.</p>
<p>The topics I will cover in my series are:</p>
<ul>
<li>Basic overview: How to send and receive coins.</li>
<li>Addresses: What an address actually is, and why you should care.</li>
<li>The block chain: What the block chain is, and how this keeps the network secure.</li>
<li>Mining: How Bitcoins are created, and why this is not &#8220;generating free money.&#8221;</li>
</ul>
<p>If you can think of any other topics you would like me to cover, let me know and I will extend the series.  If you want a bit more information right now, this video is a pretty good summary of the project:</p>
<p><object width="560" height="349"><param name="movie" value="http://www.youtube-nocookie.com/v/Um63OQz3bjo?version=3&amp;hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube-nocookie.com/v/Um63OQz3bjo?version=3&amp;hl=en_US" type="application/x-shockwave-flash" width="560" height="349" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrishowie.com/2011/06/09/bitcoin-for-humans-series/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mutable strings in Mono</title>
		<link>http://www.chrishowie.com/2010/11/24/mutable-strings-in-mono/</link>
		<comments>http://www.chrishowie.com/2010/11/24/mutable-strings-in-mono/#comments</comments>
		<pubDate>Wed, 24 Nov 2010 19:50:57 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://www.chrishowie.com/?p=434</guid>
		<description><![CDATA[Update 2010-12-17: Those of you who saw this post appear and then vanish were not seeing things. The Mono community identified the contents of this blog post as a serious security vulnerability in Moonlight that, through violation of the type system, allows the CoreCLR security layer to be bypassed. Attackers could potentially run arbitrary code [...]]]></description>
			<content:encoded><![CDATA[<p style="border-bottom: 1px solid #fff"><b>Update 2010-12-17:</b> Those of you who saw this post appear and then vanish were not seeing things.  The Mono community identified the contents of this blog post as a serious security vulnerability in Moonlight that, through violation of the type system, allows the CoreCLR security layer to be bypassed.  Attackers could potentially run arbitrary code with the permissions of the user running Moonlight.  This entry was therefore temporarily removed until a patch was made available.  See <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-4254">CVE-2010-4254</a> and <a href="http://secunia.com/advisories/42373">SA42373</a>.  If you are using Moonlight, <a href="http://www.go-mono.com/moonlight/download.aspx">update to 2.3.0.1 or later</a> ASAP.  The original and unedited blog post follows:</p>
<p>So I was messing around with generic methods and discovered that <a href="https://bugzilla.novell.com/show_bug.cgi?id=654136">generic constraints can be bypassed on Mono 2.6.7 and 2.8 using reflection</a> (with the exception of the <code>new()</code> constraint).  One of the fun results of this bug is that the <code>String</code> class can be made mutable <i>without using reflection to set private members!</i></p>
<p>The following code demonstrates this; it is legal and will run on Mono up to and including version 2.8:</p>
<pre>using System;
using System.Reflection;

public class FakeString {
    public int length;
    public char start_char;
}

public class TestCase {
    private static FakeString UnsafeConversion&lt;T&gt;(T thing)
        where T : FakeString
    {
        return thing;
    }

    public static void Main() {
        var a = "foo";
        var b = MakeMutable(a);

        Console.WriteLine(a);
        b.start_char = 'b';
        Console.WriteLine(a);
    }

    private static FakeString MakeMutable(string s)
    {
        var m = typeof(TestCase).GetMethod("UnsafeConversion", BindingFlags.NonPublic | BindingFlags.Static);
        var m2 = m.MakeGenericMethod(typeof(string));

        var d = (Func&lt;string, FakeString&gt;)Delegate.CreateDelegate(typeof(Func&lt;string, FakeString&gt;), null, m2);

        return d(s);
    }
}</pre>
<p>This code outputs:</p>
<pre>foo
boo</pre>
<p>Smells like some fun exploits could be written taking advantage of this.  Should Moonlight users be afraid?  I&#8217;m not absolutely certain, but I think there might just be a way to do some damage.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrishowie.com/2010/11/24/mutable-strings-in-mono/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenVP has landed</title>
		<link>http://www.chrishowie.com/2010/08/20/openvp-has-landed/</link>
		<comments>http://www.chrishowie.com/2010/08/20/openvp-has-landed/#comments</comments>
		<pubDate>Fri, 20 Aug 2010 17:53:26 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Banshee]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[OpenVP]]></category>

		<guid isPermaLink="false">http://www.chrishowie.com/?p=430</guid>
		<description><![CDATA[Well, if you&#8217;ve been waiting for some kind of stable release of OpenVP for Banshee, you will love this. OpenVP is part of the Banshee Community Extensions 1.7.4 release! Go get it, and be sure to file any bugs you come across.]]></description>
			<content:encoded><![CDATA[<p>Well, if you&#8217;ve been waiting for some kind of stable release of OpenVP for Banshee, you will love this.  <a href="http://mail.gnome.org/archives/banshee-list/2010-August/msg00072.html">OpenVP is part of the Banshee Community Extensions 1.7.4 release!</a>  <a href="http://download.banshee.fm/banshee-community-extensions/1.7.4/">Go get it</a>, and be sure to <a href="http://code.google.com/p/openvisualizationplatform/issues/list">file any bugs</a> you come across.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrishowie.com/2010/08/20/openvp-has-landed/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>New email address, new mail system</title>
		<link>http://www.chrishowie.com/2010/05/14/new-email-address-new-mail-system/</link>
		<comments>http://www.chrishowie.com/2010/05/14/new-email-address-new-mail-system/#comments</comments>
		<pubDate>Fri, 14 May 2010 18:16:06 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Computer]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Meta]]></category>

		<guid isPermaLink="false">http://www.chrishowie.com/?p=404</guid>
		<description><![CDATA[I&#8217;ve already sent out a message to those I contact frequently, but for the rest of you, my email address has changed from cdh&#65279;owie&#64;gmail&#46;com to me&#64;chris&#65279;howie&#46;com. I have decided to migrate away from Gmail for a variety of reasons. I figured I&#8217;d use my domain so that I have flexibility in my provider choice. For [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve already sent out a message to those I contact frequently, but for the rest of you, my email address has changed from cdh&#65279;owie&#64;gmail&#46;com to <a href="mailto:me&#64;chris&#65279;howie&#46;com">me&#64;chris&#65279;howie&#46;com</a>.</p>
<p>I have decided to migrate away from Gmail for a variety of reasons.  I figured I&#8217;d use my domain so that I have flexibility in my provider choice.  For example, if I decide to change my mail provider I don&#8217;t have to get a new address.  So this change should be permanent.</p>
<p>Now, being a tinkerer, I figured I&#8217;d set up a mail system for myself that retains the features I like from Gmail while doing away with the downsides of using Gmail.  My final system is complicated, but effective.  And it was a fun four days setting it up!  (No, that wasn&#8217;t sarcasm.  This is the kind of thing I enjoy.)</p>
<p>My MTA is Postfix, running on mail.chrishowie.com.  It accepts mail for me and delivers mail from me.  The standard security features are in place: SPF/blacklist checking and no unauthenticated relaying.  I also established SPF records for my domain.  I do not have a spam filter, but I might set up SpamAssassin later if I actually start seeing spam in my inbox; no spam has made it past the sender blacklist check yet.</p>
<p>For downloading mail, I set up Courier as a POP3 server.  The observant will note that this would nullify one of the most useful aspects of Gmail: access to your email from anywhere.  Once you download from a POP3 server and delete, your mail is gone from the server and lives in your mail client.</p>
<p>That&#8217;s where the rest of the rig comes into play.  On my home LAN server I have a multi-piece system that provides me with this anywhere-access.  I have a getmail4 cron job that fetches mail from my POP3 server, as well as from my Gmail account (so people can still reach me using my Gmail address), and some of my other mail accounts, and delivers the mail to my maildir using Dovecot&#8217;s delivery agent.  From there, the agent processes my sieve rules, sorting my mail into various folders.  (It&#8217;s like your favorite mail program&#8217;s &#8220;filters&#8221; only it runs on my server instead of my mail clients, so the configuration is centralized.)</p>
<p>For reading all this mail, I run Dovecot, an IMAP server.  All my mail clients fetch mail from this server, and since it is IMAP, changes to messages (like moving a message between folders, or adding tags, or whatever) are actually pushed back to the server.  So I can use several mail clients at once and they all have a consistent view of my mailbox.</p>
<p>The only major piece I have yet to set up is an LDAP server for centralization of my address book.  The rest has been working quite well.  I can use Thunderbird at home, or my mobile phone&#8217;s email client when I&#8217;m out of the house.  No limiting or inconvenient web interfaces required.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrishowie.com/2010/05/14/new-email-address-new-mail-system/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Why I hate IM contact groups</title>
		<link>http://www.chrishowie.com/2010/04/21/why-i-hate-im-contact-groups/</link>
		<comments>http://www.chrishowie.com/2010/04/21/why-i-hate-im-contact-groups/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 16:53:31 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Computer]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://www.chrishowie.com/?p=382</guid>
		<description><![CDATA[Or at least as they are currently implemented. (Rambling rant alert!) Almost every IM client on the planet has the concept of a group. You create a group, give it a name, and populate it with your contacts. At first glance, this is useful. Having used IM clients since the latter years of AIM&#8217;s domination, [...]]]></description>
			<content:encoded><![CDATA[<p>Or at least as they are currently implemented.  (Rambling rant alert!)</p>
<p>Almost every IM client on the planet has the concept of a group.  You create a group, give it a name, and populate it with your contacts.  At first glance, this is useful.</p>
<p>Having used IM clients since the latter years of AIM&#8217;s domination, I have consistently struggled with the best way to group my contacts.  To this day I have no solution.  Why?</p>
<p>Because the group model is inherently broken in that <b>every major IM client out there allows one group per contact.</b>  This assumes that each person I know has exactly one type of relationship to me.  A contact cannot be a friend, coworker, family member, and developer.  You must pick one.</p>
<p>This problem is exacerbated by multi-protocol clients.  Not through any specific fault of their own, but when they support connecting to many different services, you suddenly wind up with an overwhelming number of groups with no coherent purpose.  If you didn&#8217;t name your groups exactly the same, or you used a different grouping paradigm, you are SOL and must merge the groups somehow.  This becomes an impossible mess when the service on the other end (Facebook, for example) allows contacts to be in multiple groups.  Which group they wind up in on your IM client may as well be random, and may not even be the same each time you connect.  (<i><b>Edit:</b> Since writing this I have discovered that the XMPP server operated by Facebook does actually indicate to clients when contacts are in more than one group.  Pidgin honors this.</i>)</p>
<p>What we need is a cross-service &#8220;tagging&#8221; mechanism that lets me say &#8220;this person is a coworker at X company, and worked with me on Y open-source project.&#8221;  Then, whether I am looking for coworkers at X or codevelopers on Y, this person shows up.  Rules could be established so that &#8220;coworker at X company&#8221; membership implies &#8220;coworker&#8221; membership.  This may at first glance seem like nested groups, but it is very different.  It is completely free-form, and allows me to model my contact structure after how I interact with people in real life.  Not some bizarre mutually-exclusive set of too-shallow or too-specific relationships.</p>
<p>Multi-protocol clients should then support tag equivalency, so that service-mandated groups can be rolled into a differently-named tag.  Or ignore one account&#8217;s groups entirely, with everyone being rolled into one tag, with the possibility of local memorization of extra tags.</p>
<p>But the way things stand now, having groups at all is actually a hindrance to my communication.  &#8220;Did I put that person in friends or coworkers?  Or are they still in the service-specific default friends/buddies/oxygen-converters group?&#8221;</p>
<p>In lieu of a real solution to this problem, I want to disable groups entirely.  Except&#8230; whoops&#8230; Pidgin doesn&#8217;t even let me do that.</p>
<p>I welcome everyone&#8217;s thoughts on this issue.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrishowie.com/2010/04/21/why-i-hate-im-contact-groups/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>PGP key transition</title>
		<link>http://www.chrishowie.com/2010/04/14/pgp-key-transition/</link>
		<comments>http://www.chrishowie.com/2010/04/14/pgp-key-transition/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 18:20:28 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Computer]]></category>

		<guid isPermaLink="false">http://www.chrishowie.com/?p=377</guid>
		<description><![CDATA[I am migrating to a new OpenPGP key. If this concerns you, or if you are interested, please read my key transition statement and take appropriate action. Please verify that the transition is signed by both my old and new keys.]]></description>
			<content:encoded><![CDATA[<p>I am migrating to a new OpenPGP key.  If this concerns you, or if you are interested, please read <a href="http://www.chrishowie.com/files/key-transition-2010-04-14.txt">my key transition statement</a> and take appropriate action.  Please verify that the transition is signed by both my old and new keys.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrishowie.com/2010/04/14/pgp-key-transition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

