<?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>Whatever happened to Benjamin Ragheb? &#187; Nerdery</title>
	<atom:link href="http://www.benzado.com/blog/what/nerdery/feed" rel="self" type="application/rss+xml" />
	<link>http://www.benzado.com/blog</link>
	<description>A professional&#039;s personal blog.</description>
	<lastBuildDate>Mon, 11 Apr 2011 18:06:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
		<item>
		<title>Using curl to test .htaccess redirects</title>
		<link>http://www.benzado.com/blog/post/370/test-htaccess-with-curl</link>
		<comments>http://www.benzado.com/blog/post/370/test-htaccess-with-curl#comments</comments>
		<pubDate>Wed, 02 Feb 2011 19:04:27 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[.htaccess]]></category>
		<category><![CDATA[curl]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=370</guid>
		<description><![CDATA[A quick tip for testing htaccess redirects with curl]]></description>
			<content:encoded><![CDATA[<p>Say you want to use .htaccess URL rewriting to make sure that example.com always redirects to www.example.com (or vice-versa). Or something more complicated that depends on the host name.</p>
<p>You want to test it before you upload to your production server, but your staging server has a different URL (obviously).</p>
<p>An easy trick is to use curl, manually setting the Host: header to simulate access through different URLs. For example, assume your test server is at IP address 1.2.3.4 and you want to make sure that example.com redirects to www.example.com. Type this:</p>
<pre>curl --head --header "Host: example.com" http://1.2.3.4/</pre>
<p>The &#8211;head option fetches only the headers. The &#8211;header option spoofs the Host: header with the value that would have been sent by a browser accessing your production site.</p>
<p>If your .htaccess is correct, you should get output like this:</p>
<pre>HTTP/1.1 301 Moved Permanently
Date: Wed, 02 Feb 2011 18:47:54 GMT
Server: Apache/2.2.14
Location: http://www.example.com/</pre>
<p>If the HTTP code on the first line is 301 and you have a Location field with the expected URL, it worked!</p>
<p>If you see &#8220;HTTP/1.1 200 OK&#8221; then the server just served up a regular page. If you see &#8220;HTTP/1.1 500 Internal Server Error&#8221; then something went horribly wrong.</p>
<p>Armed with this knowledge, a clever person could write a script to automate these tests, confirming that all the redirects work as expected <em>before</em> deploying the site.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/370/test-htaccess-with-curl/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to make a VirtualBox guest boot from an external drive on a Mac host</title>
		<link>http://www.benzado.com/blog/post/366/virtualbox-external-drive</link>
		<comments>http://www.benzado.com/blog/post/366/virtualbox-external-drive#comments</comments>
		<pubDate>Sun, 30 Jan 2011 00:58:08 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[VirtualBox]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=366</guid>
		<description><![CDATA[This is the story of how I used VirtualBox to set up a virtual machine to boot a Windows 7 guest from an external hard disk on a Mac OS X host.]]></description>
			<content:encoded><![CDATA[<p>I have been using Macintosh since before it was cool. A lot has changed since then: now Apple <em>is</em> cool, Macs use Intel processors, and <a href="http://www.kernelthread.com/publications/virtualization/">software can emulate a virtual computer inside your actual computer</a>. Although Microsoft becomes less relevant each day, there are still valid reasons besides masochism that a person might want access to Windows.</p>
<p>This is the story of how I used VirtualBox to set up a Windows 7 guest on a Mac OS X host. Lots of people have done this. The reason I feel my story is compelling enough to tell is that, rather than using a single file to act as a virtual hard disk, I am using an <em>actual</em> hard disk, connected to my Mac via FireWire.</p>
<p>Why do this?</p>
<ul>
<li><strong>Performance</strong>. Giving your virtual machine it&#8217;s own dedicated hard disk means it isn&#8217;t competing with the host machine for access. I haven&#8217;t run tests, and the USB or FireWire bottleneck may compromises guest performance, but my inner engineer would rather have a slower guest than a slower guest<em> and</em> host.</li>
<li><strong>Backup</strong>. A virtual hard disk is a large, frequently changing file. Most backup software, such as <a href="http://www.apple.com/macosx/what-is-macosx/time-machine.html">Time Machine</a>, doesn&#8217;t work well with these.</li>
<li><strong>Portability</strong>. To use the virtual machine on a second computer, all I need to do is copy the settings, only a few kilobytes of data. Then all I have to do is plug the external disk into whatever computer I feel like using that day.</li>
<li><strong>Access</strong>. Instead of being locked away in a virtual hard disk file, my files are accessible to any computer that I can plug the drive into.</li>
</ul>
<p>Now that I have convinced you this is worth the hassle, I will describe the details of the hassle.</p>
<p>Warning: the procedure below is not for the faint of heart. If you are uncomfortable at a command line, you may want to wait for software to support this in a more graceful manner.</p>
<p><span id="more-366"></span></p>
<h3>Install VirtualBox</h3>
<p>On Mac OS X you have three options (that I am aware of): <a href="http://www.parallels.com/products/desktop/">Parallels Desktop</a>, <a href="http://www.vmware.com/products/fusion/">VMware Fusion</a>, and <a href="http://www.virtualbox.org/">VirtualBox</a>. I used VirtualBox because it is free and I am a cheapskate. Parallels and VMware are very reasonably priced, and supposedly offer better performance, but my needs are modest and VirtualBox is pretty good.</p>
<p><a href="http://www.virtualbox.org/wiki/Downloads">Download VirtualBox</a> and follow the installation instructions, etc. Don&#8217;t create your virtual machine just yet. Note to people of the future: 4.0.2 was the latest available version at the time of writing.</p>
<h3>Create Virtual Disk File</h3>
<p>Although your virtual machine will be using an actual hard disk, you still need to make a file that tells VirtualBox how to access the device. You can&#8217;t do this through the graphical interface, so you must drop down to the command line. Connect your disk and <a href="http://guides.macrumors.com/Terminal">open a Terminal window</a>. Then type:</p>
<pre style="margin: 8px;">diskutil list</pre>
<p>You should see some output that looks like this:</p>
<pre style="margin: 8px;">/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *250.1 GB   disk0
   1:                        EFI                         209.7 MB   disk0s1
   2:                  Apple_HFS Macintosh HD            215.8 GB   disk0s2
   3:       Microsoft Basic Data BOOTCAMP                33.9 GB    disk0s3
/dev/disk1
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     Apple_partition_scheme                        *2.2 TB     disk1
   1:        Apple_partition_map                         32.3 KB    disk1s1
   2:                  Apple_HFS Drobo                   2.2 TB     disk1s3
/dev/disk2
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     Apple_partition_scheme                        *10.8 GB    disk2
   1:        Apple_partition_map                         32.3 KB    disk2s1
   2:                 Apple_HFSX benzado                 10.8 GB    disk2s2
/dev/disk4
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *60.0 GB    disk4</pre>
<p>From this list, you need to identify which disk is the one you want to install onto. In my case, it&#8217;s the last one, disk4. I wish I could tell you exactly what to look for, but at this point I don&#8217;t know what&#8217;s on your disk, if it&#8217;s been formatted, etc. If you&#8217;re unsure, look for a number in the size column that matches the size of the drive.</p>
<p>Now for some harsh reality: Mac OS X assigns these disk numbers on a first-connected, first-served basis. In my case, the internal hard drive is disk0 and my <a href="http://www.drobo.com/">Drobo</a> is disk1. When I log in, Finder mounts my <a href="http://www.apple.com/mobileme/features/idisk.html">iDisk</a>, so that&#8217;s disk2. At some point I downloaded and mounted a disk image to install some software, it was disk3. Then I connected the external drive, disk4. Finally, I ejected the disk image, which is why disk3 does not appear in the list above.</p>
<p>Our problem is that VirtualBox needs a disk identifier, but the identifier depends on when we plugged the drive in. The least painful way to deal with this problem is to create a symbolic link to the device identifier, and tell VirtualBox to use that. If the external disk&#8217;s identifier has changed, all we need to do is update the symbolic link. Let&#8217;s do that.</p>
<p>Switch to the directory where VirtualBox stores it&#8217;s hard disk files:</p>
<pre>cd ~/Library/VirtualBox/HardDisks/</pre>
<p>Create a link to the device we noted earlier:</p>
<pre>ln -s /dev/disk4 ExternalDiskDeviceLink</pre>
<p>Create the virtual disk file:</p>
<pre>VBoxManage internalcommands createrawvmdk -filename ExternalDisk.vmdk -rawdisk $PWD/ExternalDiskDeviceLink</pre>
<p>This creates a virtual disk file named ExternalDisk.vmdk which refers to the link ExternalDiskDeviceLink, which in turn points to the device /dev/disk4.</p>
<p>Whenever you need to point to a new device, update the symbolic link file:</p>
<pre>ln -s /dev/disk3 ~/Library/VirtualBox/HardDisks/ExternalDiskDeviceLink</pre>
<p>You may be wondering, why not just use VBoxManage to create a bunch of the vmdk files, and switch between those? You could do that, but each time you create a file, it is assigned a UUID which is apparently visible to the guest OS. Microsoft Office, for example, believes it has been copied to a new computer if this UUID changes, forcing you to reactivate your legally obtained copy by telephone.</p>
<p>Also, clicking around in VirtualBox to change the disk file each time would get annoying (to me) fast.</p>
<h3>Configure a Virtual Machine</h3>
<p>Launch VirtualBox and create a new virtual machine. The prompts are fairly straightforward, I won&#8217;t explain them all. When it asks you to select a virtual hard disk, select <strong>Use existing hard disk</strong> and then click the tiny folder icon to select the ExternalDisk.vmdk file you created earlier.</p>
<p>The guest and the host cannot use the external disk at the same time, so if the disk has been mounted on the host, make sure to eject it before you try to start the virtual machine. If you don&#8217;t, VirtualBox will lambast you with a cryptic, angry error message containing the word BUSY.</p>
<p>(If you get a different error message containing the word UNSUPPORTED, try changing the configuration so that the disk is connected to a virtual IDE controller rather than a virtual SATA controller.)</p>
<p>Once the VM is running, you can install Windows 7 (or whatever other OS you like). Allow the installer to partition and format the external drive.</p>
<h3>Prevent the Drive from Auto-mounting</h3>
<p>Even though I would eject the drives before starting the VM, Mac OS X would mount them again as soon as the VM shut down. This was annoying.</p>
<p>Then at some point I noticed Mac OS X mounted the drives <em>while the virtual machine was running</em>. This caused the VM to lock up and was generally horrible. So even though I was good about unmounting the drives before starting the VM, it is <em>absolutely necessary</em> to prevent Mac OS X from auto-mounting the drives.</p>
<p>If it&#8217;s running, shut down the VM. Let the drives mount automatically or use Disk Utility to mount them. Then open a Terminal window and type:</p>
<pre>diskutil list</pre>
<p>Here is the part of the output we&#8217;re interested in:</p>
<pre>/dev/disk4
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *60.0 GB    disk4
   1:               Windows_NTFS System Reserved         104.9 MB   disk4s1
   2:               Windows_NTFS Homunculus Brain        59.9 GB    disk4s2</pre>
<p>Windows has created two partitions; we need to make sure they don&#8217;t mount. We do this by listing them in the system&#8217;s <a href="http://en.wikipedia.org/wiki/Fstab">fstab file</a>. We can identify disks by label (name) or <a href="http://en.wikipedia.org/wiki/Universally_unique_identifier">UUID</a>. It&#8217;s better to use the UUID if we can, since it&#8217;s easy to change a disk&#8217;s label but impossible (well, very difficult) to change it&#8217;s UUID. Unfortunately, some partitions don&#8217;t appear to have one.</p>
<p>Find out if each partition has a UUID:</p>
<pre>diskutil info disk4s1</pre>
<p>Look for a line like:</p>
<pre>   Volume UUID:              FB4E2CC6-36EF-41E1-9E41-D6E0D932F2EB</pre>
<p>Make a note of the UUID; if it doesn&#8217;t have one, note the Volume Name instead. Repeat for disk4s2 and so on. Now create a file at /etc/fstab (you need <a href="http://guides.macrumors.com/sudo">root privileges</a> to do so) and add the following lines. (If the file already exists, you can just add these lines to the end.)</p>
<pre># identifier, mount point, fs type, options
LABEL=System\040Reserved  none  ntfs  ro,noauto
UUID=FB4E2CC6-36EF-41E1-9E41-D6E0D932F2EB  none  ntfs  ro,noauto</pre>
<p>In my case, &#8220;System Reserved&#8221; did not have a UUID, so I identified it by label, using \040 to represent the space. I&#8217;m not too worried about it, since its label is unlikely to change. The main partition&#8217;s name, other the other hand, can be changed by clicking around within Windows, so I&#8217;ve copied the UUID from above. You should copy the UUID from your system and not the one from this web page.</p>
<p>Anyway, that &#8220;noauto&#8221; keyword on the end of the line is what prevents Mac OS X from mounting the disk when you plug the drive in.</p>
<p>Test it by ejecting the disks, unplugging the drive, then plugging it back in. If nothing happens, you&#8217;ve succeeded!</p>
<p>If you ever want to mount the disks manually (perhaps to copy a file without booting up your VM), use Disk Utility.</p>
<h3>Congratulate yourself</h3>
<p>You have done it: a virtual machine that boots from an actual hard disk.</p>
<p>These instructions are based on my faulty memory of what worked for me on my computer. If you run into problems, leave a comment and let me know, but I can&#8217;t guarantee I can help you.</p>
<p>There is definitely room for improvement here. An enterprising sort of person could probably write a script or application that automatically updates the symbolic link before starting the VM.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/366/virtualbox-external-drive/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Changing the default scan format on a Canon imageCLASS MF8450c</title>
		<link>http://www.benzado.com/blog/post/362/mfing-mf8450c</link>
		<comments>http://www.benzado.com/blog/post/362/mfing-mf8450c#comments</comments>
		<pubDate>Thu, 09 Dec 2010 23:01:00 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[Canon]]></category>
		<category><![CDATA[MF8450c]]></category>
		<category><![CDATA[usability]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=362</guid>
		<description><![CDATA[I provide tech support for an office with a Canon Color imageCLASS MF8450c. It&#8217;s a printer, scanner, fax machine, and copier all in one. It is a usability nightmare. It takes dozens of button presses to accomplish anything. This is made worse by the fact that it has some pretty stupid default settings. For example, [...]]]></description>
			<content:encoded><![CDATA[<p>I provide tech support for an office with a <a href="http://www.amazon.com/gp/product/B001IDYVW6?ie=UTF8&amp;tag=benjpeteragh-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B001IDYVW6">Canon Color imageCLASS MF8450c</a>. It&#8217;s a printer, scanner, fax machine, and copier all in one. <strong>It is a usability nightmare.</strong> It takes dozens of button presses to accomplish anything. This is made worse by the fact that it has some pretty stupid default settings. For example, as a scanner it can create files in PDF, JPEG, and TIFF format. Guess which is the default? If you guessed &#8220;WTF is TIFF?&#8221; then you get a cookie!</p>
<p>This is a scanner for office settings, where people are usually interested in creating PDF files from legal documents, and don&#8217;t want high resolution uncompressed black and white images. So <em>every </em>time somebody needs to scan <em>anything</em>, they must change the format from TIFF to PDF. This is crazy.</p>
<p>For the longest time, I didn&#8217;t think there was a way to change the default. Turns out I was wrong. I don&#8217;t think you will blame me for thinking it was impossible, though. Inspired by <a href="http://www.automationadventures.com/2009/01/14/setting-default-scan-format-on-canon-5075i/">instructions for other models of Canon equipment</a>, I gave it another try. Here&#8217;s how to do it:</p>
<ol>
<li>&#8220;Additional Func.&#8221;</li>
<li>&#8220;Communications Settings&#8221;</li>
<li>&#8220;Common Settings&#8221;</li>
<li>&#8220;TX Settings&#8221;</li>
<li>&#8220;Change Send Func. Mode&#8221;</li>
<li>&#8220;Register&#8221;</li>
<li>Now you see a menu of scanning options, including an item for Color/File Format. Change it to whatever you like.</li>
<li>Select &#8220;Register&#8221; and then &#8220;Done&#8221; the appropriate number of times to get back to the main menu.</li>
<li>The next time you scan, you may be presented with the old defaults, making you think the change did not take hold. If you back out to the main menu and then try to scan again, you may find that the change has taken effect.</li>
</ol>
<p>I mean, seriously? <em>Communications settings?</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/362/mfing-mf8450c/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>File references relative to DERIVED_FILE_DIR in Xcode</title>
		<link>http://www.benzado.com/blog/post/352/file-references-relative-to-derived_file_dir-in-xcode</link>
		<comments>http://www.benzado.com/blog/post/352/file-references-relative-to-derived_file_dir-in-xcode#comments</comments>
		<pubDate>Tue, 28 Sep 2010 21:42:52 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=352</guid>
		<description><![CDATA[Let&#8217;s say you have a Mac or iOS app which stores its data in an SQLite database. It looks for this database file on launch; if missing, the app copies a template file from its bundle. How do you configure your Xcode project to store that template file in the app bundle? Let&#8217;s also say [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s say you have a Mac or iOS app which stores its data in an SQLite database. It looks for this database file on launch; if missing, the app copies a template file from its bundle. How do you configure your Xcode project to store that template file in the app bundle?</p>
<p>Let&#8217;s also say you have a source file of SQL commands, checked into source control, that you use to generate the database file. You could manually generate the database file and add it to your project, but you want a clean build process, with no steps to remember between checkout and build.</p>
<p>The right way to accomplish this is by adding a <a href="http://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/XcodeBuildSystem/200-Build_Phases/bs_build_phases.html#//apple_ref/doc/uid/TP40002690-CJABHEIB">Run Script Build Phase</a> to your target, so that when you build, Xcode creates the database file for you.</p>
<p>Xcode lets you specify the Input Files the script depends on and the Output Files it generates, so that it can examine modification dates and determine if the script needs to be run at all. When you add a new Output File to the list, the default value is <strong>$(DERIVED_FILE_DIR)/myfile</strong>, which seems to be a pretty clear endorsement of that location as the place to store generated files.</p>
<p>So let&#8217;s say you write the script and save the database file to <strong>$(DERIVED_FILE_DIR)/Template.db</strong>. You add a reference to this file to your Xcode project (navigating to a DerivedSources folder somewhere within the Intermediate Build Files directory). When you build, Xcode generates your file (Run Script phase) then copies it into your app&#8217;s bundle (Copy Bundle Resources phase). Hooray!</p>
<p>Then you change the build configuration from Debug to Release, and it breaks. Why?</p>
<p>The problem is the file references. The DERIVED_FILE_DIR location depends on the current target and build configuration. When you switched from Debug to Release, the script dutifully generated a file in the correct location, but the file references are looking in the wrong place. The Debug location is hardcoded into the path.</p>
<p>Select any of the files and hit Cmd-I, and you&#8217;ll see a Path Type popup menu that tells Xcode <a href="http://developer.apple.com/library/ios/documentation/DeveloperTools/Conceptual/XcodeProjectManagement/130-Files_in_Projects/project_files.html#//apple_ref/doc/uid/TP40002666-BBCDFECB">how to resolve that file&#8217;s path</a>. Here are all the options:</p>
<ul>
<li><strong>Relative to Enclosing Group:</strong> this just passes the buck.</li>
<li><strong>Relative to Project:</strong> this is where your source files are stored.</li>
<li><strong>Absolute Path:</strong> this doesn&#8217;t even try.</li>
<li><strong>Relative to Build Product:</strong> this sounds promising, but Build Products are distinct from Intermediate Build Files, and we want the latter.</li>
<li><strong>Relative to Xcode folder:</strong> nope.</li>
<li><strong>Relative to Current SDK:</strong> of course not.</li>
</ul>
<p>At this point, you could give up and modify your script to write the file directly into the app bundle. But that would be so dirty!</p>
<p>It turns out you are not limited to only those options. Additional source trees you define in Xcode Preferences will appear in that popup menu. Here&#8217;s what to do:</p>
<ol>
<li>If you haven&#8217;t already, organize all the derived files into a DerivedSources group, and set the Path Type of each to be <strong>Relative to Enclosing Group</strong>. If done properly, the Path: field should contain only the file name. (If that&#8217;s not the case, click <strong>Choose&#8230;</strong> to select the file. If the file doesn&#8217;t exist, do a build to create it.)</li>
<li>Open Xcode Preferences and select <strong>Source Trees</strong>.</li>
<li>Add a new source tree, with Setting Name as <strong>DERIVED_FILE_DIR</strong>, Display Name as <strong>Derived Files</strong>, and Path as <strong>$(DERIVED_FILE_DIR)</strong>.</li>
<li>Click OK.</li>
<li>In the project window, select the <strong>DerivedSources</strong> group and hit Cmd-I.</li>
<li>Change Path Type to <strong>Relative to Derived Files</strong>.</li>
<li>Unfortunately, the Xcode GUI is not able to resolve DERIVED_FILE_DIR properly; the Full Path will be missing the active target&#8217;s name. As a result, the path is invalid, and Xcode will fill in the Path field trying to find it&#8217;s way to a DerivedSources folder. We don&#8217;t want that, we want Path: to be None. I know of no way to do that within Xcode, so we&#8217;ll have to edit the project file. <strong>Take a deep breath.</strong></li>
<li>Close Xcode.</li>
<li>Use a text editor to open the <strong>project.pbxproj</strong> file inside your Xcode project bundle.</li>
<li>Find the <strong>DerivedSources</strong> section. It will contain a few key-value pairs: isa, children, name, path, and sourceTree. Delete the <strong>path</strong> line and save the file.</li>
<li>Reopen your project file.</li>
</ol>
<p>The group will appear in red, indicating that the Xcode GUI can&#8217;t find them, but when you perform a build Xcode will look in the right places and use the correct files.</p>
<p>I figured this out by experimenting on my own, so it&#8217;s possible that these instructions won&#8217;t work for you, or that there&#8217;s a better way to do this. If that&#8217;s the case, let me know, and I&#8217;ll update this post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/352/file-references-relative-to-derived_file_dir-in-xcode/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A simple way to keep your Mac awake</title>
		<link>http://www.benzado.com/blog/post/346/pmset-noidle</link>
		<comments>http://www.benzado.com/blog/post/346/pmset-noidle#comments</comments>
		<pubDate>Wed, 15 Sep 2010 06:07:11 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=346</guid>
		<description><![CDATA[This is a meandering post that ends with a shell scripting tip. Images on this blog had been broken ever since I migrated to NearlyFreeSpeech.NET several months ago. I took some time today to fix them and tie up some other loose ends. I learned that PHP&#8217;s safe mode (as implemented by NSFN, anyway) won&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>This is a meandering post that ends with a shell scripting tip.</p>
<p>Images on this blog had been broken ever since I migrated to <a href="https://www.nearlyfreespeech.net/">NearlyFreeSpeech.NET</a> several months ago. I took some time today to fix them and tie up some other loose ends. I learned that PHP&#8217;s safe mode (as implemented by NSFN, anyway) won&#8217;t allow a file to be created unless the group of the destination directory and the script being executed match. Once I <code>chgrp</code>&#8216;d everything to the &#8220;web&#8221; group, things I couldn&#8217;t get working before, like <a href="http://wordpress.org/extend/plugins/wp-super-cache/">WP-Super-Cache</a>, started working again.</p>
<p>I use rsync to update my website, and it would be great if it could take care of setting the owner and group appropriately on files it copied to the web server. Unfortunately, rsync will only try to find a group with the same name on both systems, or ignore the group it entirely. There doesn&#8217;t seem to be a way to provide your own mapping to rsync, and tell it that the local group &#8220;staff&#8221; should be mapped to group &#8220;web&#8221; on the remote system.</p>
<p>Just in case there were some rsync secrets I didn&#8217;t know about, I went searching on Super User, and that&#8217;s where I browsed my way to this question: ﻿<a href="http://superuser.com/questions/99247/stop-my-mac-from-sleeping-whilst-a-bash-script-is-running-and-then-allow-it-to-sl">Stop my mac from Sleeping whilst a bash script is running and then allow it to sleep as normal when it&#8217;s done?</a></p>
<p>The lone answer to the question merely suggested reading the <a href="http://www.manpagez.com/man/1/pmset/">manual page for pmset</a>. I figured I could offer the world something more helpful than <a href="http://xkcd.com/293/">RTFM</a>, so I took a look at it myself. At first I thought I&#8217;d have to do a lot of work to figure out the current power settings, save them, disable sleep, do whatever work the Mac needs to stay awake for, then finally restore the saved settings. That would have been especially difficult since pmset&#8217;s output isn&#8217;t designed for parsing.</p>
<p>However, it turns out pmset has a mode designed just for this situation. It&#8217;s barely explained in the manual, but if you call <code>pmset noidle</code>, sleep will be disable for as long as the process is alive. So all you need to do is something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># start background process to disable sleep</span>
pmset noidle <span style="color: #000000; font-weight: bold;">&amp;</span>
<span style="color: #666666; font-style: italic;"># save its process ID so we can terminate it later</span>
<span style="color: #007800;">PMSETPID</span>=<span style="color: #007800;">$!</span>
&nbsp;
...have your fun here...
&nbsp;
<span style="color: #666666; font-style: italic;"># kill pmset so the computer can sleep if it wants to</span>
<span style="color: #c20cb9; font-weight: bold;">kill</span> <span style="color: #007800;">$PMSETPID</span></pre></div></div>

<p>It would be nice if <a href="http://superuser.com/questions/99247/stop-my-mac-from-sleeping-whilst-a-bash-script-is-running-and-then-allow-it-to-sl/188743#188743">my write up</a> would improve <a href="http://superuser.com/users/21562/benzado">my Super User Reputation</a>, but considering that the question is viewed approximately 0.37 times per day, I&#8217;m not holding my breath.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/346/pmset-noidle/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Make Xcode nag you about unfinished TODOs</title>
		<link>http://www.benzado.com/blog/post/329/make-xcode-nag-you-about-unfinished-todos</link>
		<comments>http://www.benzado.com/blog/post/329/make-xcode-nag-you-about-unfinished-todos#comments</comments>
		<pubDate>Fri, 08 Jan 2010 08:51:15 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=329</guid>
		<description><![CDATA[Add a simple Run Script Build Phase to your project and you'll never forget another TODO again.]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re like me, you often make promises to yourself in the form of TODO comments in your code. For example:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// TODO: make sure file exists before opening!</span>
fooBar <span style="color: #002200;">=</span> <span style="color: #002200;">&#91;</span><span style="color: #002200;">&#91;</span>FooBar alloc<span style="color: #002200;">&#93;</span> initWithFile<span style="color: #002200;">:</span>path<span style="color: #002200;">&#93;</span>;</pre></div></div>

<p>This is a reasonable thing to do, because sometimes you just want to get something working right now and aren&#8217;t in the mood to write all the required error checking code. But, you also know that you cannot trust your <a href="http://theinfosphere.org/Transcript:I,_Roommate#time-04-13">soft human brain</a> to remember to add the check later, so you write a comment to remind yourself to do it.</p>
<p>Xcode recognizes the TODO: keyword in your comments and helpfully <a href="http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/XcodeWorkspace/100-The_Text_Editor/text_editor.html#//apple_ref/doc/uid/TP40002679-SW10">adds items to the function popup menu</a> so that you can quickly navigate to them. In addition to <code>TODO:</code>, Xcode will also recognize <code>FIXME:</code> (when you know the code is broken), <code>???:</code> (when you don&#8217;t know what it does), and <code>!!!:</code> (when you wish you didn&#8217;t know).</p>
<p>That&#8217;s helpful when you&#8217;re editing a file, but what about a TODO tucked away in some dark corner of your source code that you haven&#8217;t visited in a while? You&#8217;re likely to forget about it, and how can you keep a promise you forgot that you made?</p>
<p>The answer, of course, is to have somebody nag you. Fortunately, there&#8217;s a way to have Xcode fill that role. All you have to do is add a simple Run Script Build Phase which turns them into Build Warnings.</p>
<p>Select <b>Project &gt; New Build Phase &gt; New Run Script Build Phase</b> from the menu bar. Then, copy and paste this into the script window:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">KEYWORDS</span>=<span style="color: #ff0000;">&quot;TODO:|FIXME:|\?\?\?:|\!\!\!:&quot;</span>
<span style="color: #c20cb9; font-weight: bold;">find</span> <span style="color: #800000;">${SRCROOT}</span> \<span style="color: #7a0874; font-weight: bold;">&#40;</span> <span style="color: #660033;">-name</span> <span style="color: #ff0000;">&quot;*.h&quot;</span> <span style="color: #660033;">-or</span> <span style="color: #660033;">-name</span> <span style="color: #ff0000;">&quot;*.m&quot;</span> \<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #660033;">-print0</span> <span style="color: #000000; font-weight: bold;">|</span> \
    <span style="color: #c20cb9; font-weight: bold;">xargs</span> <span style="color: #660033;">-0</span> <span style="color: #c20cb9; font-weight: bold;">egrep</span> <span style="color: #660033;">--with-filename</span> <span style="color: #660033;">--line-number</span> <span style="color: #660033;">--only-matching</span> <span style="color: #ff0000;">&quot;(<span style="color: #007800;">$KEYWORDS</span>).*<span style="color: #000099; font-weight: bold;">\$</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> \
    <span style="color: #c20cb9; font-weight: bold;">perl</span> <span style="color: #660033;">-p</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;s/(<span style="color: #007800;">$KEYWORDS</span>)/ warning: <span style="color: #000099; font-weight: bold;">\$</span>1/&quot;</span></pre></td></tr></table></div>

<p>What does it mean?</p>
<p>Line 1 defines the keywords we want to search for. If you want to exclude a keyword or include a different one, edit this line.</p>
<p>Line 2 uses the <a href="http://developer.apple.com/mac/library/DOCUMENTATION/Darwin/Reference/ManPages/man1/find.1.html">find</a> command to generate a list of all files in your project directory (SRCROOT) having an .h or .m extension. If you want to search more files, you will need to edit this line.</p>
<p>Line 3 uses <a href="http://developer.apple.com/mac/library/DOCUMENTATION/Darwin/Reference/ManPages/man1/xargs.1.html">xargs</a> to pass those file names along to <a href="http://developer.apple.com/mac/library/DOCUMENTATION/Darwin/Reference/ManPages/man1/egrep.1.html">egrep</a>, which searches inside the files for lines containing one of the keywords. If any are found, it outputs the file name, line number, and the matching part of the line.</p>
<p>Line 4 uses Perl to format the lines as warnings.</p>
<p>The output of the script will look like this:</p>
<p><code>/Users/benzado/Projects/FooBart/Baz.m:42: warning: TODO: make sure file exists before opening!</code></p>
<p>Xcode will recognize lines in this format and treat them as first class build warnings. You can see them in the Build Results panel and, just like a warning from the compiler, a double click will open an editor window and take you directly to the offending line.</p>
<p><i>An Exercise For The Enterprising Reader: modify the script so that no warnings or errors are reported during Debug builds, but TODOs are flagged as errors in Release builds.</i></p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/329/make-xcode-nag-you-about-unfinished-todos/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Draw your own Disclosure Indicator</title>
		<link>http://www.benzado.com/blog/post/325/draw-your-own-disclosure-indicator</link>
		<comments>http://www.benzado.com/blog/post/325/draw-your-own-disclosure-indicator#comments</comments>
		<pubDate>Mon, 04 Jan 2010 03:21:17 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[code]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=325</guid>
		<description><![CDATA[In which I share code for a function to draw an iPhone disclosure indicator.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m writing Cocoa Touch code to draw a button which, when pressed, pushes a new view controller onto the stack. If I was working with a UITableView, I&#8217;d simply set the cell&#8217;s accessory to be a <a href="http://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/MobileHIG/ContentViews/ContentViews.html#//apple_ref/doc/uid/TP40006556-CH12-SW13">disclosure indicator</a> (the little gray arrowhead) and call it a day.</p>
<p>But I&#8217;m not working with table cells, so even though the standard disclosure indicator is <em>perfect</em> for this situation, if I want one I&#8217;ll have to draw it myself.</p>
<p>In this situation I will usually take a screenshot of the real iPhone control, add the image file to my project, and then feel kind of guilty about it. I began to do this, but I realized that the disclosure indicator is really only two gray lines. Two lines! How hard can it be to just draw it in code?</p>
<p>It turns out that it&#8217;s not too hard, if you&#8217;re willing to spend some time experimenting with different numbers and seeing what looks right. Fortunately for you, I&#8217;ve saved you the trouble by posting the answer here:</p>

<div class="wp_syntax"><div class="code"><pre class="objc" style="font-family:monospace;"><span style="color: #11740a; font-style: italic;">// Draws a disclosure indicator such that the tip of the arrow is at (x,y)</span>
<span style="color: #a61390;">void</span> BRDrawDisclosureIndicator<span style="color: #002200;">&#40;</span>CGContextRef ctxt, CGFloat x, CGFloat y<span style="color: #002200;">&#41;</span> <span style="color: #002200;">&#123;</span>
    <span style="color: #a61390;">static</span> <span style="color: #a61390;">const</span> CGFloat R <span style="color: #002200;">=</span> <span style="color: #2400d9;">4.5</span>; <span style="color: #11740a; font-style: italic;">// &quot;radius&quot; of the arrow head</span>
    <span style="color: #a61390;">static</span> <span style="color: #a61390;">const</span> CGFloat W <span style="color: #002200;">=</span> <span style="color: #2400d9;">3</span>; <span style="color: #11740a; font-style: italic;">// line width</span>
    CGContextSaveGState<span style="color: #002200;">&#40;</span>ctxt<span style="color: #002200;">&#41;</span>;
    CGContextMoveToPoint<span style="color: #002200;">&#40;</span>ctxt, x<span style="color: #002200;">-</span>R, y<span style="color: #002200;">-</span>R<span style="color: #002200;">&#41;</span>;
    CGContextAddLineToPoint<span style="color: #002200;">&#40;</span>ctxt, x, y<span style="color: #002200;">&#41;</span>;
    CGContextAddLineToPoint<span style="color: #002200;">&#40;</span>ctxt, x<span style="color: #002200;">-</span>R, y<span style="color: #002200;">+</span>R<span style="color: #002200;">&#41;</span>;
    CGContextSetLineCap<span style="color: #002200;">&#40;</span>ctxt, kCGLineCapSquare<span style="color: #002200;">&#41;</span>;
    CGContextSetLineJoin<span style="color: #002200;">&#40;</span>ctxt, kCGLineJoinMiter<span style="color: #002200;">&#41;</span>;
    CGContextSetLineWidth<span style="color: #002200;">&#40;</span>ctxt, W<span style="color: #002200;">&#41;</span>;
    CGContextStrokePath<span style="color: #002200;">&#40;</span>ctxt<span style="color: #002200;">&#41;</span>;
    CGContextRestoreGState<span style="color: #002200;">&#40;</span>ctxt<span style="color: #002200;">&#41;</span>;
<span style="color: #002200;">&#125;</span></pre></div></div>

<p>Before calling the function, you should set the stroke color to 50% gray if you&#8217;re drawing on a white background or white if the control is highlighted and you&#8217;re drawing on a blue background. Or, <a href="http://stackoverflow.com/questions/1852672/best-way-to-change-the-color-view-of-disclosure-indicator-accessory-view-in-a-tab">you can use whatever color you like</a>.</p>
<p>To be honest, I only eyeballed the result, so it <em>might</em> not be a pixel-perfect reproduction of the real thing. However, I think my eyeballs are at least as good as most users&#8217; eyeballs, so I will confidently declare this code Good Enough.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/325/draw-your-own-disclosure-indicator/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nicer ways to view UNIX man pages</title>
		<link>http://www.benzado.com/blog/post/319/nicer-ways-to-view-unix-man-pages</link>
		<comments>http://www.benzado.com/blog/post/319/nicer-ways-to-view-unix-man-pages#comments</comments>
		<pubDate>Mon, 30 Nov 2009 02:38:57 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=319</guid>
		<description><![CDATA[There is a wealth of information available in the UNIX manual pages, but it feels a little silly to be reading text out of a terminal window, especially since I paid so much money for all this fancy font rendering technology. Here are some alternatives: To view a man page in Xcode&#8217;s documentation window, simply [...]]]></description>
			<content:encoded><![CDATA[<p>There is a wealth of information available in the <a href="http://en.wikipedia.org/wiki/Man_page">UNIX manual pages</a>, but it feels a little silly to be reading text out of a terminal window, especially since I paid so much money for <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/TextArchitecture/Concepts/ArchitectureOverview.html">all this fancy font rendering technology</a>.</p>
<p>Here are some alternatives:</p>
<p>To view a man page in Xcode&#8217;s documentation window, simply select &#8220;Open man Page&#8230;&#8221; from the Help menu. For some reason, I hadn&#8217;t noticed that menu item until I read this <a href="http://toxicsoftware.com/manoxcode/">hint on accessing it via AppleScript</a>. Nicely formatted and references to other man pages are hyperlinked.</p>
<p><a href="http://bruji.com/bwana/index.html">Bwana</a> allows you to read man pages in any web browser, by registering itself as a protocol handler for <code>man:</code> URLs. Once installed, you can type <code>man:perl</code> in your browser&#8217;s address bar or <code>open man:perl</code> at a command prompt to read a manual page in your browser. Like Xcode, cross-references become hyperlinks, but it formats text using Courier. Source code is available, so I guess if I care enough I can do something about it.</p>
<p>Finally, a surprisingly short incantation will <a href="http://www.macosxhints.com/article.php?story=20051225101106519">open any man page as a beautifully formatted document in Preview</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">man</span> <span style="color: #660033;">-t</span> <span style="color: #c20cb9; font-weight: bold;">perl</span> <span style="color: #000000; font-weight: bold;">|</span> open <span style="color: #660033;">-f</span> <span style="color: #660033;">-a</span> <span style="color: #000000; font-weight: bold;">/</span>Applications<span style="color: #000000; font-weight: bold;">/</span>Preview.app</pre></div></div>

<p>The <code>-t</code> option tells <code>man</code> to output PostScript, and the <code>-f</code> option tells <code>open</code> to put its input into a temporary file and pass that along to the specified application.</p>
<p>After reading that hint I set about writing a shell function so I could type <code>manp perl</code> to open Perl&#8217;s manual page in Preview. However, Preview&#8217;s PostScript to PDF conversion is kind of slow, so I wound up writing something slightly more sophisticated:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> manp <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #7a0874; font-weight: bold;">local</span> <span style="color: #007800;">M</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">man</span> <span style="color: #660033;">-w</span> <span style="color: #007800;">$*</span><span style="color: #000000; font-weight: bold;">`</span>               <span style="color: #666666; font-style: italic;"># Get path of page source.</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #007800;">$M</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span> <span style="color: #7a0874; font-weight: bold;">return</span>; <span style="color: #000000; font-weight: bold;">fi</span>     <span style="color: #666666; font-style: italic;"># Quit if it doesn't exist.</span>
    <span style="color: #7a0874; font-weight: bold;">local</span> <span style="color: #007800;">N</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">basename</span> <span style="color: #007800;">$M</span> .gz<span style="color: #000000; font-weight: bold;">`</span>         <span style="color: #666666; font-style: italic;"># Extract the name of the file and</span>
    <span style="color: #7a0874; font-weight: bold;">local</span> <span style="color: #007800;">P</span>=<span style="color: #007800;">$TMPDIR</span><span style="color: #000000; font-weight: bold;">/</span>man.<span style="color: #007800;">$N</span>.pdf        <span style="color: #666666; font-style: italic;"># use it to create a PDF file name.</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-e</span> <span style="color: #007800;">$P</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>              <span style="color: #666666; font-style: italic;"># If the PDF file doesn't exist,</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> Creating PDF <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #007800;">$N</span>... 
        <span style="color: #c20cb9; font-weight: bold;">man</span> <span style="color: #660033;">-t</span> <span style="color: #007800;">$1</span> <span style="color: #000000; font-weight: bold;">|</span> pstopdf <span style="color: #660033;">-i</span> <span style="color: #660033;">-o</span> <span style="color: #007800;">$P</span>  <span style="color: #666666; font-style: italic;"># generate it.</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
    open <span style="color: #007800;">$P</span>                           <span style="color: #666666; font-style: italic;"># Open the PDF version.</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span></pre></div></div>

<p>Then I went back and read the <a href="http://www.macosxhints.com/article.php?story=20051225101106519#comments">comments</a>, which contain a dozen or so different versions of the same idea. But mine&#8217;s the best! Copy and paste it into the your <code>.profile</code> if you agree.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/319/nicer-ways-to-view-unix-man-pages/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t printf when you can tcpdump</title>
		<link>http://www.benzado.com/blog/post/317/dont-printf-when-you-can-tcpdump</link>
		<comments>http://www.benzado.com/blog/post/317/dont-printf-when-you-can-tcpdump#comments</comments>
		<pubDate>Tue, 10 Nov 2009 23:04:20 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[tcpdump]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=317</guid>
		<description><![CDATA[Instead of using print statements to debug network communication, use tcpdump and get a complete and accurate picture of what's on the wire.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on an app that talks to a web service, and in the course of debugging it&#8217;s good to know what exactly is being sent to and from the web server. I had been doing so with the tried and true method of <a href="http://stackoverflow.com/questions/189562/what-is-the-proper-name-for-doing-debugging-by-adding-print-statements">printf() debugging</a> (this is Cocoa, so NSLog() debugging, actually), but it was getting to be a pain:</p>
<ol>
<li>If I print all network traffic all the time, it overwhelms my console, making it useless for any other kind of output. So instead, I&#8217;m constantly inserting or removing NSLog() statements as I work. Not to mention having to reproduce a request because the right logging statements weren&#8217;t in place the first time around.</li>
<li>NSURLConnection returns downloaded information as an NSData object, so simply passing it to NSLog() dumps a lot of useless hexadecimal code to the screen. That means I must first create an NSString from the data, print it, then release it. (I can&#8217;t use %s, the data isn&#8217;t null terminated.)</li>
<li>NSURLConnection does a lot of behind the scenes work, like storing cookies and setting Content-Length headers. That&#8217;s nice, but that makes it hard to know exactly what&#8217;s being sent on the wire.</li>
</ol>
<p>And that&#8217;s when it occurred to me: why not just watch what&#8217;s on the wire? tcpdump is a command line utility which monitors network traffic and prints out packets that you specify.</p>
<p>Here&#8217;s the incantation to monitor HTTP traffic to and from a specified host:</p>
<blockquote><p><code>sudo tcpdump -l -q -A "host <b>(Specified Host)</b> and tcp port 80 and (((ip[2:2] - ((ip[0]&#038;0xf)<<2)) - ((tcp[12]&#038;0xf0)>>2)) != 0)"</code></p></blockquote>
<p>To explain briefly, <code>sudo</code> runs the command as root, <code>-l</code> enables line buffering, <code>-q</code> hides some of the less interesting protocol information, and <code>-A</code> prints the content of each packet in ASCII. The filtering expression that follows selects packets to or from (Specified Host), to or from port 80, and ignoring SYN, FIN, ACK-only, and other non-data packets. I&#8217;ll confess, I don&#8217;t understand that last part completely, I copied it from the <a href="http://linux.die.net/man/8/tcpdump">tcpdump man page</a>.</p>
<p>To make the output a little easier to read, I pipe the output to a Perl script I quickly hacked together which watches for the packet header lines and outputs the <a href="http://isthe.com/chongo/tech/comp/ansi_escapes.html">ANSI escape codes</a> to render them in bold. But I&#8217;ll leave that as an exercise to you, dear reader.</p>
<p>There&#8217;s no need to download anything, tcpdump is already installed on your Mac. (I don&#8217;t know if it&#8217;s part of the standard install or the Developer Tools, but what do you care?)</p>
<p>Now, what would be <em>really</em> sweet is a graphical app to do this. I found <a href="http://www.tastycocoabytes.com/cpa/">Cocoa Packet Analyzer</a>, but it&#8217;s a little low-level for me. I don&#8217;t care about packet specifics; I&#8217;d prefer something that reconstructed the tcp streams in an easy to navigate way.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/317/dont-printf-when-you-can-tcpdump/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Spam Filter for Facebook Events</title>
		<link>http://www.benzado.com/blog/post/290/fb-events-filter</link>
		<comments>http://www.benzado.com/blog/post/290/fb-events-filter#comments</comments>
		<pubDate>Fri, 16 Oct 2009 19:46:56 +0000</pubDate>
		<dc:creator>Benjamin</dc:creator>
				<category><![CDATA[Nerdery]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Google Calendar]]></category>
		<category><![CDATA[iCal]]></category>
		<category><![CDATA[icalproxy]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.benzado.com/blog/?p=290</guid>
		<description><![CDATA[I love that Facebook exports events as a calendar that I can subscribe to in Apple iCal or Google Calendar. It saves much copying and pasting. Unfortunately, somebody is almost always creating an event that spans several days. Then my calendar looks like this: This is annoying, because that purple monster isn&#8217;t even a real [...]]]></description>
			<content:encoded><![CDATA[<p>I love that Facebook exports events as a calendar that I can subscribe to in Apple iCal or Google Calendar. It saves much copying and pasting. Unfortunately, somebody is almost always creating an event that spans several days. Then my calendar looks like this:</p>
<p><img class="aligncenter size-medium wp-image-344" title="Giant event messing up my calendar" src="http://www.benzado.com/blog/wp-content/uploads/2010/09/iCalScreenShot-300x195.png" alt="" width="300" height="195" /></p>
<p>This is annoying, because that purple monster isn&#8217;t even a real event; it&#8217;s just a notice that <a href="http://www.amazon.com/gp/product/B002FQ8NEM?ie=UTF8tag=benjpeteragh-20linkCode=as2camp=1789creative=390957creativeASIN=B002FQ8NEM">somebody&#8217;s film is available for download from Amazon</a><img style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.com/e/ir?t=benjpeteragh-20l=as2o=1a=B002FQ8NEM" border="0" alt="" width="1" height="1" />. As much as I encourage everybody to watch that film, I don&#8217;t want it eating up my calendar. I am routinely invited to events like this, and they are always announcements, or &#8220;I&#8217;m looking for a roommate,&#8221; or &#8220;I was too lazy to create four separate events for the show I&#8217;m doing four times this month.&#8221; In other words, calendar spam.</p>
<p>This would be tolerable, if there were some way to hide individual events, but there isn&#8217;t. Facebook includes every event you&#8217;ve been invited to, even if you RSVP: Not Attending. You can uninvite yourself using the &#8220;Remove from My Events&#8221; link, but it&#8217;s tedious and doesn&#8217;t protect you from being re-invited in the future. It&#8217;s also of no use if you&#8217;re away from the computer and viewing your calendar on your iPhone.</p>
<h3>How to Clean Your Calendar</h3>
<p>I solved the problem with a program that acts as a proxy between your calendar app and Facebook, removing events that are longer than 12 hours. It&#8217;s on the web, so you can use it, too.</p>
<p>First, find your Facebook Calendar URL by going to <a href="http://www.facebook.com/events.php">Facebook Events</a> and clicking &#8220;Export Events&#8221; in the top left corner. A box will appear with an address that looks something like this:</p>
<pre>http://www.facebook.com/ical/u.php?uid=123456&amp;key=789abcdef</pre>
<p>To use the filter, change the first part of the address (everything before the question mark) so that it looks like this:</p>
<pre>http://www.benzado.com/bin/icalproxy.php?uid=123456&amp;key=789abcdef</pre>
<p>Then you can use the new address to subscribe to your filtered calendar in apps like <a href="http://docs.info.apple.com/article.html?path=iCal/4.0/en/9869.html">Apple iCal</a> or <a href="http://www.google.com/support/calendar/bin/answer.py?hl=enanswer=37100">Google Calendar</a>.</p>
<p>Note that using my filter means your events pass through my web server, and even though I&#8217;m not really interested in looking at them, I could. So if you&#8217;re super concerned about your privacy, keep that in mind.</p>
<p>If you&#8217;d like to see how the script works or make a copy to run on your own server, you can <a href="http://www.benzado.com/bin/icalproxy.php?getsrc">view the source code</a>. If you extend it in any interesting ways, please let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.benzado.com/blog/post/290/fb-events-filter/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Served from: www.benzado.com @ 2012-02-04 20:16:04 by W3 Total Cache -->
