<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
  	<atom:link href="http://unflyingobject.com/blog/rss.php" rel="self" type="application/rss+xml" />
    <title>unflyingobject.com - for the thrill of understanding</title>
  	<link>http://unflyingobject.com/blog/</link>
		<description>mac geekery</description>
		<language>en-us</language>
		<ttl>500</ttl>


	  <item>
	    <title>
  	    <![CDATA[AppleScript's path to me]]>
    	</title>
   		<pubDate>Fri, 05 Sep 2008 19:31:52 +0300</pubDate>
	   	<link>http://unflyingobject.com/blog/posts/1220632312</link>
  	 	<guid>http://unflyingobject.com/blog/posts/1220632312</guid>
			<author>filipp@mechmail.net (Filipp Lepalaan)</author>
			<description>
				<![CDATA[<p>Just something to be aware of:</p>

<pre><code>POSIX path of (path to me) &amp; "Contents/Resources" as string
-&gt; "/Users/flepalaa/Desktop/Backup.app/Contents/Resources"
property myPath : POSIX path of (path to me) &amp; "Contents/Resources" as string
set the result to myPath
-&gt; "/Applications/AppleScript/Script Editor.app/Contents/Resources"
</code></pre>

<p><a href="http://www.macosxhints.com/article.php?story=20080223103121102">Apparently</a> the latter is what <em>path to me</em> was "supposed" to mean before 10.5. AppleScript makes me want to smoke crack. :P</p>
]]>
			</description>
		</item>


	  <item>
	    <title>
  	    <![CDATA[serveradmin settings indices]]>
    	</title>
   		<pubDate>Tue, 02 Sep 2008 11:20:02 +0300</pubDate>
	   	<link>http://unflyingobject.com/blog/posts/1220343602</link>
  	 	<guid>http://unflyingobject.com/blog/posts/1220343602</guid>
			<author>filipp@mechmail.net (Filipp Lepalaan)</author>
			<description>
				<![CDATA[<p>There's one more really annoying thing with <em>serveradmin</em>:</p>

<pre><code>mail:~ file$ sudo serveradmin settings vpn:Servers:com.apple.ppp.pptp:IPv4:DestAddressRanges:_array_index:0 = \"10.64.200.200\"
vpn:Servers:com.apple.ppp.pptp:IPv4:DestAddressRanges:_array_index:0 = "10.64.200.200"
mail:~ file$ sudo serveradmin settings vpn:Servers:com.apple.ppp.pptp:IPv4:DestAddressRanges:_array_index:1 = \"10.64.200.254\"
Invalid index "1", must specifiy array elements in order
Index = 1, count = 0, currentArray = ()
for key: "vpn:Servers:com.apple.ppp.pptp:IPv4:DestAddressRanges:_array_index:1"
</code></pre>

<p>And actually the manpage doesn't say anything about how to work with numeric indices:</p>

<blockquote>
  <p>"When setting array values, special notation is needed. There are two types of arrays. Some arrays have special id keys that allow you to access individual array elements. These are accessed using the special key _array_id followed by the value of the id tag (eg. web:Mod-ules:_array_id:dav_module). To add a new element to such an array, you need to have a special line with a "create" value".</p>
</blockquote>

<p>I struggled a lot with this trying to bring a dead VPN service back to life (it had lost all its settings). I finally ended up exprting the settings from another 10.4 server and importing them in, but then I discovered this workaround:</p>

<pre><code>mail:~ file$ cat - | sudo serveradmin settings
vpn:Servers:com.apple.ppp.pptp:IPv4:DestAddressRanges:_array_index:0 = "10.64.200.200"
vpn:Servers:com.apple.ppp.pptp:IPv4:DestAddressRanges:_array_index:1 = "10.64.200.254"
</code></pre>

<p>and it worked. That's right  - if you want to use numeric indices, <strong>you must provide the whole array every time you make a change</strong>. So basically dump the existing settings, append your new element and then set the whole array.</p>
]]>
			</description>
		</item>


	  <item>
	    <title>
  	    <![CDATA[serveradmin settings all]]>
    	</title>
   		<pubDate>Mon, 01 Sep 2008 15:06:22 +0300</pubDate>
	   	<link>http://unflyingobject.com/blog/posts/1220270782</link>
  	 	<guid>http://unflyingobject.com/blog/posts/1220270782</guid>
			<author>filipp@mechmail.net (Filipp Lepalaan)</author>
			<description>
				<![CDATA[<p>Trying to back up 10.4 server settings, you might run into this gross <em>serveradmin</em> bug:</p>

<pre><code>machine:~ root# serveradmin settings all &gt; all.sabackup
2008-09-01 14:34:43.994 serveradmin[12811] Exception in doCommand: *** -[NSCFArray objectAtIndex:]: index (0) beyond bounds (0)
serveradmin(12811,0xa000ed88) malloc: ***  Deallocation of a pointer not malloced: 0x15c3bc0; This could be a double free(), or free() called with the middle of an allocated block; Try setting environment variable MallocHelp to see tools to help debug
</code></pre>

<p>But luckily it's easy to work around with a little bit of shell:</p>

<pre><code>for s in $(serveradmin list); do serveradmin settings $s &gt;&gt; all.sabackup; done
</code></pre>

<p>Save that as a Bash function and you're good to go.</p>
]]>
			</description>
		</item>


	  <item>
	    <title>
  	    <![CDATA[serveradmin settings & IP addresses]]>
    	</title>
   		<pubDate>Mon, 01 Sep 2008 14:42:00 +0300</pubDate>
	   	<link>http://unflyingobject.com/blog/posts/1220269320</link>
  	 	<guid>http://unflyingobject.com/blog/posts/1220269320</guid>
			<author>filipp@mechmail.net (Filipp Lepalaan)</author>
			<description>
				<![CDATA[<p>In 2005 I <a href="http://lists.apple.com/archives/macos-x-server/2005/dec/msg00385.html">complained</a> about a bug in <a href="http://www.manpagez.com/man/8/serveradmin/">serveradmin</a> which resulted in garbled input when using IP numbers. It's not just with DNS either, the same problem exists also with VPN settings. 10.4.11 has this bug as well:</p>

<pre><code>machine:~ root# serveradmin settings \
    vpn:Servers:com.apple.ppp.pptp:IPv4:DestAddressRanges:_array_index:0 = "192.168.2.200"
vpn:Servers:com.apple.ppp.pptp:IPv4:DestAddressRanges:_array_index:0 = 192.167999
</code></pre>

<p>Gross. Here's the "workaround":</p>

<pre><code>machine:~ root# serveradmin settings \
    vpn:Servers:com.apple.ppp.pptp:IPv4:DestAddressRanges:_array_index:0 = \"192.168.2.200\"
</code></pre>

<p>In other words, shell is chomping the quotes and <em>serveradmin</em> gets confused with the dotted quad. I still think this is a bug with <em>serveradmin</em>, or with the documentation, at least. :-/</p>

<p>Oh, and <a href="http://barebones.com/support/bbedit/arch_bbedit9.html">BBEdit 9 is out</a></p>
]]>
			</description>
		</item>


	  <item>
	    <title>
  	    <![CDATA[GoogleConverter]]>
    	</title>
   		<pubDate>Sat, 30 Aug 2008 10:11:47 +0300</pubDate>
	   	<link>http://unflyingobject.com/blog/posts/1220080307</link>
  	 	<guid>http://unflyingobject.com/blog/posts/1220080307</guid>
			<author>filipp@mechmail.net (Filipp Lepalaan)</author>
			<description>
				<![CDATA[<p>A fun little project that could serve well in an "intro to practical programming" course:</p>

<pre><code>filipp@probook.local [~]  &gt; gc 14 in in cm
14 in = 35.56 centimeters
</code></pre>

<p>Wait, but we already have <a href="http://developer.apple.com/documentation/Darwin/Reference/ManPages/man1/units.1.html">units(1)</a>! Yes, but can it do this:</p>

<pre><code>filipp@probook.local [~]  &gt; gc 14,9 usd in eur
14,9 U.S. dollars = 10,1650976 Euros
</code></pre>

<p>All a whopping 8 lines of PHP (the working man's language):</p>

<pre><code>#!/usr/bin/env php
&lt;?php

  array_shift ($argv);
  if (count ($argv) == 0) die ("Not enough arguments\n");
  $q = implode ("+", $argv);
  $c = file_get_contents ("http://www.google.com/search?q=$q");
  preg_match ('/&lt;div id=res.+?&lt;\/h2&gt;/', $c, $r);
  $a = str_replace ('&amp;nbsp;', '', strip_tags ($r[0]));
  if ($a == "Search Results") $a = "No results";
  printf ("%s\n", $a);

?&gt;
</code></pre>

<p>:)</p>
]]>
			</description>
		</item>


	  <item>
	    <title>
  	    <![CDATA[Microsoft's New Hope]]>
    	</title>
   		<pubDate>Mon, 21 Jul 2008 21:31:54 +0300</pubDate>
	   	<link>http://unflyingobject.com/blog/posts/1216665114</link>
  	 	<guid>http://unflyingobject.com/blog/posts/1216665114</guid>
			<author>filipp@mechmail.net (Filipp Lepalaan)</author>
			<description>
				<![CDATA[<p>You know Vista's in trouble when you suddenly find this in your inbox:
<img src="http://unflyingobject.com/tmp/msjolie.png" alt="MS Jolie" /></p>
]]>
			</description>
		</item>


	  <item>
	    <title>
  	    <![CDATA[last.fm and WebClip]]>
    	</title>
   		<pubDate>Fri, 18 Jul 2008 15:44:49 +0300</pubDate>
	   	<link>http://unflyingobject.com/blog/posts/1216385089</link>
  	 	<guid>http://unflyingobject.com/blog/posts/1216385089</guid>
			<author>filipp@mechmail.net (Filipp Lepalaan)</author>
			<description>
				<![CDATA[<p>When WebClip was first demoed I thought it was the coolest thing ever. About a year (?)
later, I finally found a use for it - a lightweight last.fm radio player.</p>

<ul>
<li>Go to your last.fm > Listen</li>
<li>File > Open in Dashboard</li>
<li>Hover over the Flash player, click + Enter</li>
<li>Flip the widget and uncheck "Only play audio in Dashboard"</li>
</ul>

<p><img src="http://unflyingobject.com/tmp/lfmWebClip.jpg" alt="lfmWebClip" /></p>
]]>
			</description>
		</item>


	  <item>
	    <title>
  	    <![CDATA[Going Oldschool]]>
    	</title>
   		<pubDate>Fri, 18 Jul 2008 09:22:27 +0300</pubDate>
	   	<link>http://unflyingobject.com/blog/posts/1216362147</link>
  	 	<guid>http://unflyingobject.com/blog/posts/1216362147</guid>
			<author>filipp@mechmail.net (Filipp Lepalaan)</author>
			<description>
				<![CDATA[<p>This site has been majorly downgraded today. I ditched the old XML-RPC blog engine and
replaced it with a shiny, yet totally oldschool text file based solution. Sure, it doesn't
have comments or categories, but there's something incredibly liberating to sit here and blog
using nano over SSH.</p>

<p>The RSS should work, and an Apache Redirect makes sure the old RSS links still work,
but previous links to old stories have not been remapped (the new system just uses the
text file's mtime's timestamp as the ID, while the old one used a counter). Also
direct links to posts are broken for now.</p>

<p>I don't even feel terribly bad about not having comments either - most of the stuff here is just
inane technobabble anyways. If you do feel like commenting or sending a suggestion, then feel
free to do so at <a href="mailto:filipp.mechmal.net">filipp@mechmail.net</a>.</p>

<p>The new blogging engine is about a whopping 30 lines of PHP.</p>
]]>
			</description>
		</item>


	  <item>
	    <title>
  	    <![CDATA[Migrating Group Wiki Pages]]>
    	</title>
   		<pubDate>Fri, 18 Jul 2008 09:05:34 +0300</pubDate>
	   	<link>http://unflyingobject.com/blog/posts/1216361134</link>
  	 	<guid>http://unflyingobject.com/blog/posts/1216361134</guid>
			<author>filipp@mechmail.net (Filipp Lepalaan)</author>
			<description>
				<![CDATA[<p>It's surprisingly difficult to transfer entire wikis between groups
since it's not just a matter of copying static HTML files as I thought previously.
Here's a rough sketch of the process. It worked for me, but might not for everyone.</p>

<pre><code># wikimove from to
SRC=$1; DST=$2
cd /Library/Collaboration/Groups

# Take a backup
cp -r $SRC $SRC.bak; cp -r $DST $DST.bak

# Transfer the old search indices
sqlite3 $SRC/wiki/index.db .dump | sed 's/groups\/$SRC\//groups\/$DST\//' | sqlite3 $DST/wiki/index.db
chown teamsserver $DST/wiki/index.db;
chmod 0750 $DST/wiki/index.db
sed 's/groups\/$SRC\//groups\/$DST\//' $SRC/extrainfo &gt;&gt; $DST/extrainfo

# Transfer the actual documents and metadata
mv $SRC/wiki/*.page $DST/wiki/
cd $DST/wiki
for p in *.page ; do sed -i '' 's/groups\/$SRC\//groups\/$DST\//g' $p/page.html; done
for p in *.page ; do sed -i '' 's/groups\/$SRC\//groups\/$DST\//g' $p/page.plist; done
</code></pre>

<p>Don't forget to clean those .bak directories or else wikid will not start due to permissions errors. You'll still 
have references to your old group wiki inside the revisions.db files which you can get rid of with:</p>

<pre><code>for p in *.page ; 
    do sqlite3 $p/revisions.db .dump | sed 's/groups\/$SRC\//groups\/$DST\//g' &gt; /tmp/revisions.sql
    rm $p/revisions.db
    sqlite3 $p/revisions.db &lt; /tmp/revisions.sql
done

srm /tmp/revisions.sql
</code></pre>

<h2>Disaster recovery</h2>

<p>If you accidentally hose a group wiki's page.plist and page.html files, it's possible to recover the latest versions 
of the pages, if you still have the revisions.db files intact. Here's how I did it:</p>

<pre><code>cd group/wiki
for p in *.page ;
    do sqlite3 $p/revisions.db "select content from revisions order by revision desc limit 1" &gt; /tmp/wikitmp.plist
  defaults read /tmp/wikitmp content &gt; $p/page.html;
    defaults delete /tmp/wikitmp content;
    defaults write /tmp/wikitmp 'modifiedDate' -date $(defaults read /tmp/wikitmp modifiedDate | cut -d . -f 1)
    plutil -convert xml1 /tmp/wikitmp.plist -o $p/page.plist;
    done

srm /tmp/wikitmp.plist
</code></pre>

<p>This breaks things like accented characters (replaced by codes returned from defaults), but it sure beats rewriting 
every single page. :P</p>
]]>
			</description>
		</item>


	  <item>
	    <title>
  	    <![CDATA[Use Expect for SMTP testing]]>
    	</title>
   		<pubDate>Thu, 10 Jul 2008 13:39:51 +0300</pubDate>
	   	<link>http://unflyingobject.com/blog/posts/1215686391</link>
  	 	<guid>http://unflyingobject.com/blog/posts/1215686391</guid>
			<author>filipp@mechmail.net (Filipp Lepalaan)</author>
			<description>
				<![CDATA[<p>I learned about <a href="http://expect.nist.gov/">Expect</a> from a past ADC video session about OS X deployment. Here's a very practical use for it - testing an SMTP server. Just run it with <em>expect filename</em>.</p>

<pre><code>spawn telnet smtpserver 25
expect "220 "
send "MAIL FROM:test@example.comr"
expect "250 Ok$"
send "RCPT TO:testuser@serverr"
expect "250 Ok$"
send "DATAr"
expect "354"
send "From: "SMTP Test" &lt;test@example.com&gt;
Subject: This is a test
Date: Wed, 02 Jul 2008 15:08:43 +0000
Body of test message r.r"
expect "250 Ok$"
send "QUITr"
</code></pre>
]]>
			</description>
		</item>


  </channel>
</rss>
