<?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>Destructive Design</title>
	<atom:link href="http://blog.desudesudesu.org/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://blog.desudesudesu.org</link>
	<description>DESU DESU DESU</description>
	<lastBuildDate>Tue, 23 Apr 2013 05:41:47 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>(untitled)</title>
		<link>http://blog.desudesudesu.org/?p=1660</link>
		<comments>http://blog.desudesudesu.org/?p=1660#comments</comments>
		<pubDate>Tue, 23 Apr 2013 05:41:47 +0000</pubDate>
		<dc:creator>Taro</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[random shit]]></category>

		<guid isPermaLink="false">http://blog.desudesudesu.org/?p=1660</guid>
		<description><![CDATA[There is a &#8220;must be this tall to ride&#8221; limit on the Internet, and that is your own IP and the ability to act as a peer on the network. If you don&#8217;t meet those requirements, you are just a consumer. You&#8217;re eyeballs that someone else is renting out. You&#8217;re a digital serf.]]></description>
				<content:encoded><![CDATA[<blockquote><p>There is a &#8220;must be this tall to ride&#8221; limit on the Internet, and that is your own IP and the ability to act as a peer on the network.<br />
If you don&#8217;t meet those requirements, you are just a consumer. You&#8217;re eyeballs that someone else is renting out. You&#8217;re a digital serf.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.desudesudesu.org/?feed=rss2&#038;p=1660</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>turns out i just hate computers</title>
		<link>http://blog.desudesudesu.org/?p=1643</link>
		<comments>http://blog.desudesudesu.org/?p=1643#comments</comments>
		<pubDate>Fri, 12 Oct 2012 04:22:43 +0000</pubDate>
		<dc:creator>Taro</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[fuck]]></category>
		<category><![CDATA[fuck computers]]></category>
		<category><![CDATA[fuck fucking]]></category>
		<category><![CDATA[fuck it all]]></category>
		<category><![CDATA[fucking drunk]]></category>

		<guid isPermaLink="false">http://blog.desudesudesu.org/?p=1643</guid>
		<description><![CDATA[So I was trolling around on HN (god help us all) and stumbled upon someone jamming a link in sideways to an otherwise reasonable circlejerk. The link was so fucking interesting I can&#8217;t help but post about it. Eve.com? Really? Circle jerk tip #4: check your goddamn copy before submitting links to the collective. Browsing [...]]]></description>
				<content:encoded><![CDATA[<p>So I was trolling around on HN (god help us all) and stumbled upon someone jamming a link in sideways to an otherwise reasonable circlejerk. The link was so fucking interesting I can&#8217;t help but post about it.</p>
<p><img src="http://blog.desudesudesu.org/wp-content/uploads/2012/10/do-they-really.png"></p>
<p><a href="http://eve.com">Eve.com</a>? Really?</p>
<p><b>Circle jerk tip #4:</b> check your goddamn copy before submitting links to the collective.</p>
<p>Browsing some more on <abbr title="Learn Street; I won't help their SEO with a link">that site</abbr> I find <a href="http://www.lynda.com/Mac-OS-X-10-6-tutorials/Unix-for-Mac-OS-X-Users/78546-2.html?">this link</a>, which purports to be a guide to learning Unix on OSX. Ignore the fact that it&#8217;s a fucking <i>video t<sup>u</sup>torial</i> about fucking Unix, the part you should be looking at is the table of contents. It goes fucking on and on about useless drivel without actually mentioning the one fucking saving grace of using a terminal-based system.</p>
<p>fucking. <i>man. <b>pages</b></i>.</p>
<p>fucking fuck.</p>
<p>Turns out I don&#8217;t hate computers. I just fucking hate anyone who uses them.</p>
<p>FUCK.</p>
<p>EDIT, PS: shoutout to the nodejs releng team who managed to, between 0.6.13 and 0.6.17 subtly change <tt>fs.createWriteStream</tt> to NOT throw an exception when <tt>open(2)</tt> returns an error, and instead emit an <tt>error</tt> event on the stream object. Way to keep a goddamn stable API between fucking minor releases, guys. Also go fuck yourselves I hate you.</p>
<p>EDIT2: before anyone asks, yeah I would run an virtualenv thing to maintain parallel nodejs installs to prevent issues like this; that is, if <a href="https://github.com/visionmedia/n/issues/86">I didn&#8217;t give a fuck about my system</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.desudesudesu.org/?feed=rss2&#038;p=1643</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Untitled</title>
		<link>http://blog.desudesudesu.org/?p=1633</link>
		<comments>http://blog.desudesudesu.org/?p=1633#comments</comments>
		<pubDate>Sat, 28 Jul 2012 22:43:38 +0000</pubDate>
		<dc:creator>Taro</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[madness has consumed me]]></category>

		<guid isPermaLink="false">http://blog.desudesudesu.org/?p=1633</guid>
		<description><![CDATA[I just rewrote the entire backend codebase for one of my work projects from node.js to Go. My co-workers thought I was joking when I told them. Ha. Ha. Ha.]]></description>
				<content:encoded><![CDATA[<p><a href="http://blog.desudesudesu.org/wp-content/uploads/2012/07/04CB30004DFF442493FE18225012DFC2.jpeg"><img src="http://blog.desudesudesu.org/wp-content/uploads/2012/07/04CB30004DFF442493FE18225012DFC2.jpeg" alt="" title="04CB30004DFF442493FE18225012DFC2" width="600" height="336" class="aligncenter size-medium wp-image-1634" /></a></p>
<p>I just rewrote the entire backend codebase for one of my work projects from node.js to Go.</p>
<p>My co-workers thought I was joking when I told them.</p>
<p>Ha. <i>Ha.</i> <b><i>Ha.</i></b></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.desudesudesu.org/?feed=rss2&#038;p=1633</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fun Javascript Primitives Time</title>
		<link>http://blog.desudesudesu.org/?p=1628</link>
		<comments>http://blog.desudesudesu.org/?p=1628#comments</comments>
		<pubDate>Tue, 17 Jul 2012 21:40:43 +0000</pubDate>
		<dc:creator>Taro</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[i give up]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[whiskey]]></category>

		<guid isPermaLink="false">http://blog.desudesudesu.org/?p=1628</guid>
		<description><![CDATA[Suppose you have some javascript, and you&#8217;re inspecting some arguments passed in from another developer because you&#8217;re an asshole and want to throw TypeError&#8216;s whenever possible to spite the fact that you&#8217;re not using a strong, statically-typed language. So you write some code: function dongstrap(a1) { if (!(a1 instanceof String)) { throw new TypeError("ASSHATS"); } [...]]]></description>
				<content:encoded><![CDATA[<p>Suppose you have some javascript, and you&#8217;re inspecting some arguments passed in from another developer because you&#8217;re an asshole and want to throw <tt>TypeError</tt>&#8216;s whenever possible to spite the fact that you&#8217;re not using a strong, statically-typed language. So you write some code:</p>
<pre>function dongstrap(a1) {
  if (!(a1 instanceof String)) {
    throw new TypeError("ASSHATS");
  }
}</pre>
<p>You go to test it and &#8230; wait, what? <tt>dongstrap("dongs");</tt> doesn&#8217;t throw? So you fire up your handy javascript REPL and, sure enough, <tt>"" instanceof String == false</tt>.</p>
<p>What. The. Fuck.</p>
<p>Okay, so string literals aren&#8217;t really objects. Okay. So they shouldn&#8217;t behave like objects.</p>
<pre>String.prototype.dongs = function() { 
  throw new Error("dongs"); 
}

"".dongs(); // Throws "dongs"</pre>
<p>Okay, so string literals BEHAVE like objects, but are not objects. I imagine that they were originally vanilla primitive types &#8212; you couldn&#8217;t coerce them to ever act like objects and had to check the type via <tt>typeof whatever === 'string'</tt>. Fine, I get it, Javascript is old as shit. And then someone else comes along and is like</p>
<blockquote><p>SMALLTALK IS LOVE, SEX ME SOME RUBY, ALL VALUES ARE CAN BE OBJECTS</p></blockquote>
<p>And that&#8217;s fine and all; but during the actual implementation meeting (probably for backwards-compatibility nonsense), they were like &#8220;HEY, LET&#8217;S TACK THIS SHIT ON TOP OF IT AND MAKE ALL KINDS OF HOLES FOR PEOPLE TO FALL INTO, JOB SECURITY ETC&#8221; and there were nods all around, because it was just after the first dot-com bubble and everyone was sleepless at night with worry about how they&#8217;d make their next mortgage payment, much less send their still-infantile children through an over-priced, over-valued 4-year course on increasing bodily tolerance to liquor.</p>
<p>So if we revisit the original function, and instead invoke the <tt>String</tt> constructor directly &#8211;</p>
<pre>dongstrap(new String("dongs"));</pre>
<p>The exception gets thrown as expected.</p>
<p>And that would make sense and all, but we&#8217;ve already rewritten to</p>
<pre>function dongstrap2(a1) {
  if (typeof a1 === 'string') {
    throw new TypeError('seriously');
  }
}</pre>
<p>&#8230;and guess what <tt>typeof(new String(''))</tt> is? Yeah. It&#8217;s not <tt>string</tt>. It&#8217;s <tt>object</tt>. So, frustrated and infuriated, you replace the keys displaced from slamming your keyboard on the ground and with gritted teeth smash out the third and final implementation before breaking out the fifth of whiskey stashed in your desk drawer next to the loaded colt .45</p>
<pre>function dongstrap3(a1) {
  if (!(a1 instanceof String) &#038;&#038; !(typeof a1 === 'string')) {
    throw new TypeError('fuck you');
  }
}</pre>
<p>After commiting your changes, as you raise the revolved to your jaw, you have two thoughts:</p>
<ol>
<li>Why the fuck was I, nay, anyone, writing in such a braindead language?</li>
<li>This madness probably applies to <tt>Number</tt>s as well.</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.desudesudesu.org/?feed=rss2&#038;p=1628</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>So, I lied.</title>
		<link>http://blog.desudesudesu.org/?p=1623</link>
		<comments>http://blog.desudesudesu.org/?p=1623#comments</comments>
		<pubDate>Sat, 12 May 2012 19:56:19 +0000</pubDate>
		<dc:creator>Taro</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[4scrape]]></category>
		<category><![CDATA[cake]]></category>

		<guid isPermaLink="false">http://blog.desudesudesu.org/?p=1623</guid>
		<description><![CDATA[4scrape is alive again. Completely rewritten from scratch in Go, featuring even more stupid bullshit on the frontend. And it&#8217;s using a real fulltext indexer this time around. In it for the long haul this time around.]]></description>
				<content:encoded><![CDATA[<p><a href="http://4scrape.org">4scrape is alive again</a>. Completely rewritten from scratch in <a href="http://golang.org">Go</a>, featuring even more stupid bullshit on the frontend. And it&#8217;s using <a href="http://sphinxsearch.com">a real fulltext indexer</a> this time around. In it for the long haul this time around.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.desudesudesu.org/?feed=rss2&#038;p=1623</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>bullshit rant, part 1</title>
		<link>http://blog.desudesudesu.org/?p=1619</link>
		<comments>http://blog.desudesudesu.org/?p=1619#comments</comments>
		<pubDate>Tue, 16 Aug 2011 05:08:27 +0000</pubDate>
		<dc:creator>Taro</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[bullshit rant]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mention of go]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[tl;dr]]></category>
		<category><![CDATA[why did i quit smoking]]></category>

		<guid isPermaLink="false">http://blog.desudesudesu.org/?p=1619</guid>
		<description><![CDATA[If you haven&#8217;t watched Josh Berkus&#8217;s presentation, &#8220;Scale Fail&#8221;, consider doing so now. I&#8217;m a real sucker for using Reddit/prog/it to choose what programming language/framework/libraries to use for my upcoming projects. Sometimes it&#8217;s worse than usual, and I find myself trying to figure out which project to shoehorn one thing or another into. Naturally, right [...]]]></description>
				<content:encoded><![CDATA[<p>If you haven&#8217;t watched <a href="https://www.youtube.com/watch?v=nPG4sK_glls">Josh Berkus&#8217;s presentation, &#8220;Scale Fail&#8221;</a>, consider doing so now.</p>
<p>I&#8217;m a real sucker for using Reddit/prog/it to choose what programming language/framework/libraries to use for my upcoming projects. Sometimes it&#8217;s worse than usual, and I find myself trying to figure out which project to shoehorn <a href="http://documentcloud.github.com/backbone/">one</a> <a href="http://mbostock.github.com/d3/">thing</a> or <a href="https://github.com/mrdoob/three.js/">another</a> into. </p>
<p>Naturally, right now I&#8217;m running high on the Node.js wave and tweaking along the Go rave. Naturally, I&#8217;ve had wildly different experiences with each.</p>
<p><img src="http://blog.desudesudesu.org/wp-content/uploads/2011/08/nodejs-dark-150x80.png" alt="" title="nodejs-dark" width="150" height="80" class="size-thumbnail wp-image-1620" /></p>
<p>I started using Node.js back when it was version 0.2.0, back before <a href="http://npmjs.org">npm</a> was widely used, when <a href="http://expressjs.org">Express</a> was first brewing, even before hipsters decided how to be cool. To be honest, since then it&#8217;s had a fairly stable API, and the ecosystem gets better every day. In my mind though, it still has two massive warts:</p>
<h2>Continuation passing can make code pig disgusting</h2>
<p><a href="http://blog.ankurgoyal.com/post/6433642218/node-js-is-backwards">Quite</a> a <a href="http://ncannasse.fr/blog/is_nodejs_wrong">few</a> people have bitched about continuation passing in Node.js being a pain for a variety of reasons.</p>
<h3>It makes the code look like piss</h3>
<p>This is not that big of a deal &#8212; if your code looks like piss because of the continuation passing style, then you&#8217;re not doing it right. Your code needs to either be restructured to accurately reflect what you&#8217;re trying to do, or you should use <a href="http://documentcloud.github.com/underscore/">one</a> of <a href="https://github.com/willconant/flow-js">several</a> existing libraries for manipulating control flow in a CPS-friendly manner.</p>
<h3>Lexical scoping can make refactoring code &#8220;fun&#8221;</h3>
<p>Almost every Node.js application is going to have code that looks like</p>
<p><code>
<pre>function(foo, bar) {
  foo.do(function(x) {
    bar.do(function(y) {
      /* snip */
    });
  });
}</pre>
<p></code></p>
<p>Assume that you want to lift the callback passed to <tt>foo.do</tt> into a separate, named function:</p>
<p><code>
<pre>function lifted(x) {
  bar.do(function(y) {
    /* snip */
  });
}</pre>
<p></code></p>
<p>The problem is that we&#8217;re referencing <tt>bar</tt> which was previously closed on from the parent environment. By lifting the function out of the lexical scope (presumably to use the same functionality elsewhere), we completely sacrifice all the automatic loveliness of closures. Instead, we have to explicitly go through the function to lift (which may be fairly long and complex, mind you), annotate exactly what&#8217;s used from the parent scope, then manually bind it into a closure:</p>
<p><code>
<pre>function lifted(bar) {
  return function(x) {
    bar.do(function(y) {
      /* snip */
    });
  };
}

function(foo, bar) {
  foo.do(lifted(bar));
}</pre>
<p></code></p>
<p>To add insult to injury, the compiler will accept whatever you give it, and fault you at runtime for any mistakes.</p>
<p>If you&#8217;ve got some Javascript curry magic, please let me know :(</p>
<h3>When spaghetti is what&#8217;s on the menu</h3>
<p>The biggest issue I have with continuation passing is that (since I&#8217;m dealing mostly with web applications) it&#8217;s exceedingly difficult to trace a failure back to a specific request. Error propagation in Node.js manifests itself in one of three forms:</p>
<ol>
<li>A thrown exception</li>
<li>An <tt>'error'</tt> event is emitted from an <tt>EventListener</tt></li>
<li>An error parameter is passed to a callback</li>
</ol>
<h4>Thrown Exceptions</h4>
<p>Exceptions are used solely to communicate errors in synchronous calls, which naturally are few and far between. The handler is almost always in the same lexical scope of the calling code (since letting the exception propagate further may trigger a <tt>process.unhandledException</tt> event, which should almost always kill the application as cleanly as possible), so it&#8217;s not that big of a deal. </p>
<p>If you&#8217;re balking at the aforementioned &#8220;<tt>process.unhandledException</tt> should kill the application as cleanly as possible&#8221; &#8212; the logic here is that you really have no idea where the hell the exception came from, and even if you do, you have no access to the scope from which it was thrown. You can&#8217;t guarantee that your application is in a consistent state &#8212; your only recourse is to SHUT. DOWN. EVERYTHING. (if this is not the case and you can guarantee a consistent state, somehow, please let me know. that would be amazing).</p>
<h4>Error Events</h4>
<p><tt>'error'</tt> events are fun little things &#8212; whenever you emit an <tt>'error'</tt> event on any <tt>EventEmitter</tt>, if there are no listeners for that event, the process exits (I don&#8217;t believe that an <tt>process.unhandledException</tt> is emitted, even). </p>
<p>This actually works out really well, in most cases. Whenever you&#8217;re binding listeners for something, you should bind the error listener too &#8212; you&#8217;ve got all the stuff you need to identify from whence the error originated within lexical scope.</p>
<p>The one massive snafu is that when you&#8217;re abstracting an abstraction that uses <tt>EventEmitter</tt> internally, you <b>MUST</b> remember to handle and forward all the <tt>error</tt> events. You might be reading this and say &#8220;oh but that&#8217;s easy to remember it&#8217;ll never happen&#8221;. It actually happens more often than you think &#8212; the built-in <tt>http.Client</tt> functionality didn&#8217;t properly catch and forward errors from the internal <tt>net.Socket</tt> for a long time. You had to manually get the undocumented <tt>socket</tt> member and attach a listener manually. I think they fixed this in the new <tt>http.request</tt> interface.</p>
<h4>Errors in callbacks &#8212; lexical scope strikes again</h4>
<p>I think the most common form of error passing is by just returning an error code in a callback parameter. This works really well, until you start refactoring stuff and realize how much shit you&#8217;re stuffing in a closure.</p>
<p>Actually I don&#8217;t remember where I was going on this one &#8212; it seems that it&#8217;s trivially solved by just using the &#8220;pass it forward&#8221; error code C-ism.</p>
<h2>Writing native (C++) extension is a bitchface</h2>
<p>I uhh, this is getting kind of long. I&#8217;m gonna break this into a <tt><abbr title="see what i did there">multipart/post</abbr></tt> and write up section 2 of Node.js bitchings and then eventually write up a section on <a href="http://golang.org">Go</a> bitchings. Hooray!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.desudesudesu.org/?feed=rss2&#038;p=1619</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Invoking mount(2) in FreeBSD 8.x</title>
		<link>http://blog.desudesudesu.org/?p=1616</link>
		<comments>http://blog.desudesudesu.org/?p=1616#comments</comments>
		<pubDate>Mon, 18 Jul 2011 03:20:13 +0000</pubDate>
		<dc:creator>Taro</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[freebsd]]></category>
		<category><![CDATA[mention of go]]></category>
		<category><![CDATA[nuclear farting program]]></category>
		<category><![CDATA[where are the goddamn docs]]></category>

		<guid isPermaLink="false">http://blog.desudesudesu.org/?p=1616</guid>
		<description><![CDATA[So I&#8217;m still writing Go bindings for a lot of common FreeBSD functionality. Yesterday I implemented a means to list all mounted filesystems, so today I&#8217;m writing the bindings to mount(2) to mount/umount them. If you look at the man page for mount, you&#8217;ll see that the function signature looks like this: int mount(const char [...]]]></description>
				<content:encoded><![CDATA[<p>So I&#8217;m still writing <a href="http://golang.org">Go</a> bindings for a lot of common FreeBSD functionality. <a href="http://blog.desudesudesu.org/?p=1607">Yesterday</a> I implemented a means to list all mounted filesystems, so today I&#8217;m writing the bindings to <a href="http://www.freebsd.org/cgi/man.cgi?query=mount&#038;apropos=0&#038;sektion=2&#038;manpath=FreeBSD+8.2-RELEASE&#038;format=html">mount(2)</a> to mount/umount them.</p>
<p>If you look at the man page for <tt>mount</tt>, you&#8217;ll see that the function signature looks like this:</p>
<pre><code>    int mount(const char *type, const char *dir, int flags, void *data);</code></pre>
<p>The <tt>void*</tt> should scare you.</p>
<p>I haven&#8217;t been able to dig up any information about what the fuck should be passed to it (granted, I haven&#8217;t looked <abbr title="at all, actually">very hard</abbr> because, judging from the contents of <tt>src/sbin/mount_*/*.c</tt> in the FreeBSD sources, it&#8217;s been entirely superseded by <tt>nmount</tt>.</p>
<pre><code>    int nmount(struct iovec *iov, u_int niov, int flags);</code></pre>
<p>Poking around, <tt>struct iovec</tt> (eventually included from <tt>sys/uio.h</tt>) is defined as this:</p>
<pre><code>struct iovec {
    void *iov_base;
    size_t iov_len;
}</code></pre>
<p>Effectively, <tt>nmount</tt> takes an array of these structs which effectively form a flattened vector of (key, value) tuples. As far as I can tell, <tt>iov_base</tt> is <i>always</i> a NULL-terminated <tt>char*</tt>, and <tt>iov_len</tt> should be <tt>strlen(iov_base) + 1</tt> (for the NULL terminator).</p>
<p>Unfortunately, the only hints that <tt>man 2 nmount</tt> gives us is</p>
<p><quote>
<pre>The following options are required by all file
     systems:
	   fstype     file system type name (e.g., ``procfs'')
	   fspath     mount point pathname (e.g., ``/proc'')

     Depending on the file system type, other options may be recognized or
     required; for example, most disk-based file systems require a ``from''
     option containing the pathname of a special device in addition to the
     options listed above.</pre>
<p></quote></p>
<p>So far, the only way I&#8217;ve been able to find the actual options is to dig through <tt>mount_*</tt> sources and see what they use, but it&#8217;s pretty gross. Take, for example, the following two filesystems:</p>
<ul>
<li><b>nullfs</b> simply layers one vnode on top of another, effectively grafting one directory over another.</li>
<li><b>unionfs</b> (roughly) does the same thing, but still lets you access the grafted-over directory in read-only mode (and can be configured to do cool shit like copy-on-write).</li>
</ul>
<p>They&#8217;re pretty close, but let&#8217;s look at the arguments that each of them take:</p>
<h5>nullfs</h5>
<ul>
<li><b>fstype</b>: &#8220;nullfs&#8221;</li>
<li><b>fspath</b>: Path to the directory to graft over.</li>
<li><b>target</b>: Path of the directory that&#8217;s being grafted onto another.</li>
</ul>
<p>IMHO, <tt>"target"</tt> should be <tt>"from"</tt>, bikesheds, et. al.</p>
<h5>unionfs</h5>
<ul>
<li><b>fstype</b>: &#8220;unionfs&#8221;</li>
<li><b>fspath</b>: Path to the directory where the unionfs will be mounted.</li>
<li><b>from</b>: Same as &#8220;target&#8221;, above.</li>
<li><b>below</b>: Makes &#8220;fspath&#8221; writable, &#8220;from&#8221; read-only (swaps default behavior)</li>
<li><b>errmsg</b>: &#8230;I have no fucking idea, a <tt>char[255]</tt> which presumably is used as a buffer instead of <tt>errno</tt>?</li>
<li>&#8230;anything else passed as <tt>-oyour=mom</tt> passed to <tt>mount_unionfs</tt>?!</li>
</ul>
<p>Maybe this is more a gripe that <tt>unionfs</tt> seems to be very shitty. And maybe I just haven&#8217;t found a nice magical table of options that every filesystem takes. But FFFFFF SERIOUSLY >:(</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.desudesudesu.org/?feed=rss2&#038;p=1616</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>getmntinfo(2) from Go &#8212; a foray into cgo</title>
		<link>http://blog.desudesudesu.org/?p=1607</link>
		<comments>http://blog.desudesudesu.org/?p=1607#comments</comments>
		<pubDate>Sun, 17 Jul 2011 04:59:57 +0000</pubDate>
		<dc:creator>Taro</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[batman's cock is huge]]></category>
		<category><![CDATA[cgo]]></category>
		<category><![CDATA[fuck documentation]]></category>
		<category><![CDATA[go]]></category>

		<guid isPermaLink="false">http://blog.desudesudesu.org/?p=1607</guid>
		<description><![CDATA[Go is a fun esoteric language that strives for system-level usage. Currently in all real operating systems, C is the dominant systems language and as such, all the functionality for interfacing with core features are exposed as raw C APIs. Go provides a C FFI layer called cgo, which handles all the preprocessing and linking [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://golang.org">Go</a> is a fun esoteric language that strives for system-level usage. Currently in all real operating systems, C is the dominant systems language and as such, all the functionality for interfacing with core features are exposed as raw C APIs. Go provides a C FFI layer called <a href="http://golang.org/cmd/cgo/">cgo</a>, which handles all the preprocessing and linking magic in the background. Unfortunately, there&#8217;s little-to-no documentation available for cgo, just a couple of toy examples in Go&#8217;s <tt>misc/cgo</tt> directory (there&#8217;s actually a shitton of production examples in the Go package sources though &#8212; fucking everything uses cgo).</p>
<p>So, what I want to do is expose <a href="http://www.freebsd.org/cgi/man.cgi?query=getmntinfo&#038;apropos=0&#038;sektion=0&#038;manpath=FreeBSD+8.2-RELEASE&#038;format=html"><tt>getmntinfo</tt></a>, which simply lists the metadata for all mounted filesystems. In C, this is pretty trivial:</p>
<p><code>
<pre>#include &lt;sys/param.h&gt;
#include &lt;sys/ucred.h&gt;
#include &lt;sys/mount.h&gt;

#include &lt;stdio.h&gt;

int main() {
	struct statfs *bufs;
	int i = getmntinfo(&#038;bufs, 0);
	int j = 0;

	for (j = 0; j < i; ++j) {
		struct statfs fs = bufs[j];
		printf("[%s] %s -> %s\n", fs.f_fstypename, 
			fs.f_mntfromname, fs.f_mntonname);
	}

	return 0;
}</pre>
<p></code></p>
<p>This, however, presents a variety of problems for the Go implementation &#8211;</p>
<ol>
<li>We don&#8217;t really know how many <tt>struct statfs</tt> we&#8217;re getting back.</li>
<li>The memory allocated is actually allocated statically; we just get an opaque pointer back to an in-library address.</li>
<li>The fields of <tt>struct statfs</tt> are <tt>char[N]</tt>s rather than <tt>char*</tt>s.</ol>
<p>Thankfully, calling <tt>getmntinfo</tt> is pretty trivial &#8211;</p>
<p><code>
<pre>
func GetMntInfo() []MntInfo {
	var tmp *C.struct_statfs;
	i := int(C.getmntinfo(&#038;tmp, 0))
</pre>
<p></code></p>
<p>It&#8217;s pretty close to the C version &#8212; we just allocate a pointer, and pass a pointer to it in. <tt>getmntinfo</tt> sets the value of the pointer to an internal array of <tt>struct statfs</tt>&#8216;s and lets us go along our merry way. Naturally, we want to marshal it to the appropriate Go types.</p>
<pre><code>
	info := make([]MntInfo, i)
	for j, _ := range(info) {
</code></pre>
<p>So we create an array to marshal values into and begin to iterate through it.</p>
<p>This is where it gets nasty. All we have right now is an opaque pointer to a <tt>struct statfs</tt> &#8212; in C we&#8217;d just use pointer arithmetic to get the other entries in the array. Go, fortunately, explicitly disallows pointer arithmetic. I&#8217;m not sure what the appropriate method to get values out of it is. First, I tried something like</p>
<pre><code>
foo := (*[]MntInfo)(unsafe.Pointer(tmp))
item := (*foo)[j]
</code></pre>
<p>But that seems to cause a panic (no idea why). I got tired of dicking with it and threw in the cards, simply exposing the following C function in the cgo header &#8211;</p>
<pre><code>
struct statfs* offset(struct statfs *v, int i) {
	return v + i;
}
</code></pre>
<p>With that, there&#8217;s no need to dick with much of anything, so we can get the current <tt>struct statfs</tt> of the iteration pass via</p>
<pre><code>
		s := C.offset(tmp, C.int(j))
</code></pre>
<p>Finally, the <tt>char[16]</tt> values need to be marshaled out. Unfortunately, the <tt>C.GoString</tt> marshaling function <i>only</i> takes a <tt>char*</tt> and it&#8217;s too damn stubborn to take an implicitly-convertible type (noting that <tt>X*</tt> != <tt>X[]</tt>). The other beef is that cgo&#8217;s type system processes a <tt>char[]</tt> strangely as a <tt>[]_C_char_type</tt>, so we can index it perfectly fine (but not implicitly coerce it into a pointer). </p>
<p>So we juggle some types and shit all over <tt>unsafe.Pointer</tt> and make it do what we want &#8211;</p>
<p><code>
<pre>
		info[j].FsType = C.GoString((*C.char)
			(unsafe.Pointer(&#038;s.f_fstypename[0])))
		info[j].MntFrom = C.GoString((*C.char)
			(unsafe.Pointer(&#038;s.f_mntfromname[0])))
		info[j].MntOn = C.GoString((*C.char)
			(unsafe.Pointer(&#038;s.f_mntonname[0])))
	}

	return info
}
</pre>
<p></code></p>
<p>And, after several hours of not finding any fucking documentation and screaming at the fucking monitor the damn thing finally works. I&#8217;m completely glossing over the terrible shitty build system they&#8217;ve got set up (it basically only provides functionality to INSTALL to built cgo packages &#8212; I haven&#8217;t found a way to actually build and link them otherwise) &#8212; will probably have to read through all the fucking makefiles that do evil shit.</p>
<p>At some point just doing everything in C is easier, I suspect :|</p>
<hr/>
<p><small>will post full code listing in a sec</small></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.desudesudesu.org/?feed=rss2&#038;p=1607</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Calling a templated member function of a typedef&#8217;d template class</title>
		<link>http://blog.desudesudesu.org/?p=1602</link>
		<comments>http://blog.desudesudesu.org/?p=1602#comments</comments>
		<pubDate>Mon, 11 Jul 2011 23:28:48 +0000</pubDate>
		<dc:creator>Taro</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[c++ is a clusterfuck]]></category>
		<category><![CDATA[seriously wtf]]></category>
		<category><![CDATA[stupid shit]]></category>

		<guid isPermaLink="false">http://blog.desudesudesu.org/?p=1602</guid>
		<description><![CDATA[C++ is insane. Assume you have a templated Object: template struct Object { template void func(){}; }; And you want to wrap up the instance in a Proxy object: template struct Proxy { typedef Object WrappedType; WrappedType obj; static void Func() { Proxy *self = new Proxy; self->obj.func(); } }; Pretty straightforward, but when you [...]]]></description>
				<content:encoded><![CDATA[<p>C++ is insane.</p>
<p>Assume you have a templated <tt>Object</tt>:</p>
<p><code>
<pre>template <typename T> 
struct Object {
	template <typename T1> void func(){};
};</pre>
<p></code></p>
<p>And you want to wrap up the instance in a <tt>Proxy</tt> object:</p>
<p><code>
<pre>template <typename T>
struct Proxy {
	typedef Object<T> WrappedType;
	WrappedType obj;

	static void Func() {
		Proxy<T> *self = new Proxy<T>;
		self->obj.func<Foo>();
	}
};</pre>
<p></code></p>
<p>Pretty straightforward, but when you actually try to invoke <tt>Proxy<T>::Func</tt> on an arbitrary <tt>T</tt> using g++</p>
<p><code>
<pre>struct Foo {};

int main() {
	Proxy<Foo>::Func();
	return 0;
}</pre>
<p></code></p>
<p>g++ shits itself completely:</p>
<p><code>
<pre>$ g++ test1.cpp 
test1.cpp: In static member function ‘static void Proxy<T>::Func()’:
test1.cpp:13: error: ‘Foo’ was not declared in this scope
test1.cpp:13: error: expected primary-expression before ‘)’ token
$ g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5666) (dot 3)</code></pre>
<p>Fucking fantastic.</p>
<p>Some tinkering reveals that the compiler is getting confused as to what the fuck <tt>obj.func</tt> is somewhere. The following implementation of <tt>Func</tt> works fine (but defeats the point of using templates) --</p>
<p><code>
<pre>	static void Func() {
		Proxy<T> *self = new Proxy<T>;
		Object<Foo> bar = self->obj;
		bar.func<Foo>();
	}</pre>
<p></code></p>
<p>I searched for awhile and turned up jack diddly squat, then a co-worker informed me the fix is to use the following:</p>
<p><code>
<pre>	static void Func() {
		Proxy<T> *self = new Proxy<T>;
		self->obj.template func<Foo>();
	}</pre>
<p></code></p>
<p>I don't know what the fuck this <tt>instance.template function<..>()</tt> bullshit is, but apparently MSVC implicitly puts it in there for you. I've certainly never seen it before and it's completely orthogonal to any fix I would have assumed.</p>
<p>tl;dr C++ is a clusterfuck.</p>
<hr />
EDIT: <a href="http://stackoverflow.com/questions/1840253/c-template-member-function-of-template-class-called-from-template-function">A stack overflow post</a> which contains a reference to the C++03 standard (14.2/4) in the answers. fml.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.desudesudesu.org/?feed=rss2&#038;p=1602</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>A centralized system for sharing sensitive content</title>
		<link>http://blog.desudesudesu.org/?p=1592</link>
		<comments>http://blog.desudesudesu.org/?p=1592#comments</comments>
		<pubDate>Tue, 21 Jun 2011 01:00:14 +0000</pubDate>
		<dc:creator>Taro</dc:creator>
				<category><![CDATA[Random]]></category>
		<category><![CDATA[dropbox]]></category>
		<category><![CDATA[lots of bullet points]]></category>
		<category><![CDATA[tarsnap]]></category>
		<category><![CDATA[terrible idea]]></category>
		<category><![CDATA[too much wanking; not enough free time]]></category>

		<guid isPermaLink="false">http://blog.desudesudesu.org/?p=1592</guid>
		<description><![CDATA[I have too many stupid ideas which I&#8217;ll never have enough time to implement. Despite that, some of them I&#8217;d really like to see implemented because I bloody need them. So please someone steal this and implement it, even though it&#8217;s a stupid piece of trash ;_; Overview The goal is to combine the easy-to-use [...]]]></description>
				<content:encoded><![CDATA[<blockquote><p>I have too many stupid ideas which I&#8217;ll never have enough time to implement. Despite that, some of them I&#8217;d really like to see implemented because I bloody need them. So please someone steal this and implement it, even though it&#8217;s a stupid piece of trash ;_;</p></blockquote>
<h1>Overview</h1>
<p>The goal is to combine the easy-to-use native interfaces of DropBox (http://www.dropbox.com/) with the paranoid strong-encryption cryptography of Tarsnap (http://www.tarsnap.com/) to create a cloud-based sharable storage system where you can share content with yourself and other people, but not even the server providers can see the content being shared.</p>
<h1>Deficits in Existing Systems</h1>
<h2>DropBox</h2>
<p>DropBox is a service for easily storing and sharing content in the cloud &#8212; after registering an account, it effectively presents itself as a file share on your local machine (Windows, OSX, Linux, etc). Any changes to the data on the file share are automatically and seamlessly propagated to the central server, and from there to any other clients looking at those files. Effectively, it’s a USB drive that’s stored on the internet.</p>
<p>Their shell integration is critical to their success &#8212; a naive user can simply run the software and interact with it in the same manner as a USB thumb drive. Because it exposes itself as a logical volume, applications can interface with it out-of-the-box.</p>
<p>Despite the amazing ease-of-use, DropBox is completely insecure and unsuitable for use in a sensitive environment:</p>
<ul>
<li>It relies on password authentication</li>
<li>The server software they use is buggy; numerous critical security holes are constantly found
<ul>
<li>Password reset doesn’t deauth clients, http://forums.dropbox.com/topic.php?id=12645</li>
<li>Able to reset any password, http://pastebin.com/yBKwDY6T</li>
</ul>
<li>Data is not encrypted; hosting providers (or anyone who can get access) has all your data</li>
</ul>
<h2>Tarsnap</h2>
<p>Tarsnap is an online backup system “for the truely paranoid”. After registering, you provide tarsnap with a public key to authenticate all data requests. There are two methods of operation &#8212; put data and get data. All data is automatically encrypted by the client software with your public key, then signed with your private, then sent to the server. As soon as the data leaves your system, no one can access it ever again without your private key.</p>
<p>Despite the extreme caution it takes with data security, Tarsnap is completely unusable for the majority of DropBox’s use cases:</p>
<ul>
<li>All core functionality is exposed in command-line tools rather than shell integration</li>
<li>Designed around loading large, static files; no support for inter-file metadata (directories, etc)</li>
<li>Everything done with a single key pair &#8212; cannot share data with other uses without giving them your private key</li>
</ul>
<h1>Solution Criteria</h1>
<p>We need something that combines the ease-of-use of DropBox’s data-sharing characteristics with the data paranoia of Tarsnap. In particular, it should fulfill the following criteria:</p>
<ul>
<li>No data sent over the network or stored on the server should be unencrypted</li>
<li>The server should not be able to decrypt any of the data it contains</li>
<li>Private keys must never be shared</li>
<li>It must be possible for one user to share a single binary file with multiple users without duplicating the binary content</li>
<li>The system must present itself to the end-user as if it were a USB drive (e.g., seamless shell integration)</li>
</ul>
<h1>Proposed Solution</h1>
<h2>Transport-Level Details</h2>
<p>Data is represented in an encrypted unit which will be henseforth termed a “blob”. A blob consists of the following data segments:</p>
<ol>
<li>The binary payload itself, encrypted with a single-use symmetric key, X⁰</li>
<li>A list of Pⁿ, where each Pⁿ is the known public key of a friend the user authorizes to view the data</li>
<li>A list of Xⁿ, where X⁰ is encrypted with each Pⁿ</li>
</ol>
<p>Each blob is identified by the SHA256 (or equivalent) hash of its contents (henceforth referred to as the blob ID).</p>
<p>Like Tarsnap, the transport provides two operations &#8211; putting content on the server, and getting content from the server.</p>
<h3>Sending Content</h3>
<p>To put content on the server, one blob for each logical file is created, signed with the user’s private key, then uploaded to the server. The server can then verify that the payload was sent by the user and is what the user intended to send. Furthermore, it can see who the user has authorized to view the data (so it can quickly send access denied messages to people who don’t have access to the content).</p>
<h3>Receiving Content</h3>
<p>Likewise, a client can receive content by sending a request for a specific blob ID. The request is signed with the user’s key for authentication purposes. If the client is authenticated, the server then transmits the blob.</p>
<p>The client then thumbs through the blob and finds the copy of the single-use symetric key signed with their public key. They decrypt it, then use the decrypted key to decrypt the payload of the blob.</p>
<h3>Listing/Removing Content</h3>
<p>Since the server knows effectively nothing about the content, these are pretty easy use-cases: the client simply sends a signed request to the server. In the former, the server sends a list of blob IDs back to the client (in addition to possible metadata, like file size, for billing purposes). In the later, the client simply sends a blob ID (or list of IDs) to the server and the server removes them.</p>
<h2>Providing a Seamless User Experience</h2>
<p>What’s been described thus far is effectively Tarsnap with a form of content sharing built-in. As such, it is only suitable for client consumption, not end-user consumption. In addition to transmitting, storing and receiving binary blobs, the user must be able to append metadata to that blob. Some likely forms of metadata include</p>
<ul>
<li>Symbolic name of the content (e.g., a filename)</li>
<li>Hierarchical organization of the content (e.g., file directory structure)</li>
<li>Other tidbits normally expected of filesystems to provide (atime/mtime, etc)</li>
</ul>
<p>Support for metadata is built entirely on top of the existing transport infrastructure &#8212; metadata for all files belonging to a user is encoded as a single, separate blob which contains a hierarchy of metadata objects, each of which contain the blob IDs of the data they reference.</p>
<p>In addition to the actual metadata, as listed above, each metadata object also contains one of the following:</p>
<ol>
<li>A blob ID which references the blob containing the content of the file, OR</li>
<li>A set of “child” metadata objects (e.g., this one is a directory) OR</li>
<li>A blob ID which references another metadata blob (e.g., a shared directory)</li>
</ol>
<p>The “shared directory” is an abstraction on top of the transport-level permission details that services two purposes: it provides beyond all-or-nothing to share metadata with other users, and it provides an intuitive way to do directory-level sharing (e.g., having a “Shared with Alice and Bob” directory &#8212; though the client would have to make sure every blob referenced in that tree was appended with the appropriate encrypted keys).</p>
<p>At this point, we’ve effectively built, from the ground-up, a centralized file-sharing system with no shared secrets.</p>
<blockquote><p>Good luck making it financially viable ;_;</p></blockquote>
<blockquote><p>EDIT: Apparently <a href="https://spideroak.com">it already exists</a>. lol.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.desudesudesu.org/?feed=rss2&#038;p=1592</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 4.333 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2013-06-18 16:24:56 -->
