<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5385036587194404038</id><updated>2012-01-31T14:33:10.559-08:00</updated><title type='text'>Technical notes, my online memory</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default?start-index=101&amp;max-results=100'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>253</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-962814888756279176</id><published>2012-01-16T22:04:00.000-08:00</published><updated>2012-01-16T22:04:37.686-08:00</updated><title type='text'>Really basic wireless survey with built-in linux tools</title><content type='html'>What channel should I use for my access point?  It seems like I'm always asking this question as people start new access points in my neighbourhood.  Some wireless access points can pick a channel automatically, but my experience with this has been pretty poor. I suspect the algorithm is too simplistic to be of any use.  A naive implementation might pick the first channel that has no other APs on it, which could be a terrible choice if the strongest interference signal is on the adjacent channel.&lt;br /&gt;&lt;br /&gt;Ideally you want to pick the channel that gives you the best signal-to-noise ratio, but where there are heaps of APs at varying strengths in different parts of the house the choice is non-obvious.  Sadly there doesn't seem to be a FOSS wireless survey tool like &lt;a href="http://reactivated.net/writing_udev_rules.html#ownership"&gt;Fluke AirMagnet&lt;/a&gt;, and while you can use &lt;a href="http://www.kismetwireless.net/"&gt;kismet&lt;/a&gt; to collect signal strength data you will have to do some analysis of the data yourself (my wireless card also didn't play well with kismet).&lt;br /&gt;&lt;br /&gt;I decided to optimise for one location - where I use the laptop the most.  So I set my AP to channel 1 and:&lt;br /&gt;&lt;pre&gt;sudo iwlist wlan0 scanning &gt; ch1.txt&lt;br /&gt;&lt;/pre&gt;Rinse and repeat for all the other channels (setting the channel on my AP is quick, but this might be impractical if yours is slow, requires re-auth etc.).  Then compare the signal strengths:&lt;br /&gt;&lt;pre&gt;grep --before-context=4 "myessid" ch*.txt&lt;br /&gt;&lt;/pre&gt;Pick the channel with the highest quality number (best signal strength).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-962814888756279176?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/962814888756279176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=962814888756279176' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/962814888756279176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/962814888756279176'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2012/01/really-basic-wireless-survey-with-built.html' title='Really basic wireless survey with built-in linux tools'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-2145568684482895290</id><published>2012-01-16T21:42:00.000-08:00</published><updated>2012-01-16T22:05:44.152-08:00</updated><title type='text'>Root a TMobile MyTouch 4G (HTC Glacier) to install Cyanogen</title><content type='html'>This was my first time rooting an android phone.  There are most probably better ways to do this, but here are my notes for better or worse.  I followed &lt;a href="http://wiki.cyanogenmod.com/wiki/HTC_Glacier:_Full_Update_Guide#Rooting_the_HTC_Glacier"&gt;these instructions&lt;/a&gt;, which were pretty good and I won't reproduce them, so consider this a diff.  First install the jdk from the 'default-jdk' apt package.&lt;br /&gt;&lt;br /&gt;Install the &lt;a href="http://developer.android.com/sdk/index.html"&gt;Android SDK&lt;/a&gt;, including the platform-tools component to get adb.  If you try to use it without root you'll get a permissions error like this:&lt;br /&gt;&lt;pre&gt;$ android-sdk-linux/platform-tools/adb devices&lt;br /&gt;List of devices attached &lt;br /&gt;???????????? no permissions&lt;br /&gt;&lt;/pre&gt;Add this UDEV rule to /etc/udev/rules.d/51-android.rules.  Note this gives &lt;a href="http://reactivated.net/writing_udev_rules.html#ownership"&gt;all users write permissions&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;SUBSYSTEM=="usb", SYSFS{idVendor}=="0bb4", MODE="0666"&lt;br /&gt;&lt;/pre&gt;Plug it back in:&lt;br /&gt;&lt;pre&gt;$ android-sdk-linux/platform-tools/adb devices&lt;br /&gt;List of devices attached &lt;br /&gt;XXXXXXXXXXXX device&lt;br /&gt;&lt;/pre&gt;Change the mode on the phone to 'charge-only', and unmount the SD card if it is mounted.  This allows adb and subsequent rooting tools to access /sdcard.  If you have it in disk drive mode you'll get errors like these from adb:&lt;br /&gt;&lt;pre&gt;failed to copy 'Superuser.apk' to '/sdcard//Superuser.apk': Read-only file system&lt;br /&gt;&lt;/pre&gt;To do the cyangogen install you can use the 'ROM Manager' app by ClockworkMod, available in the android market.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-2145568684482895290?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/2145568684482895290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=2145568684482895290' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2145568684482895290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2145568684482895290'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2012/01/rooting-tmobile-mytouch-4g-htc-glacier.html' title='Root a TMobile MyTouch 4G (HTC Glacier) to install Cyanogen'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-5626353407352839235</id><published>2012-01-10T20:35:00.000-08:00</published><updated>2012-01-14T20:57:29.159-08:00</updated><title type='text'>Ubuntu system monitor in the taskbar post-unity (Natty and Oneiric)</title><content type='html'>With the &lt;a href="http://unity.ubuntu.com/"&gt;unity changes&lt;/a&gt; from Natty onward, the traditional Ubuntu gnome taskbar disappeared to be replaced by a set of &lt;a href="http://www.omgubuntu.co.uk/2011/01/the-omg-guide-to-must-have-indicator-applets/"&gt;application panel indicators&lt;/a&gt;.  I was used to seeing my machine vitals (cpu, network, load etc.) displayed using system monitor in the taskbar.  I was pleased to see that this can still be achieved by installing the 'indicator-multiload' package.&lt;br /&gt;&lt;br /&gt;Depending on the version you have, the autostart &lt;a href="https://bugs.launchpad.net/indicator-multiload/+bug/836893"&gt;might not work&lt;/a&gt;.  If it doesn't, just:&lt;br /&gt;&lt;pre&gt;mkdir ~/.config/autostart&lt;br /&gt;&lt;/pre&gt;and toggle the 'autostart' checkbox under preferences.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-5626353407352839235?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/5626353407352839235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=5626353407352839235' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5626353407352839235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5626353407352839235'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2012/01/ubuntu-system-monitor-in-taskbar-post.html' title='Ubuntu system monitor in the taskbar post-unity (Natty and Oneiric)'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-3594911049253788640</id><published>2012-01-09T21:23:00.000-08:00</published><updated>2012-01-30T17:35:02.481-08:00</updated><title type='text'>Broken BCM4313 "ping: sendmsg: No buffer space available"</title><content type='html'>My Broadcom wireless card was broken on Ubuntu 11.10 Oneiric Ocelot.  The card connected to my AP fine, but after a short time would barf.  A ping to the AP would return a few successful replies followed by:&lt;br /&gt;&lt;pre&gt;ping: sendmsg: No buffer space available&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is a &lt;a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/871580"&gt;known issue&lt;/a&gt;, and seems to affect &lt;a href="http://ubuntuforums.org/showthread.php?t=1832771"&gt;quite a few people&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;First I tried installing the proprietary broadcom driver from the 'broadcom-sta-common' package, but that was worse - it wouldn't even recognise the interface.  I tried a whole bunch of later kernels and finally found one that worked: 3.1.8.&lt;br /&gt;&lt;br /&gt;The ubuntu &lt;a href="http://kernel.ubuntu.com/~kernel-ppa/mainline/"&gt;mainline kernel repo&lt;/a&gt; makes &lt;a href="https://wiki.ubuntu.com/Kernel/MainlineBuilds?action=show&amp;redirect=KernelMainlineBuilds"&gt;trying new kernels easy&lt;/a&gt;.  Just download and install these debs:&lt;br /&gt;&lt;pre&gt;linux-headers-3.1.8-030108_3.1.8-030108.201201061759_all.deb&lt;br /&gt;linux-headers-3.1.8-030108-generic-pae_3.1.8-030108.201201061759_i386.deb&lt;br /&gt;linux-image-3.1.8-030108-generic_3.1.8-030108.201201061759_i386.deb&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Update:&lt;/b&gt; spoke too soon.  This is still broken on 3.1.8 it just takes longer to manifest.  I'm now also seeing a bunch of these messages:&lt;br /&gt;&lt;pre&gt;kernel: [25244.951243] ieee80211 phy0: START: tid 1 is not agg'able&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Update 2012-01-30:&lt;/b&gt;  Now I'm also seeing lots of this:&lt;br /&gt;&lt;pre&gt;ieee80211 phy0: brcms_c_prec_enq_head: No where to go, prec == 4&lt;br /&gt;&lt;/pre&gt;I'm going to up net.core.rmem and net.core.wmem as suggested in a comment, but that's really only treating the symptoms.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-3594911049253788640?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/3594911049253788640/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=3594911049253788640' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3594911049253788640'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3594911049253788640'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2012/01/broken-bcm4313-ping-sendmsg-no-buffer.html' title='Broken BCM4313 &quot;ping: sendmsg: No buffer space available&quot;'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-4039369073498753386</id><published>2012-01-06T16:18:00.000-08:00</published><updated>2012-01-13T16:15:07.153-08:00</updated><title type='text'>Firewire and DMA attacks on OS X</title><content type='html'>I recently spent some time testing Firewire memory access on OS X to determine the current state of vulnerability to DMA attacks.  There is a lot of prior art (&lt;a href="http://www.hermann-uwe.de/blog/physical-memory-attacks-via-firewire-dma-part-1-overview-and-mitigation"&gt;Uwe Hermann has a good summary&lt;/a&gt;), and I was particularly interested in the claims of &lt;a href="http://www.frameloss.org/2011/09/18/firewire-attacks-against-mac-os-lion-filevault-2-encryption/"&gt;deficiencies in the DMA defences provided by Lion&lt;/a&gt; (&lt;b&gt;Update:&lt;/b&gt; it looks like this was CVE-2011-3215 &lt;a href="http://support.apple.com/kb/HT5002"&gt;fixed in 10.7.2&lt;/a&gt;, which agrees with my findings).&lt;br /&gt;&lt;br /&gt;To check for &lt;a href="http://en.wikipedia.org/wiki/File:FireWire-46_Diagram.svg"&gt;firewire&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Thunderbolt_(interface)"&gt;thunderbolt&lt;/a&gt; ports programmatically you can parse the output of system_profiler:&lt;br /&gt;&lt;pre&gt;$ system_profiler SPFireWireDataType SPThunderboltDataType&lt;br /&gt;FireWire:&lt;br /&gt;&lt;br /&gt;    FireWire Bus:&lt;br /&gt;&lt;br /&gt;      Maximum Speed: Up to 800 Mb/sec&lt;br /&gt;       ...&lt;br /&gt;&lt;br /&gt;Thunderbolt:&lt;br /&gt;&lt;br /&gt;    MacBook Pro:&lt;br /&gt;&lt;br /&gt;      Vendor Name: Apple, Inc.&lt;br /&gt;      Device Name: MacBook Pro&lt;br /&gt;      UID: 0x0001000A19999900&lt;br /&gt;       ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I used two MacBookPros, one running 10.6.8 and one running 10.7.2 fully patched as at 2011-12-29.  Hardware specs:&lt;br /&gt;&lt;pre&gt;$ system_profiler SPHardwareDataType&lt;br /&gt;&lt;br /&gt;Model Name: MacBook Pro&lt;br /&gt;Model Identifier: MacBookPro8,2&lt;br /&gt;Processor Name: Intel Core i7&lt;br /&gt;Processor Speed: 2 GHz&lt;br /&gt;  ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I used the &lt;a href="http://c0re.23.nu/c0de/pyfw/"&gt;pyfw-20041111 module&lt;/a&gt; to do the DMA using dumpmem which reads 256MB from 0x10000000:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;python demo_dumpmem.py&lt;br /&gt;hexdump -C cfffffffffffffff-10000000-20000000.memdump&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and I also tested using &lt;a href="http://www.frameloss.org/2011/09/18/firewire-attacks-against-mac-os-lion-filevault-2-encryption/"&gt;ramdump.py&lt;/a&gt; and the &lt;a href="https://freddie.witherden.org/tools/libforensic1394/"&gt;libforensic1394 libraries&lt;/a&gt;, with the same results.&lt;br /&gt;&lt;pre&gt;python ./ramdump.py 1024 f&lt;br /&gt;SBP-2 not used, forcing 2048 byte pages.&lt;br /&gt;[&amp;lt;forensic1394.device.Device object at 0xfffffffff&amp;gt;]&lt;br /&gt;Attempting to access device 0: Apple Computer, Inc. Macintosh&lt;br /&gt;Wrote file ramdump.bin.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;Target 10.7.2, attacked from 10.6.8.&lt;/h4&gt;&lt;br /&gt;When targeting the 10.7.2 machine I could only access memory when the screen was unlocked, in all other scenarios I just received zeros.  Note I tested with and without FileVault2 enabled, and the results were the same. &lt;br /&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Status&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;DMA Capture Result&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Logged in, not locked&lt;/td&gt;&lt;td&gt;Captured&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Logged in, locked&lt;/td&gt;&lt;td&gt;0s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Login, log out, at login screen&lt;/td&gt;&lt;td&gt;0s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;System booted, not logged in&lt;/td&gt;&lt;td&gt;0s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Switch user from fast user switching menu&lt;/td&gt;&lt;td&gt;0s&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;The cleartext password for the logged in user can be trivially retrieved with:&lt;br /&gt;&lt;pre&gt;strings memdump | grep --after-context=4 longname | grep --after-context=1 password&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;Target 10.6.8, attacked from 10.7.2.&lt;/h4&gt;&lt;br /&gt;10.6.8 is the complete opposite, capture is possible in all cases (note that there is a &lt;a href="http://ilostmynotes.blogspot.com/2012/01/os-x-open-firmware-settings-use-nvram.html"&gt;NVRAM setting that can be used to defend against this attack&lt;/a&gt; without requiring a firmware password).&lt;br /&gt;&lt;br /&gt;&lt;table border="1"&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Status&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;DMA Capture Result&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Logged in, not locked&lt;/td&gt;&lt;td&gt;Captured&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Logged in, locked&lt;/td&gt;&lt;td&gt;Captured&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Login, log out, at login screen&lt;/td&gt;&lt;td&gt;Captured&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;System booted, not logged in&lt;/td&gt;&lt;td&gt;Captured&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Switch user from fast user switching menu&lt;/td&gt;&lt;td&gt;Captured&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;Get cleartext password with:&lt;br /&gt;&lt;pre&gt;strings memdump | grep --after-context=3 managedUser | grep --after-context=1 password&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-4039369073498753386?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/4039369073498753386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=4039369073498753386' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4039369073498753386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4039369073498753386'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2012/01/firewire-and-dma-attacks-on-os-x.html' title='Firewire and DMA attacks on OS X'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-6322539937347499625</id><published>2012-01-06T16:11:00.000-08:00</published><updated>2012-01-06T16:11:30.767-08:00</updated><title type='text'>OS X Open Firmware settings: use nvram security-mode to disable firewire DMA without a firmware password</title><content type='html'>First some background.  OS X uses &lt;a href="http://osxbook.com/book/bonus/ancient/whatismacosx/arch_boot.html"&gt;Open Firmware, which is similar to a PC's BIOS&lt;/a&gt;.  The nvram utility can be used to manipulate Open Firmware settings stored in NVRAM.  Print NVRAM settings with:&lt;br /&gt;&lt;pre&gt;nvram -p&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For firewire DMA the important setting is security-mode.  Here is an explanation of the &lt;a href="http://www.securemac.com/openfirmwarepasswordprotection.php"&gt;different nvram security modes&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;The "none" mode effectively disables security. The "command" mode just restricts the commands that may be executed to "go" and "boot". Additionally, under the "command" mode, the "boot" command may not have any arguments--that is, it will only boot the device specified in the boot device variable; no other command may be entered or any settings changed unless the password is supplied. Moreover, this password protection feature also applies to booting up with the option key held down (which allows you to choose from available bootable volumes through a built-in graphical user interface). Finally, in "full" mode, the machine is completely prohibited from booting until the password is entered.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;To set a firmware password (&lt;a href="http://projects.puppetlabs.com/projects/1/wiki/Firmware_Password_Patterns"&gt;puppet recipe&lt;/a&gt;):&lt;br /&gt;&lt;pre&gt;nvram security-password=mypass&lt;br /&gt;nvram security-mode=command&lt;br /&gt;&lt;/pre&gt;Note that anyone with root can read the hex encoded password with nvram security-password.  To remove the password ('none' is the default security mode):&lt;br /&gt;&lt;pre&gt;nvram -d security-password&lt;br /&gt;nvram security-mode=none&lt;br /&gt;&lt;/pre&gt;When a firmware password is set, &lt;a href="http://matt.ucc.asn.au/apple/"&gt;Firewire DMA is disabled&lt;/a&gt;.  This can be abused to disable firewire DMA without setting a password - just by setting security-mode to something other than 'none'.  This works for example (and will take effect after a reboot):&lt;br /&gt;&lt;pre&gt;nvram security-mode=NONE&lt;br /&gt;&lt;/pre&gt;This causes the &lt;a href="http://opensource.apple.com/source/IOFireWireFamily/IOFireWireFamily-443.4.0/IOFireWireFamily.kmodproj/IOFireWireController.cpp"&gt;firewire controller&lt;/a&gt; to put itself into secure mode:&lt;br /&gt;&lt;pre&gt;OSString * securityModeProperty = OSDynamicCast( OSString, options-&gt;getProperty("security-mode") );&lt;br /&gt;if( securityModeProperty != NULL &amp;&amp; strncmp( "none", securityModeProperty-&gt;getCStringNoCopy(), 5 ) != 0 ) {&lt;br /&gt;  // set security mode to secure/permanent&lt;br /&gt;  mode = kIOFWSecurityModeSecurePermanent;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-6322539937347499625?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/6322539937347499625/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=6322539937347499625' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6322539937347499625'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6322539937347499625'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2012/01/os-x-open-firmware-settings-use-nvram.html' title='OS X Open Firmware settings: use nvram security-mode to disable firewire DMA without a firmware password'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-5918147471034190957</id><published>2012-01-06T10:53:00.000-08:00</published><updated>2012-01-06T10:53:39.194-08:00</updated><title type='text'>Gather OS X hardware and software information with system_profiler</title><content type='html'>system_profiler is a good way to gather lots of recon information about OS X hardware and software.  Some examples&lt;br /&gt;&lt;pre&gt;     system_profiler -detailLevel full&lt;br /&gt;       Gives you absolutely everything&lt;br /&gt;&lt;br /&gt;     system_profiler -listDataTypes&lt;br /&gt;       Shows a list of the available data types.&lt;br /&gt;&lt;br /&gt;     system_profiler SPSoftwareDataType SPNetworkDataType&lt;br /&gt;       Generates a text report containing only software and network data.&lt;br /&gt;&lt;br /&gt;     system_profiler SPThunderboltDataType SPFireWireDataType&lt;br /&gt;       Just firewire and thunderbolt interfaces&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-5918147471034190957?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/5918147471034190957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=5918147471034190957' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5918147471034190957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5918147471034190957'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2012/01/gather-os-x-hardware-and-software.html' title='Gather OS X hardware and software information with system_profiler'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1025339250899331264</id><published>2011-12-29T12:37:00.000-08:00</published><updated>2011-12-29T12:37:16.415-08:00</updated><title type='text'>OS X hidden folders, extended attributes, flags, and file ACLs</title><content type='html'>On lion the ~/Library directory is hidden by default in Finder.  This doesn't bother me normally, since I rarely use Finder and it is visible on the commandline, but I recently got stuck needing to submit logs from ~/Library using a web-based form.&lt;br /&gt;&lt;br /&gt;There are some &lt;a href="http://osxdaily.com/2011/07/22/access-user-library-folder-in-os-x-lion/"&gt;one-off tricks&lt;/a&gt; you can use to access it, but, as far as I can see, no equivalent of the windows 'show hidden files' setting in Finder.  &lt;br /&gt;&lt;br /&gt;To see extended attributes (indicated by trailing @), &lt;a href="http://aplawrence.com/MacOSX/acl.html"&gt;file ACLs&lt;/a&gt; (indicated by trailing +), and flags, use this:&lt;br /&gt;&lt;pre&gt;$ ls -l@eOd Library/&lt;br /&gt;drwx------@ 38 user  group  hidden 1292 Dec 28 16:02 Library/&lt;br /&gt; com.apple.FinderInfo   32 &lt;br /&gt; 0: group:everyone deny delete&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can manipulate the 'hidden' flag (which seems to actually be implemented as a FinderInfo attribute) and others with chflags:&lt;br /&gt;&lt;pre&gt;chflags nohidden Library&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Which gives:&lt;br /&gt;&lt;pre&gt;$ ls -l@eOd Library/&lt;br /&gt;drwx------+ 38 user  group  - 1292 Dec 28 16:02 Library/&lt;br /&gt; 0: group:everyone deny delete&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1025339250899331264?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1025339250899331264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1025339250899331264' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1025339250899331264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1025339250899331264'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/12/os-x-hidden-folders-extended-attributes.html' title='OS X hidden folders, extended attributes, flags, and file ACLs'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-9063338112975597587</id><published>2011-12-20T15:22:00.000-08:00</published><updated>2011-12-20T15:23:42.864-08:00</updated><title type='text'>Simple cocoa dialogs for commandline tools in OS X</title><content type='html'>Got a commandline tool that needs to interact with a user?  &lt;a href="http://mstratman.github.com/cocoadialog/#"&gt;cocoaDialog&lt;/a&gt; is an app that can provide simple, good looking dialogs and can be invoked just by &lt;a href="http://mstratman.github.com/cocoadialog/#documentation"&gt;passing commandline options&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-9063338112975597587?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/9063338112975597587/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=9063338112975597587' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/9063338112975597587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/9063338112975597587'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/12/simple-cocoa-dialogs-for-commandline.html' title='Simple cocoa dialogs for commandline tools in OS X'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1696649548697995917</id><published>2011-12-18T20:35:00.000-08:00</published><updated>2011-12-18T20:35:30.133-08:00</updated><title type='text'>NSA response to USB-borne malware</title><content type='html'>The Washington Post has an &lt;a href="http://www.washingtonpost.com/national/national-security/cyber-intruder-sparks-response-debate/2011/12/06/gIQAxLuFgO_print.html"&gt;interesting article&lt;/a&gt; on the NSA's response to a USB-based malware infection on the US secret network in October 2008.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1696649548697995917?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1696649548697995917/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1696649548697995917' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1696649548697995917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1696649548697995917'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/12/nsa-response-to-usb-borne-malware.html' title='NSA response to USB-borne malware'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-4075833859986171613</id><published>2011-12-14T15:40:00.000-08:00</published><updated>2011-12-14T16:36:49.142-08:00</updated><title type='text'>Ruby %x, system(), `backtick`, and puppet Facter::Util::Resolution.exec differences</title><content type='html'>Below are three different ways of &lt;a href="http://blog.jayfields.com/2006/06/ruby-kernel-system-exec-and-x.html"&gt;running a system command from ruby&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;irb(main):014:0&gt; %x('echo "sdfsd"')&lt;br /&gt;sh: echo "sdfsd": command not found&lt;br /&gt;=&gt; ""&lt;br /&gt;irb(main):015:0&gt; system('echo "sdfsd"')&lt;br /&gt;sdfsd&lt;br /&gt;=&gt; true&lt;br /&gt;irb(main):016:0&gt; `echo "sdfsd"`&lt;br /&gt;=&gt; "sdfsd\n"&lt;br /&gt;&lt;/pre&gt;%x doesn't give you a shell environment, so builtin commands like echo don't exist.  system() gives you a shell, but doesn't save the output.  Backticks give you a shell environment and return the stdout output.&lt;br /&gt;&lt;br /&gt;In puppet if you're using Resolution.exec:&lt;br /&gt;&lt;pre&gt;Facter::Util::Resolution.exec('echo "sdfsd"')&lt;br /&gt;&lt;/pre&gt;Things are not so obvious.  Depending on the puppet version, you might &lt;a href="https://github.com/puppetlabs/facter/blob/d56bca8534bd21c046fd19a7fb2f776fe3e100b4/lib/facter/util/resolution.rb"&gt;get a shell environment&lt;/a&gt; and puppet is also doing some checking with &lt;a href="https://github.com/puppetlabs/facter/blob/master/lib/facter/util/resolution.rb"&gt;'which' that might result in a 'nil'&lt;/a&gt; return if your command is not a simple binary.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-4075833859986171613?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/4075833859986171613/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=4075833859986171613' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4075833859986171613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4075833859986171613'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/12/ruby-x-system-backtick-and-puppet.html' title='Ruby %x, system(), `backtick`, and puppet Facter::Util::Resolution.exec differences'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-9013524092008143256</id><published>2011-12-09T16:31:00.000-08:00</published><updated>2011-12-09T16:31:05.786-08:00</updated><title type='text'>Convert group and user GeneratedUIDs to human-readable form on OS X</title><content type='html'>When working with users and groups on OS X you frequently find that you need to lookup GUIDs to get their human-readable names.  Here are a few examples of the fairly painful syntax (good candidates for bash aliases).&lt;br /&gt;&lt;br /&gt;Get a group/user for a known GeneratedUID from local directory services:&lt;br /&gt;&lt;pre&gt;dscl . -search /Users GeneratedUID 00052AE8-5000-6000-9007-666F6B666A66&lt;br /&gt;dscl . -search /Groups GeneratedUID 00052AE8-5000-6000-9007-666F6B666A66&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and from LDAP:&lt;br /&gt;&lt;pre&gt;dscl /LDAPv3/ldap.company.com/ -search /Groups GeneratedUID 00052AE8-5000-6000-9007-666F6B666A66&lt;br /&gt;dscl /LDAPv3/ldap.company.com/ -search /Users GeneratedUID 00052AE8-5000-6000-9007-666F6B666A66&lt;br /&gt;ldapsearch -LLLx -b ou=group,dc=company,dc=com "apple-generateduid=00052AE8-5000-6000-9007-666F6B666A66" cn&lt;br /&gt;ldapsearch -LLLx -b ou=people,dc=company,dc=com "apple-generateduid=00052AE8-5000-6000-9007-666F6B666A66" uid&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Get a GeneratedUID for a known user/group:&lt;br /&gt;&lt;pre&gt;dscl localhost -read /Search/Users/auser | grep -m1 GeneratedUID | cut -c15-&lt;br /&gt;dscl localhost -read /Search/Groups/agroup | grep -m1 GeneratedUID | cut -c15-&lt;br /&gt;ldapsearch -LLLx -b ou=group,dc=company,dc=com "cn=agroup" apple-generateduid&lt;br /&gt;ldapsearch -LLLx -b ou=people,dc=company,dc=com "uid=auser" apple-generateduid&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-9013524092008143256?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/9013524092008143256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=9013524092008143256' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/9013524092008143256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/9013524092008143256'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/12/convert-group-and-user-generateduids-to.html' title='Convert group and user GeneratedUIDs to human-readable form on OS X'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-7047134068588320188</id><published>2011-12-09T12:52:00.000-08:00</published><updated>2011-12-09T14:11:25.090-08:00</updated><title type='text'>Ruby Time and DateTime: parse a string, compute the difference, simple right?</title><content type='html'>Time in ruby is a confusing maze of suckiness.&lt;br /&gt;&lt;br /&gt;The Ruby &lt;a href="http://www.ruby-doc.org/core-1.9.3/Time.html"&gt;Time class&lt;/a&gt; doesn't include a method to convert a string into a Time object (like the C standard 'strptime'), despite having a Time.strftime function.  What the?&lt;br /&gt;&lt;br /&gt;It turns out that Time.parse and Time.strptime &lt;b&gt;do&lt;/b&gt; exist, but confusingly they aren't in the core class, but in a &lt;a href="http://ruby-doc.org/stdlib-1.9.3/libdoc/time/rdoc/index.html"&gt;separate library&lt;/a&gt; you have to require that overrides the class.  WTF?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;irb(main):001:0&gt; Time.parse&lt;br /&gt;NoMethodError: undefined method `parse' for Time:Class&lt;br /&gt; from (irb):1&lt;br /&gt;irb(main):002:0&gt; require 'time'&lt;br /&gt;=&gt; true&lt;br /&gt;irb(main):003:0&gt; Time.parse&lt;br /&gt;ArgumentError: wrong number of arguments (0 for 1)&lt;br /&gt; from (irb):3:in `parse'&lt;br /&gt; from (irb):3&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So it seems that the best way to read a time from a file and compare it to the current time is the following, which gives you an answer in seconds:&lt;br /&gt;&lt;pre&gt;irb(main):010:0&gt; a=Time.parse('2011-01-10 12:34:00 UTC')&lt;br /&gt;=&gt; Mon Jan 10 12:34:00 UTC 2011&lt;br /&gt;irb(main):012:0&gt; b=Time.now.utc&lt;br /&gt;=&gt; Fri Dec 09 20:47:32 UTC 2011&lt;br /&gt;irb(main):013:0&gt; b-a&lt;br /&gt;=&gt; 28800812.788154&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The only downside of this is that the library never fails, it tries really hard to give you a Time object back, to the point where it will just return the current time if the string is rubbish:&lt;br /&gt;&lt;pre&gt;irb(main):027:0&gt; Time.parse('asdfasdfas')&lt;br /&gt;=&gt; Fri Dec 09 14:02:40 -0800 2011&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;whereas DateTime is actually more sensible:&lt;br /&gt;&lt;pre&gt;irb(main):028:0&gt; DateTime.parse('asdfasdfas')&lt;br /&gt;ArgumentError: invalid date&lt;br /&gt; from /usr/lib/ruby/1.8/date.rb:1576:in `new_by_frags'&lt;br /&gt; from /usr/lib/ruby/1.8/date.rb:1621:in `parse'&lt;br /&gt; from (irb):28&lt;br /&gt; from  :0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So my final solution was:&lt;br /&gt;&lt;pre&gt;  begin&lt;br /&gt;    DateTime.parse(time_string)&lt;br /&gt;  rescue ArgumentError&lt;br /&gt;    return 'UNKNOWN'&lt;br /&gt;  end&lt;br /&gt;  earlier = Time.parse(time_string)&lt;br /&gt;&lt;br /&gt;  now = Time.now.utc&lt;br /&gt;  hours = (now-earlier)/3600&lt;br /&gt;  return hours&lt;br /&gt;&lt;/pre&gt;Read on for an attempt to do the same with DateTime, which is a terrible, terrible API.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ruby-doc.org/stdlib-1.9.3/libdoc/date/rdoc/DateTime.html"&gt;DateTime&lt;/a&gt; has a simple way to ingest strings (and also has a strptime):&lt;br /&gt;&lt;pre&gt;irb(main):015:0&gt; require 'date'&lt;br /&gt;=&gt; false&lt;br /&gt;irb(main):023:0&gt; a=DateTime.parse('2011-12-09 00:00:00 UTC')&lt;br /&gt;=&gt; #&lt;DateTime: 4911809/2,0,2299161&gt;&lt;br /&gt;irb(main):024:0&gt; puts a&lt;br /&gt;2011-12-09T00:00:00+00:00&lt;br /&gt;=&gt; nil&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But you can't take a difference between Time and DateTime:&lt;br /&gt;&lt;pre&gt;irb(main):027:0&gt; a=DateTime.parse('2011-12-01 00:00:00 UTC')&lt;br /&gt;=&gt; #&lt;DateTime: 4911793/2,0,2299161&gt;&lt;br /&gt;irb(main):028:0&gt; b=Time.now&lt;br /&gt;=&gt; Fri Dec 09 12:10:40 -0800 2011&lt;br /&gt;irb(main):029:0&gt; b-a&lt;br /&gt;TypeError: can't convert DateTime into Float&lt;br /&gt; from (irb):29:in `-'&lt;br /&gt; from (irb):29&lt;br /&gt; from  :0&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Subtracting two DateTimes works but gives you an answer that is a rational number of days (?!):&lt;br /&gt;&lt;pre&gt;irb(main):031:0&gt; b-a&lt;br /&gt;=&gt; Rational(76394798789, 8640000000)&lt;br /&gt;irb(main):032:0&gt; c=b-a&lt;br /&gt;=&gt; Rational(76394798789, 8640000000)&lt;br /&gt;irb(main):033:0&gt; puts c&lt;br /&gt;76394798789/8640000000&lt;br /&gt;=&gt; nil&lt;br /&gt;irb(main):034:0&gt; puts c.to_f&lt;br /&gt;8.8419906005787&lt;br /&gt;=&gt; nil&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Since a fractional number of days is pretty useless you can then convert this to an array of [hours,minutes,seconds,frac]:&lt;br /&gt;&lt;pre&gt;irb(main):036:0&gt; DateTime.day_fraction_to_time(c)&lt;br /&gt;=&gt; [212, 12, 27, Rational(98789, 8640000000)]&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Why the subtraction doesn't return another type of time object is beyond me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-7047134068588320188?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/7047134068588320188/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=7047134068588320188' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7047134068588320188'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7047134068588320188'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/12/ruby-time-and-datetime-parse-string.html' title='Ruby Time and DateTime: parse a string, compute the difference, simple right?'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-6827503119491289424</id><published>2011-12-07T08:51:00.000-08:00</published><updated>2011-12-07T08:52:23.728-08:00</updated><title type='text'>auditd on OS X</title><content type='html'>Auditd gets a limited description in the &lt;a href="http://images.apple.com/support/security/guides/docs/SnowLeopard_Security_Config_v10.6.pdf"&gt;Snow Leopard Security Config doc&lt;/a&gt;.  I'm posting a quick summary here, and will update it as I learn more.&lt;br /&gt;&lt;br /&gt;auditd rules are kept in&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/etc/security&lt;/span&gt;. &amp;nbsp;The &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;audit_control&lt;/span&gt; rules apply to all users and &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;audit_user&lt;/span&gt; allows for per-user rules.&lt;br /&gt;&lt;br /&gt;Audit logs are stored in binary format in &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/var/audit/logstarttime.logfinishtime&lt;/span&gt; and can be read with:&lt;br /&gt;&lt;pre&gt;praudit /var/audit/20111018000205.20111018000916&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-6827503119491289424?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/6827503119491289424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=6827503119491289424' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6827503119491289424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6827503119491289424'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/12/auditd-on-os-x.html' title='auditd on OS X'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-7982718668860440811</id><published>2011-11-17T16:15:00.001-08:00</published><updated>2011-11-18T08:34:51.688-08:00</updated><title type='text'>Create an array of identical strings in python</title><content type='html'>To create an array of identical strings in python (sometimes useful for testing):&lt;br /&gt;&lt;pre&gt;In [12]: list("sdfsd" for x in range(1,4))&lt;br /&gt;Out[12]: ['sdfsd', 'sdfsd', 'sdfsd']&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;Update:&lt;/b&gt; a commenter points out a better way.  I knew you could do &lt;pre&gt;'a'*5&lt;/pre&gt;but didn't think to try this.  Thanks!&lt;br /&gt;&lt;br /&gt;A shorter version:&lt;br /&gt;&lt;pre&gt;In [16]: ["sdfsd"]*5&lt;br /&gt;Out[16]: ['sdfsd', 'sdfsd', 'sdfsd', 'sdfsd', 'sdfsd']&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And it's faster too....&lt;br /&gt;&lt;pre&gt;$ python -mtimeit -n10000 "list('sdfsd' for i in xrange(1000))"&lt;br /&gt;10000 loops, best of 3: 69.7 usec per loop&lt;br /&gt;$ python -mtimeit -n10000 "['sdfsd']*1000"&lt;br /&gt;10000 loops, best of 3: 5.66 usec per loop&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-7982718668860440811?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/7982718668860440811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=7982718668860440811' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7982718668860440811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7982718668860440811'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/11/create-array-of-identical-strings-in.html' title='Create an array of identical strings in python'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-7984584041890857707</id><published>2011-11-16T10:41:00.000-08:00</published><updated>2011-11-16T10:41:23.105-08:00</updated><title type='text'>OS X groups, subgroups and GeneratedUIDs</title><content type='html'>OS X groups are more confusing than they need to be, due to the use of UUIDs.  First, lets create a group to test with and include a single user (test1):&lt;br /&gt;&lt;pre&gt;$ sudo dseditgroup -o create -t group test00&lt;br /&gt;$ sudo dseditgroup -o edit -a test1 -t user test00&lt;br /&gt;$ dseditgroup -o read test00&lt;br /&gt;dsAttrTypeStandard:GeneratedUID -&lt;br /&gt;  C110609F-0C0A-42E7-B663-D93BA03ECDAC&lt;br /&gt;dsAttrTypeStandard:RecordName -&lt;br /&gt;  test00&lt;br /&gt;dsAttrTypeStandard:AppleMetaNodeLocation -&lt;br /&gt;  /Local/Default&lt;br /&gt;dsAttrTypeStandard:GroupMembers -&lt;br /&gt;  6D456134-85E6-4912-88C7-7C6139057B9B&lt;br /&gt;dsAttrTypeStandard:RecordType -&lt;br /&gt;  dsRecTypeStandard:Groups&lt;br /&gt;dsAttrTypeStandard:NestedGroups -&lt;br /&gt;dsAttrTypeStandard:PrimaryGroupID -&lt;br /&gt;  505&lt;br /&gt;dsAttrTypeStandard:GroupMembership -&lt;br /&gt;  test1&lt;br /&gt;&lt;/pre&gt;Note that we have GroupMembership that includes test1 and the GroupMembers attribute lists the GUID for the test1 user.  Neither of these attributes tell us about groups that are members of this group.  To see how they are stored, we will add a subgroup:&lt;br /&gt;&lt;pre&gt;$ sudo dseditgroup -o edit -a testsubgroup -t group test00&lt;br /&gt;$ dseditgroup -o read test00&lt;br /&gt;dsAttrTypeStandard:GeneratedUID -&lt;br /&gt;  C110609F-0C0A-42E7-B663-D93BA03ECDAC&lt;br /&gt;dsAttrTypeStandard:RecordName -&lt;br /&gt;  test00&lt;br /&gt;dsAttrTypeStandard:AppleMetaNodeLocation -&lt;br /&gt;  /Local/Default&lt;br /&gt;dsAttrTypeStandard:GroupMembers -&lt;br /&gt;  6D456134-85E6-4912-88C7-7C6139057B9B&lt;br /&gt;dsAttrTypeStandard:RecordType -&lt;br /&gt;  dsRecTypeStandard:Groups&lt;br /&gt;dsAttrTypeStandard:NestedGroups -&lt;br /&gt;  6B3D7A4A-A795-4569-8640-2105F73EEA6B&lt;br /&gt;dsAttrTypeStandard:PrimaryGroupID -&lt;br /&gt;  505&lt;br /&gt;dsAttrTypeStandard:GroupMembership -&lt;br /&gt;  test1&lt;br /&gt;&lt;/pre&gt;Note that the subgroup UUID is now listed under NestedGroups, but the human-readable name is not, presumably because apple wanted to make this as painful as possible.  There isn't a nice way to map UUID to a recordname, but searching in the local node does work (although it seems to ignore the output formatting options):&lt;br /&gt;&lt;pre&gt;$ dscl -plist . -search /Groups GeneratedUID 6B3D7A4A-A795-4569-8640-2105F73EEA6B&lt;br /&gt;testsubgroup  GeneratedUID = (&lt;br /&gt;    "6B3D7A4A-A795-4569-8640-2105F73EEA6B"&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;So the outcome of this is that to code to answer a simple question: 'who are the members of this group?' is actually really complicated.&lt;br /&gt;&lt;br /&gt;There is however a way to check if a user is a member of a group, and it will follow nested group relationships:&lt;br /&gt;&lt;pre&gt;$ sudo dseditgroup -o edit -a test2 -t user testsubgroup&lt;br /&gt;$ dseditgroup -o checkmember -m test2 test00&lt;br /&gt;yes test2 is a member of test00&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-7984584041890857707?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/7984584041890857707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=7984584041890857707' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7984584041890857707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7984584041890857707'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/11/os-x-groups-subgroups-and-generateduids.html' title='OS X groups, subgroups and GeneratedUIDs'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-2451354741266582236</id><published>2011-11-15T16:11:00.000-08:00</published><updated>2011-11-15T16:11:51.837-08:00</updated><title type='text'>Using netgroups to control login and admin privileges on OS X</title><content type='html'>I wanted to use netgroups defined in /etc/netgroup to control:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Login access via &lt;a href="http://ilostmynotes.blogspot.com/2011/11/os-x-service-acls-comappleaccess.html"&gt;access_loginwindow&lt;/a&gt;&lt;/li&gt;&lt;li&gt;OS X admin privs via the admin local group&lt;/li&gt;&lt;li&gt;sudo access via /etc/sudoers&lt;/li&gt;&lt;/ul&gt;Unfortunately I couldn't get it to work (on 10.6), but I'll document here for my own sake and the rest of the internet :)  I suspect this was because I wanted to just use the flat file, without any NIS server, and OS X was expecting to do lookups to refresh the information in the file.&lt;br /&gt;&lt;br /&gt;Run Directory Utility&lt;br /&gt;&lt;pre&gt;open /System/Library/CoreServices/Directory\ Utility.app/&lt;br /&gt;&lt;/pre&gt;and tick 'BSD Flat File and NIS' and inside there tick 'Use User and Group records in BSD Local node'.  Interestingly this is gone on Lion - it is now just NIS and there is no option for BSD local node...&lt;br /&gt;&lt;br /&gt;Assuming you have some entries in /etc/netgroup:&lt;br /&gt;&lt;pre&gt;smalltest (-,auser,)&lt;br /&gt;&lt;/pre&gt;You should be able to see them with dscl:&lt;br /&gt;&lt;pre&gt;$ dscl localhost -read /BSD/local/NetGroups/smalltest&lt;br /&gt;dsAttrTypeNative:triplet: -,auser,&lt;br /&gt;AppleMetaNodeLocation: /BSD/local&lt;br /&gt;RecordName: smalltest&lt;br /&gt;&lt;/pre&gt;And should theoretically be able to use them.  I tried this for sudo, and although it passed syntax checking it just didn't work.&lt;br /&gt;&lt;pre&gt;+smalltest ALL=(ALL) ALL&lt;br /&gt;&lt;/pre&gt;And I couldn't get dseditgroup to recognise the netgroup for use in access_loginwindow:&lt;br /&gt;&lt;pre&gt;$ sudo dseditgroup -o edit -a smalltest -t group com.apple.access_loginwindow&lt;br /&gt;Group not found.&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-2451354741266582236?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/2451354741266582236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=2451354741266582236' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2451354741266582236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2451354741266582236'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/11/using-netgroups-to-control-login-and.html' title='Using netgroups to control login and admin privileges on OS X'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1902074280845076417</id><published>2011-11-15T15:47:00.000-08:00</published><updated>2011-11-15T15:47:28.350-08:00</updated><title type='text'>OS X Service ACLs com.apple.access_*</title><content type='html'>To place ACLs on OS X services, you can create groups like this:&lt;br /&gt;&lt;pre&gt;sudo dseditgroup -o create -t group com.apple.access_loginwindow&lt;br /&gt;sudo dseditgroup -o edit -a auser -t user com.apple.access_loginwindow&lt;br /&gt;&lt;/pre&gt;which in this case will limit who can login at the console (i.e. loginwindow) to just the user 'auser'.  You can check the membership with:&lt;br /&gt;&lt;pre&gt;$ dscl . -read /Groups/com.apple.access_loginwindow&lt;br /&gt;AppleMetaNodeLocation: /Local/Default&lt;br /&gt;GroupMembership: auser&lt;br /&gt;PrimaryGroupID: 504&lt;br /&gt;RecordName: com.apple.access_loginwindow&lt;br /&gt;RecordType: dsRecTypeStandard:Groups&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Similar groups will control access to other services such as com.apple.access_ssh, com.apple.access_screensharing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1902074280845076417?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1902074280845076417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1902074280845076417' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1902074280845076417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1902074280845076417'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/11/os-x-service-acls-comappleaccess.html' title='OS X Service ACLs com.apple.access_*'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-4602296833553632600</id><published>2011-11-14T15:40:00.000-08:00</published><updated>2011-11-14T15:40:58.877-08:00</updated><title type='text'>Compiling C libraries for use in python modules on OS X: specify a target architecture</title><content type='html'>My pycurl installation was failing with these errors:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$pip install pycurl&lt;br /&gt;&lt;br /&gt;[snip]&lt;br /&gt;&lt;br /&gt;assembler (/usr/bin/../libexec/gcc/darwin/ppc/as or /usr/bin/../local/libexec/gcc/darwin/ppc/as) for architecture ppc not installed&lt;br /&gt;&lt;br /&gt;Installed assemblers are:&lt;br /&gt;&lt;br /&gt;/usr/bin/../libexec/gcc/darwin/x86_64/as for architecture x86_64&lt;br /&gt;&lt;br /&gt;/usr/bin/../libexec/gcc/darwin/i386/as for architecture i386&lt;br /&gt;&lt;/pre&gt;The solution was to specify an architecture like this:&lt;br /&gt;&lt;pre&gt;env ARCHFLAGS="-arch x86_64" pip install pycurl&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-4602296833553632600?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/4602296833553632600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=4602296833553632600' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4602296833553632600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4602296833553632600'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/11/compiling-c-libraries-for-use-in-python.html' title='Compiling C libraries for use in python modules on OS X: specify a target architecture'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-2864536481754204574</id><published>2011-11-10T14:30:00.000-08:00</published><updated>2011-11-11T16:10:45.186-08:00</updated><title type='text'>OS X logging: asl.conf, syslog.conf, syslog master filters and log rotation</title><content type='html'>The apple syslog daemon (/System/Library/LaunchDaemons/com.apple.syslogd.plist) takes configuration from &lt;i&gt;3 different sources&lt;/i&gt; *groan*.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;asl.conf&lt;/h4&gt;&lt;br /&gt;asl.conf (the apple syslog configuration file) controls what data is stored in the apple syslog binary databases under /private/var/log/asl.  It is powerful and allows everything from filtering:&lt;br /&gt;&lt;pre&gt;# save everything from emergency to notice&lt;br /&gt;? [&amp;lt;= Level notice] store&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;to access control.  This restricts read access to uid 0 (root) and gid 80 (admin): &lt;br /&gt;&lt;pre&gt;# authpriv messages are root/admin readable&lt;br /&gt;? [= Facility authpriv] access 0 80&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;syslog.conf&lt;/h4&gt;&lt;br /&gt;In addition, and independent of, asl.conf, syslogd also reads syslog.conf which is the familiar unix/linux/bsd style syslog configuration file.  This allows you to write the same log lines to plaintext log files in /var/log (or wherever) that also get stored by asl in binary form as above.  &lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Syslog master filters&lt;/h4&gt;&lt;br /&gt;As if that wasn't enough, the syslog daemon itself also has a global master filter rule, which you can inspect with: &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;$ syslog -c 0&lt;br /&gt;Master filter mask: Debug&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;AND you can set per-process filters: &lt;br /&gt;&lt;pre&gt;$ syslog -c syslogd&lt;br /&gt;ASL Data Store filter mask: Emergency - Debug&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;Reading logs&lt;/h4&gt;&lt;br /&gt;To read asl logs, just use the syslog command.  It actually comes with some nifty filtering of its own.  For example this command shows log lines sent by login for the past 2 hours:  &lt;br /&gt;&lt;pre&gt;syslog -k Sender login -k Time ge -2h&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To help you formulate queries like the above you can see the raw key value pairs using: &lt;br /&gt;&lt;pre&gt;syslog -F raw&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There is a gotcha in the &lt;a href="http://www.opensource.apple.com/source/files/files-589.3/private/etc/asl.conf?txt"&gt;default apple configuration&lt;/a&gt; which has lines like:&lt;br /&gt;&lt;pre&gt;# redirect com.apple.message.domain to /var/log/DiagnosticMessages&lt;br /&gt;? [T com.apple.message.domain] store_dir /var/log/DiagnosticMessages&lt;br /&gt;&lt;br /&gt;# redirect com.apple.performance* messages to /var/log/performance&lt;br /&gt;? [A= Facility com.apple.performance] store_dir /var/log/performance&lt;br /&gt;&lt;br /&gt;# redirect com.apple.eventmonitor* messages to /var/log/eventmonitor&lt;br /&gt;? [A= Facility com.apple.eventmonitor] store_dir /var/log/eventmonitor&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Which means just using the syslog command as above doesn't give you all the logs, including stuff like apple updates:&lt;br /&gt;&lt;pre&gt;$ syslog  | grep 'downloading "Thunderbolt Software Update, 1.0"'&lt;br /&gt;&lt;/pre&gt;To look at the DiagnosticMessages log use:&lt;br /&gt;&lt;pre&gt;$ syslog -d /var/log/DiagnosticMessages/ | grep 'downloading "Thunderbolt Software Update, 1.0"'&lt;br /&gt;Software Update[1865] &lt;notice&gt;: SWU: downloading "Thunderbolt Software Update, 1.0"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To read the BSD logs just go look at the files in /var/log.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Log Rotation&lt;/h4&gt;&lt;br /&gt;Log rotation configuration is in &lt;pre&gt;/etc/newsyslog.conf&lt;/pre&gt;and has configuration lines that look like &lt;a href="http://www.opensource.apple.com/source/crontabs/crontabs-45/private/etc/newsyslog.conf"&gt;this&lt;/a&gt; (ie. completely different to linux /etc/logrotate.d):&lt;br /&gt;&lt;pre&gt;# logfilename          [owner:group]    mode count size when  flags [/pid_file] [sig_num]&lt;br /&gt;/var/log/appfirewall.log  640  5     1000 *     J&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;See the newsyslog.conf man page for the details.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-2864536481754204574?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/2864536481754204574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=2864536481754204574' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2864536481754204574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2864536481754204574'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/11/os-x-logging-aslconf-syslogconf-and.html' title='OS X logging: asl.conf, syslog.conf, syslog master filters and log rotation'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-734203437727195199</id><published>2011-11-08T19:11:00.000-08:00</published><updated>2011-11-08T19:11:10.868-08:00</updated><title type='text'>OS X Terminal screwed up command history in iPython</title><content type='html'>I was getting some weird behaviour in ipython (0.11) in a OS X (10.6.8) Terminal window.  When I used the up arrow to access the commandline history, all long lines (and even some short lines) were screwed up - the text wrapping was wrong.  Others &lt;a href="https://bugs.launchpad.net/ipython/+bug/304263"&gt;have noticed the same thing&lt;/a&gt; and it turns out the solution is to re-install readline (which requires Xcode to compile it):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;sudo pip install readline&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-734203437727195199?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/734203437727195199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=734203437727195199' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/734203437727195199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/734203437727195199'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/11/os-x-terminal-screwed-up-command.html' title='OS X Terminal screwed up command history in iPython'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-2654750296886466511</id><published>2011-11-07T14:27:00.000-08:00</published><updated>2011-11-07T14:27:09.796-08:00</updated><title type='text'>Equivalent of 'watch' command for OS X</title><content type='html'>'watch' doesn't exist inbuilt for OS X like it does for linux.  Someone has &lt;a href="http://sveinbjorn.org/watch_macosx"&gt;actually implemented it and it is available from fink&lt;/a&gt;, but here is a bash function that uses a simple while loop to do basically the same thing.  Drop this into bash_aliases and you now have a simple version of watch.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;watch () {&lt;br /&gt;  while [ 1 ]; do "${@}" ; sleep 2 ; done&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-2654750296886466511?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/2654750296886466511/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=2654750296886466511' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2654750296886466511'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2654750296886466511'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/11/equivalent-of-watch-command-for-os-x.html' title='Equivalent of &apos;watch&apos; command for OS X'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-6250604781294040029</id><published>2011-11-07T14:17:00.000-08:00</published><updated>2011-11-07T14:17:33.395-08:00</updated><title type='text'>HOWTO write an OS X (seatbelt) sandbox profile</title><content type='html'>To create a simple seatbelt sandbox profile, start with a trace by saving this as trace.sb:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;(version 1)&lt;br /&gt;(trace "/tmp/traceout.sb")&lt;br /&gt;&lt;/pre&gt;Then&lt;br /&gt;&lt;pre&gt;sandbox-exec -f trace.sb binary_to_be_sandboxed&lt;br /&gt;sandbox-simplify /tmp/traceout.sb &gt; ./tracesimple.sb&lt;br /&gt;&lt;/pre&gt;Simplify crunches down the verbose log into a more compact profile.  Edit it (you especially want to remove any spurious dtrace lines that are artifacts of the capture process) and run the binary in its sandbox:&lt;br /&gt;&lt;pre&gt;sandbox-exec -f tracesimple.sb binary_to_be_sandboxed&lt;br /&gt;&lt;/pre&gt;&lt;a href="http://www.red-sweater.com/blog/2170/sandbox-corners"&gt;This blog&lt;/a&gt; has a simple shell script to automate the above process, but you probably want to manually inspect and edit your profile before using it for real.&lt;br /&gt;&lt;br /&gt;You can see a bunch of built-in sandboxes in &lt;pre&gt;/usr/share/sandbox&lt;/pre&gt;and you can view which running processes are sandboxed by adding the sandbox column to the activity monitor gui.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-6250604781294040029?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/6250604781294040029/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=6250604781294040029' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6250604781294040029'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6250604781294040029'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/11/howto-write-os-x-seatbelt-sandbox.html' title='HOWTO write an OS X (seatbelt) sandbox profile'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1163568191402829786</id><published>2011-11-07T13:24:00.000-08:00</published><updated>2011-11-07T13:29:51.471-08:00</updated><title type='text'>OS X kernel panic: "You need to restart your computer"</title><content type='html'>This is the OS X kernel panic screen:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-wk4J2ioz3Og/TrhMIkYsvRI/AAAAAAAAALY/YvcRC4Rg7sc/s1600/kernelpanic.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="216" src="http://1.bp.blogspot.com/-wk4J2ioz3Og/TrhMIkYsvRI/AAAAAAAAALY/YvcRC4Rg7sc/s400/kernelpanic.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Apple has some information on how you can configure OS X to &lt;a href="http://developer.apple.com/library/mac/#technotes/tn2004/tn2118.html"&gt;send kernel core dumps over TCP&lt;/a&gt; and some information on how to &lt;a href="http://developer.apple.com/library/mac/#technotes/tn2063/_index.html"&gt;debug panics&lt;/a&gt;. You can also find a panic log at &lt;pre&gt;/Library/Logs/DiagnosticReports/Kernel_time_host.panic&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1163568191402829786?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1163568191402829786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1163568191402829786' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1163568191402829786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1163568191402829786'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/11/os-x-kernel-panic-you-need-to-restart.html' title='OS X kernel panic: &quot;You need to restart your computer&quot;'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-wk4J2ioz3Og/TrhMIkYsvRI/AAAAAAAAALY/YvcRC4Rg7sc/s72-c/kernelpanic.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-7035792323958664472</id><published>2011-10-28T13:18:00.000-07:00</published><updated>2011-10-28T13:18:25.322-07:00</updated><title type='text'>NFS shares</title><content type='html'>Show NFS shares exported from a host (can also point to localhost):&lt;br /&gt;&lt;pre&gt;showmount -e 192.168.1.1&lt;br /&gt;&lt;/pre&gt;/etc/exports line on linux (share /blah with 192.168.1.2)&lt;br /&gt;&lt;pre&gt;/blah               192.168.1.2(ro)&lt;br /&gt;&lt;/pre&gt;On the mac the options format is different.  As with linux, root_squash to nobody is the default.&lt;br /&gt;&lt;pre&gt;/blah -ro 192.168.1.2&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-7035792323958664472?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/7035792323958664472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=7035792323958664472' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7035792323958664472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7035792323958664472'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/10/nfs-shares.html' title='NFS shares'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-8795040525784864639</id><published>2011-10-25T12:56:00.000-07:00</published><updated>2011-10-25T12:56:29.218-07:00</updated><title type='text'>Installing pip and virtualenv on OS X</title><content type='html'>&lt;a href="http://pypi.python.org/pypi/setuptools#files"&gt;Download&lt;/a&gt; and install the appropriate easy_install egg.&lt;br /&gt;&lt;pre&gt;sudo sh setuptools-0.6c11-py2.X.egg&lt;br /&gt;&lt;/pre&gt;and from then on it is the same as &lt;a href="http://ilostmynotes.blogspot.com/2011/01/python-way-of-future-pip-and-virtualenv.html"&gt;for linux&lt;/a&gt;&lt;br /&gt;&lt;pre&gt;sudo easy_install pip&lt;br /&gt;sudo pip install virtualenv&lt;br /&gt;&lt;/pre&gt;Create a virtualenv instance:&lt;br /&gt;&lt;pre&gt;virtualenv ENV&lt;br /&gt;&lt;/pre&gt;and you'll get something like:&lt;br /&gt;&lt;pre&gt;Could not call install_name_tool -- you must have Apple's development tools installed&lt;br /&gt;&lt;/pre&gt;So you need to go off and &lt;a href="http://developer.apple.com/xcode/"&gt;install XCode&lt;/a&gt;, which will probably take a while (4.2 is 1.7 G).&lt;br /&gt;&lt;br /&gt;Once you have Xcode, things should be good:&lt;br /&gt;&lt;pre&gt;$ virtualenv ENV&lt;br /&gt;New python executable in ENV/bin/python&lt;br /&gt;Installing setuptools............done.&lt;br /&gt;Installing pip...............done.&lt;br /&gt;$ source ENV/bin/activate&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-8795040525784864639?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/8795040525784864639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=8795040525784864639' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/8795040525784864639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/8795040525784864639'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/10/installing-pip-and-virtualenv-on-os-x.html' title='Installing pip and virtualenv on OS X'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-4418304049207883875</id><published>2011-10-20T15:20:00.000-07:00</published><updated>2011-10-20T15:20:49.420-07:00</updated><title type='text'>OSX launchd and inetd services</title><content type='html'>launchd is roughly equivalent to cron, init.d, and xinetd all rolled into one.&lt;br /&gt;&lt;br /&gt;Use it by dropping a plist into one of these directories:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;/Library/LaunchDaemons runs as root on system startup&lt;/li&gt;&lt;li&gt;/Library/LaunchAgents runs as the user on login&lt;/li&gt;&lt;li&gt;~/Library/LaunchAgents runs as the user for the specific user login&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;There is also /System/Library/Launch{Agents,Daemons} which is for the jobs installed by the OS.  Use the directories above for any custom jobs.&lt;br /&gt;&lt;br /&gt;List launchd jobs with&lt;br /&gt;&lt;pre&gt;launchctl list&lt;br /&gt;&lt;/pre&gt;Start:&lt;br /&gt;&lt;pre&gt;sudo launchctl load /Library/LaunchDaemons/com.myorg.somejob.plist&lt;br /&gt;&lt;/pre&gt;Stop:&lt;br /&gt;&lt;pre&gt;sudo launchctl unload /Library/LaunchDaemons/com.myorg.somejob.plist&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There are many different options for jobs, see the launchd.plist man page for a complete list.  A simple inetd service might look something like this:&lt;br /&gt;&lt;pre&gt;&amp;lt;dict&amp;gt;&lt;br /&gt; &amp;lt;key&amp;gt;Disabled&amp;lt;/key&amp;gt;&lt;br /&gt; &amp;lt;false/&amp;gt;&lt;br /&gt; &amp;lt;key&amp;gt;Label&amp;lt;/key&amp;gt;&lt;br /&gt; &amp;lt;string&amp;gt;com.myorg.somejob&amp;lt;/string&amp;gt;&lt;br /&gt; &amp;lt;key&amp;gt;Program&amp;lt;/key&amp;gt;&lt;br /&gt; &amp;lt;string&amp;gt;/usr/local/sbin/somejob&amp;lt;/string&amp;gt;&lt;br /&gt; &amp;lt;key&amp;gt;Sockets&amp;lt;/key&amp;gt;&lt;br /&gt; &amp;lt;dict&amp;gt;&lt;br /&gt;  &amp;lt;key&amp;gt;Listeners&amp;lt;/key&amp;gt;&lt;br /&gt;  &amp;lt;dict&amp;gt;&lt;br /&gt;   &amp;lt;key&amp;gt;SockServiceName&amp;lt;/key&amp;gt;&lt;br /&gt;   &amp;lt;string&amp;gt;9999&amp;lt;/string&amp;gt;&lt;br /&gt;  &amp;lt;/dict&amp;gt;&lt;br /&gt; &amp;lt;/dict&amp;gt;&lt;br /&gt; &amp;lt;key&amp;gt;inetdCompatibility&amp;lt;/key&amp;gt;&lt;br /&gt; &amp;lt;dict&amp;gt;&lt;br /&gt;  &amp;lt;key&amp;gt;Wait&amp;lt;/key&amp;gt;&lt;br /&gt;  &amp;lt;false/&amp;gt;&lt;br /&gt; &amp;lt;/dict&amp;gt;&lt;br /&gt;&amp;lt;/dict&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;/usr/local/sbin/somejob will be called whenever there is a connection on port 9999, and you can interact with the socket by reading and writing STDIN/STDOUT as normal for inetd.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-4418304049207883875?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/4418304049207883875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=4418304049207883875' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4418304049207883875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4418304049207883875'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/10/osx-launchd-and-inetd-services.html' title='OSX launchd and inetd services'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-3213309802651625000</id><published>2011-10-19T16:57:00.000-07:00</published><updated>2011-10-19T16:57:35.862-07:00</updated><title type='text'>Force MCX refresh - apply policy without a logout/reboot</title><content type='html'>If you are managing settings with MCX (e.g. like &lt;a href="http://ilostmynotes.blogspot.com/2011/09/reading-mcx-localcomputer-policies.html"&gt;this&lt;/a&gt;), you want your MCX settings to apply as soon as they are pushed to the machine.  Unfortunately this doesn't happen automatically.  They get stored in the local directory services node, which you can see here:&lt;br /&gt;&lt;pre&gt;dscl . -mcxread /Computers/local_computer&lt;br /&gt;&lt;/pre&gt;But they don't get propagated to the relevant plists under managed preferences until a logout or reboot happens.  You can check the managed preferences plists like this:&lt;br /&gt;&lt;pre&gt;defaults read /Library/Managed\ Preferences/com.apple.loginwindow&lt;br /&gt;&lt;/pre&gt;Fortunately on 10.6 and later, you can run mcxrefresh to force this propagation without a reboot:&lt;br /&gt;&lt;pre&gt;sudo mcxrefresh -n myusername&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-3213309802651625000?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/3213309802651625000/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=3213309802651625000' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3213309802651625000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3213309802651625000'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/10/force-mcx-refresh-apply-policy-without.html' title='Force MCX refresh - apply policy without a logout/reboot'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1357068502478249089</id><published>2011-10-19T16:50:00.000-07:00</published><updated>2011-10-19T16:50:15.874-07:00</updated><title type='text'>Puppet expansion of facts inside command strings requires double quoted string</title><content type='html'>Small gotcha for puppet facts.  If you want a puppet fact to be expanded inside a quoted string you need to use double quotes (i.e. a ruby-style format string).&lt;br /&gt;&lt;pre&gt;  exec { 'something':&lt;br /&gt;    # This has to be a double quote for the fact to get expanded&lt;br /&gt;    command     =&gt; "/usr/bin/something ${my_custom_fact}",&lt;br /&gt;    refreshonly =&gt; 'true',&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1357068502478249089?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1357068502478249089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1357068502478249089' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1357068502478249089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1357068502478249089'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/10/puppet-expansion-of-facts-inside.html' title='Puppet expansion of facts inside command strings requires double quoted string'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-7777145499848098478</id><published>2011-10-12T08:25:00.000-07:00</published><updated>2011-10-12T08:25:55.596-07:00</updated><title type='text'>Chrome Extensions vs. Apps vs. Themes and what it looks like in your extensions directory</title><content type='html'>If you look in your chrome extensions directory on disk, things are a little confusing.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;There are extensions, which you can see listed at &lt;a href="about:extensions"&gt;about:extensions&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;There are apps, which can be either &lt;a href="http://code.google.com/chrome/webstore/articles/apps_vs_extensions.html"&gt;packaged or hosted&lt;/a&gt; and will contain an app launch stanza like this in the manifest.json&lt;br /&gt;&lt;pre&gt;   "app": {&lt;br /&gt;      "launch": {&lt;br /&gt;         "web_url": "https://mail.google.com/mail/mu/?mui=ca"&lt;br /&gt;      },&lt;br /&gt;      "urls": [ "https://mail.google.com/mail/mu/" ]&lt;br /&gt;   },&lt;br /&gt;&lt;/pre&gt;These don't seem to appear anywhere in the UI apart from when you open a new tab (there is no about:apps, see &lt;a href="about:about"&gt;about:about&lt;/a&gt; for a full list of what is available).&lt;/li&gt;&lt;li&gt;Themes, which are &lt;a href="http://code.google.com/chrome/extensions/themes.html"&gt;packaged in a similar way, but don't contain javascript or HTML&lt;/a&gt;.  The manifest.json will have entries like this:&lt;br /&gt;&lt;pre&gt;   "theme": {&lt;br /&gt;      "colors": {&lt;br /&gt;         "bookmark_text": [ 105, 96, 87 ],&lt;br /&gt;         "frame": [ 92, 82, 73 ],&lt;br /&gt;         "ntp_background": [ 235, 234, 211 ],&lt;br /&gt;         "ntp_link": [ 105, 96, 87 ],&lt;br /&gt;         "ntp_section": [ 158, 163, 139, 1 ],&lt;br /&gt;         "ntp_section_link": [ 105, 96, 87 ],&lt;br /&gt;         "ntp_section_text": [ 105, 96, 87 ],&lt;br /&gt;         "ntp_text": [ 105, 96, 87 ],&lt;br /&gt;         "tab_background_text": [ 255, 255, 255 ],&lt;br /&gt;         "tab_text": [ 255, 255, 255 ],&lt;br /&gt;         "toolbar": [ 158, 163, 139 ]&lt;br /&gt;      },&lt;br /&gt;&lt;/pre&gt;&lt;/ol&gt;Also, just figuring out the name of extensions can be confusing.  In the manifest.json you will often see:&lt;pre&gt;"name": "__MSG_some_name__",&lt;br /&gt;&lt;/pre&gt;Which means you need to go look in the relevant locale file like _locales/en/messages.json to find the actual name, it will look like this (note MSG and underscores stripped):&lt;pre&gt;{&lt;br /&gt;   "some_name": {&lt;br /&gt;      "message": "My Rad Extension"&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The exception is if it is a theme, the messages.json file will look like:&lt;pre&gt;{"themeName": {"message": "Earthy", "description": "theme name"}}&lt;br /&gt;&lt;/pre&gt;Except it also has a &lt;a href="http://en.wikipedia.org/wiki/Byte_order_mark#UTF-8"&gt;UTF-8 Byte Order Mark&lt;/a&gt; prepended to the start of the file, which is the three bytes 'ef bb bf'.  If you're trying to parse it with an external JSON parser, those bytes might cause it to fail.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-7777145499848098478?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/7777145499848098478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=7777145499848098478' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7777145499848098478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7777145499848098478'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/10/chrome-extensions-vs-apps-vs-themes-and.html' title='Chrome Extensions vs. Apps vs. Themes and what it looks like in your extensions directory'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-8106605542170072282</id><published>2011-10-07T12:36:00.000-07:00</published><updated>2011-10-07T12:36:52.639-07:00</updated><title type='text'>Using OS X directory services (dscl, dseditgroup) in single user mode</title><content type='html'>To access directory services you first need a writable root:&lt;br /&gt;&lt;pre&gt;mount -uw /&lt;br /&gt;&lt;/pre&gt;Then you need the daemon loaded.  On snow leopard:&lt;br /&gt;&lt;pre&gt;launchctl load /System/Library/LaunchDaemons/com.apple.DirectoryServices.plist&lt;br /&gt;&lt;/pre&gt;And &lt;a href="http://support.apple.com/kb/HT4749"&gt;on Lion&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;launchctl load /System/Library/LaunchDaemons/com.apple.opendirectoryd.plist&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;On lion you might see an error about DirectoryServices.plist not existing when you connect with dscl, it can be ignored.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-8106605542170072282?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/8106605542170072282/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=8106605542170072282' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/8106605542170072282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/8106605542170072282'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/10/using-os-x-directory-services-dscl.html' title='Using OS X directory services (dscl, dseditgroup) in single user mode'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1239093230815472096</id><published>2011-10-06T16:36:00.000-07:00</published><updated>2011-10-06T16:36:03.424-07:00</updated><title type='text'>Transparent screen lock for monitoring displays</title><content type='html'>There are situations where a transparent screen lock is useful: i.e. monitoring displays, build status etc.  On ubuntu I have used &lt;a href="http://manpages.ubuntu.com/manpages/hardy/man1/xtrlock.1x.html"&gt;xtrlock&lt;/a&gt;, and I'm looking for something similar for OS X.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1239093230815472096?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1239093230815472096/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1239093230815472096' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1239093230815472096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1239093230815472096'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/10/transparent-screen-lock-for-monitoring.html' title='Transparent screen lock for monitoring displays'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-4221788617965334422</id><published>2011-10-04T15:34:00.000-07:00</published><updated>2011-10-04T16:27:40.033-07:00</updated><title type='text'>OS X and DNS</title><content type='html'>If you look at /etc/resolv.conf on a mac and expect to see the definitive DNS config, you are being misled.  While some tools might use this config, most applications will use the mDNSResponder (the name is confusing, it is also used for unicast DNS) config maintained by configd.  You can see this with:&lt;br /&gt;&lt;pre&gt;scutil --dns&lt;br /&gt;&lt;/pre&gt;You can check out the mDNSReponder config with:&lt;br /&gt;&lt;pre&gt;defaults read /System/Library/LaunchDaemons/com.apple.mDNSResponder&lt;br /&gt;&lt;/pre&gt;Which, incidentally, is the place to add -NoMulticastAdvertisements to &lt;a href="http://support.apple.com/kb/HT3789"&gt;disable bonjour&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can make a query through mDNSResponder with:&lt;br /&gt;&lt;pre&gt;$ dscacheutil -q host -a name slashdot.org&lt;br /&gt;name: slashdot.org&lt;br /&gt;ip_address: 216.34.181.45&lt;br /&gt;&lt;br /&gt;$ dscacheutil -q host -a ip_address 216.34.181.45&lt;br /&gt;name: slashdot.org&lt;br /&gt;alias: 45.181.34.216.in-addr.arpa &lt;br /&gt;ip_address: 216.34.181.45&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To see the DNS cache, dump the state of mDNSResponder into system.log with:&lt;br /&gt;&lt;pre&gt;sudo killall -INFO mDNSResponder&lt;br /&gt;&lt;/pre&gt;You can also turn on (very verbose) DNS logging into system.log:&lt;br /&gt;&lt;pre&gt;sudo killall -USR1 mDNSResponder&lt;br /&gt;&lt;/pre&gt;Or even turn on packet capture with:&lt;br /&gt;&lt;pre&gt;sudo killall -USR2 mDNSResponder&lt;br /&gt;&lt;/pre&gt;You can see the other (non-DNS) caching in the local directory service with:&lt;br /&gt;&lt;pre&gt;dscacheutil -statistics&lt;br /&gt;dscacheutil -cachedump -entries&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-4221788617965334422?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/4221788617965334422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=4221788617965334422' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4221788617965334422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4221788617965334422'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/10/os-x-and-dns.html' title='OS X and DNS'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1922244379543980201</id><published>2011-10-03T23:02:00.000-07:00</published><updated>2011-10-03T23:16:22.844-07:00</updated><title type='text'>Automount and directory service search paths on OS X</title><content type='html'>The OS X directory service uses the search path to retrieve owner, group, and automount information.  A config looks like this:&lt;br /&gt;&lt;pre&gt;$ dscl localhost -read /Search&lt;br /&gt;CSPSearchPath: /Local/Default /BSD/local /LDAPv3/main.ldap.example.com&lt;br /&gt;DHCPLDAPDefault: off&lt;br /&gt;LSPSearchPath: /Local/Default /BSD/local&lt;br /&gt;NSPSearchPath: /Local/Default /BSD/local&lt;br /&gt;ReadOnlyNode: ReadOnly&lt;br /&gt;SearchPath: /Local/Default /BSD/local /LDAPv3/main.ldap.example.com&lt;br /&gt;SearchPolicy: dsAttrTypeStandard:CSPSearchPath&lt;br /&gt;&lt;/pre&gt;The SearchPolicy tells you which one will be used - in this case the Custom Search Path or CSPSearchPath (LSPSearchPath and NSPSearchPath are read-only), which will look in /Local/Default then /BSD/local then in the LDAP server main.ldap.example.com.  This is roughly the equivalent of nsswitch.conf on linux.  You can also see the same information in Directory Utility:&lt;br /&gt;&lt;pre&gt;"/System/Library/CoreServices/Directory Utility.app/Contents/MacOS/Directory Utility"&lt;br /&gt;&lt;/pre&gt;This app is used to configure the services that the mac will talk to for authentication (LDAP, NIS, Local, AD etc.), you can access that config on the command line with:&lt;br /&gt;&lt;pre&gt;sudo defaults read /Library/Preferences/DirectoryService/DirectoryService&lt;br /&gt;&lt;/pre&gt;Automounts are kept in /etc/auto_master and you can get it to look in LDAP for the mounting info by adding '+auto_master' to the config.  It will look for an automount map (see /etc/autofs.conf for more configuration options):&lt;br /&gt;&lt;pre&gt;dn: ou=auto.master,ou=automount,ou=admin,dc=example,dc=com&lt;br /&gt;ou: auto.master&lt;br /&gt;objectClass: top&lt;br /&gt;objectClass: automountMap&lt;br /&gt;&lt;/pre&gt;And shares identified by cn:&lt;br /&gt;&lt;pre&gt;dn: cn=/home,ou=auto.master,ou=automount,ou=admin,dc=example,dc=com&lt;br /&gt;cn: /home&lt;br /&gt;objectClass: top&lt;br /&gt;objectClass: automount&lt;br /&gt;automountInformation: -nosuid home.nfs:/home&lt;br /&gt;&lt;/pre&gt;You can dump a full list of shares with a LDAP search like this:&lt;br /&gt;&lt;pre&gt;ldapsearch -LLLx -b ou=auto.master,ou=automount,ou=admin,dc=example,dc=com&lt;br /&gt;&lt;/pre&gt;or via dscl like this:&lt;br /&gt;&lt;pre&gt;dscl localhost -readall /LDAPv3/main.ldap.example.com/Automount&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1922244379543980201?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1922244379543980201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1922244379543980201' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1922244379543980201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1922244379543980201'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/10/automount-and-directory-service-search.html' title='Automount and directory service search paths on OS X'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1480591139276422466</id><published>2011-09-16T14:32:00.000-07:00</published><updated>2011-12-08T17:51:35.780-08:00</updated><title type='text'>LDAP search queries</title><content type='html'>Some quick examples of common LDAP search queries.&lt;br /&gt;&lt;br /&gt;Search for a particular user:&lt;br /&gt;&lt;pre&gt;ldapsearch -LLLx "uid=myuser"&lt;br /&gt;&lt;/pre&gt;If your LDAP database is giant, you might want to limit that search to just the people tree:&lt;br /&gt;&lt;pre&gt;ldapsearch -LLLx -b ou=people,dc=myorg,dc=com "uid=myuser"&lt;br /&gt;&lt;/pre&gt;Find a netgroup:&lt;br /&gt;&lt;pre&gt;ldapsearch -LLLx -b ou=netgroup,dc=myorg,dc=com "cn=mymachine.myorg.com"&lt;br /&gt;&lt;/pre&gt;Wildcards also work:&lt;br /&gt;&lt;pre&gt;ldapsearch -LLLx -b ou=netgroup,dc=myorg,dc=com "cn=*fred*.myorg.com"&lt;br /&gt;&lt;/pre&gt;Regular group:&lt;br /&gt;&lt;pre&gt;ldapsearch -LLLx -b ou=group,dc=myorg,dc=com "cn=sysadmins"&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1480591139276422466?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1480591139276422466/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1480591139276422466' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1480591139276422466'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1480591139276422466'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/09/ldap-search-queries.html' title='LDAP search queries'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-704098383769507804</id><published>2011-09-16T12:05:00.000-07:00</published><updated>2011-09-16T12:06:19.984-07:00</updated><title type='text'>Reading MCX local_computer policies on the command line</title><content type='html'>Mactech has an article on using &lt;a href="http://www.mactech.com/articles/mactech/Vol.26/26.03/2603MacEnterprise-LocalMCXRevisited/index.html"&gt;local mcx policies&lt;/a&gt;.  To read them:&lt;br /&gt;&lt;pre&gt;dscl . -mcxread /Computers/local_computer&lt;br /&gt;&lt;/pre&gt;and you can also see the full contents of the local_computer record like this:&lt;br /&gt;&lt;pre&gt;defaults read /var/db/dslocal/nodes/Default/computers/local_computer&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-704098383769507804?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/704098383769507804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=704098383769507804' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/704098383769507804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/704098383769507804'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/09/reading-mcx-localcomputer-policies.html' title='Reading MCX local_computer policies on the command line'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-5645973411553962240</id><published>2011-09-14T18:32:00.000-07:00</published><updated>2011-09-14T18:33:09.732-07:00</updated><title type='text'>Reading and modifying OS X plist files on the command line</title><content type='html'>OS X uses plist files to store configuration information - you can think of them as OS X's version of the windows registry.&lt;br /&gt;&lt;br /&gt;To read a plist you can use:&lt;br /&gt;&lt;pre&gt;defaults read /Library/Preferences/com.apple.CrashReporter&lt;br /&gt;&lt;/pre&gt;and similarly to write a value to a plist&lt;br /&gt;&lt;pre&gt;sudo defaults write /Library/Preferences/com.apple.CrashReporter SomeKey -bool TRUE&lt;br /&gt;sudo defaults write /Library/Preferences/com.apple.CrashReporter SomeKey -string "somevalue"&lt;br /&gt;&lt;/pre&gt;and delete&lt;br /&gt;&lt;pre&gt;sudo defaults delete /Library/Preferences/com.apple.CrashReporter SomeKey&lt;br /&gt;&lt;/pre&gt;You can also use plutil to dump an XML version to stdout:&lt;br /&gt;&lt;pre&gt;plutil -convert xml1 -o - filename.plist&lt;br /&gt;&lt;/pre&gt;as well as convert between binary and XML formats.  Xcode also ships with a plist editor.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-5645973411553962240?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/5645973411553962240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=5645973411553962240' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5645973411553962240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5645973411553962240'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/09/reading-and-modifying-os-x-plist-files.html' title='Reading and modifying OS X plist files on the command line'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-5054774155155491384</id><published>2011-09-14T17:50:00.000-07:00</published><updated>2011-10-06T09:55:39.260-07:00</updated><title type='text'>Managing OS X users, groups, and access control from the commandline</title><content type='html'>User info&lt;br /&gt;&lt;pre&gt;dscl . read /Users/testing&lt;br /&gt;&lt;/pre&gt;Group info&lt;br /&gt;&lt;pre&gt;dscl . read /Groups/admin&lt;br /&gt;&lt;/pre&gt;Create a user&lt;br /&gt;&lt;pre&gt;sudo dscl . -create /Users/testing&lt;br /&gt;&lt;/pre&gt;Add a user to the admin group&lt;br /&gt;&lt;pre&gt;sudo dseditgroup -o edit -a testing -t user admin&lt;br /&gt;&lt;/pre&gt;Remove a user from the admin group&lt;br /&gt;&lt;pre&gt;sudo dseditgroup -o edit -d testing -t user admin&lt;br /&gt;&lt;/pre&gt;Delete a user&lt;br /&gt;&lt;pre&gt;sudo dscl . -delete /Users/testing&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-5054774155155491384?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/5054774155155491384/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=5054774155155491384' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5054774155155491384'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5054774155155491384'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/09/managing-os-x-users-groups-and-access.html' title='Managing OS X users, groups, and access control from the commandline'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1975008405835415147</id><published>2011-09-09T08:31:00.000-07:00</published><updated>2011-09-09T08:31:39.862-07:00</updated><title type='text'>Redirection of stdout and stderr</title><content type='html'>Some notes on redirection, &lt;a href="http://tldp.org/LDP/abs/html/io-redirection.html"&gt;this article has a good summary&lt;/a&gt;.  I hold these patterns in my head, but had long since forgotten what the syntax actually meant.  Send stdout and stderr to the same file:&lt;br /&gt;&lt;pre&gt;./generatesomeoutput &amp;&gt; some_file&lt;br /&gt;&lt;/pre&gt;Send stderr to stdout:&lt;br /&gt;&lt;pre&gt;./generatesomeoutput 2&gt;&amp;1&lt;br /&gt;&lt;/pre&gt;which is filedescriptor '2' (stderr) to file descriptor '1' (stdout), and the '&amp;' indicates that '1' is a filedescriptor not a filename.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1975008405835415147?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1975008405835415147/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1975008405835415147' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1975008405835415147'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1975008405835415147'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/09/redirection-of-stdout-and-stderr.html' title='Redirection of stdout and stderr'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-5076567484274551989</id><published>2011-09-07T12:53:00.000-07:00</published><updated>2011-09-07T12:53:19.443-07:00</updated><title type='text'>Mounting DMG images, the hard way</title><content type='html'>Opening a DMG in the finder is a fast way to get it mounted.  The manual steps are broken down as follows:&lt;br /&gt;&lt;br /&gt;Attach the disk image (if you omit the 'nomount' flag it will do the mounting automatically, I'm stopping that for demonstration purposes)&lt;br /&gt;&lt;pre&gt;root# hdiutil attach -nomount testing.dmg&lt;br /&gt;/dev/disk1           Apple_partition_scheme          &lt;br /&gt;/dev/disk1s1         Apple_partition_map             &lt;br /&gt;/dev/disk1s2         Apple_Driver_ATAPI              &lt;br /&gt;/dev/disk1s3         Apple_HFS                &lt;br /&gt;&lt;/pre&gt;The disk now exists:&lt;br /&gt;&lt;pre&gt;dhcp-172-26-92-208:images root# diskutil list&lt;br /&gt;[...snip...]&lt;br /&gt;/dev/disk1&lt;br /&gt;   #:                       TYPE NAME                    SIZE       IDENTIFIER&lt;br /&gt;   0:     Apple_partition_scheme                        *4.2 GB     disk1&lt;br /&gt;   1:        Apple_partition_map                         30.7 KB    disk1s1&lt;br /&gt;   2:         Apple_Driver_ATAPI                         2.0 KB     disk1s2&lt;br /&gt;   3:                  Apple_HFS Mac OS X                4.2 GB     disk1s3&lt;br /&gt;&lt;/pre&gt;And you can mount all partitions like this:&lt;br /&gt;&lt;pre&gt;diskutil mountDisk /dev/disk1&lt;br /&gt;&lt;/pre&gt;or just one with:&lt;br /&gt;&lt;pre&gt;diskutil mount /dev/disk1s3&lt;br /&gt;&lt;/pre&gt;Since we didn't specify targets, they will appear under /Volumes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-5076567484274551989?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/5076567484274551989/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=5076567484274551989' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5076567484274551989'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5076567484274551989'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/09/mounting-dmg-images-hard-way.html' title='Mounting DMG images, the hard way'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-2121034514922453234</id><published>2011-09-07T11:51:00.001-07:00</published><updated>2011-09-07T11:51:39.938-07:00</updated><title type='text'>HOWTO Convert an Apple disk image (DMG) to ISO</title><content type='html'>&lt;pre&gt;hdiutil convert /path/to/filename.dmg -format UDTO -o /path/to/savefile.iso&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-2121034514922453234?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/2121034514922453234/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=2121034514922453234' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2121034514922453234'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2121034514922453234'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/09/howto-convert-apple-disk-image-dmg-to.html' title='HOWTO Convert an Apple disk image (DMG) to ISO'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-2225276856209739691</id><published>2011-09-04T17:36:00.000-07:00</published><updated>2011-09-04T17:36:39.607-07:00</updated><title type='text'>HOWTO: dd a disk and watch progress</title><content type='html'>On linux, dd a disk and watch progress with this command. $! is the PID of the most recent background command:&lt;br /&gt;&lt;pre&gt;dd if=/dev/zero of=/dev/null bs=512k&amp;&lt;br /&gt;while [ $! ]; do kill -USR1 $! &amp;&amp; sleep 10 ; done&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;OS X uses a different signal:&lt;br /&gt;&lt;pre&gt;dd if=/dev/zero of=/dev/null bs=512k&amp;&lt;br /&gt;while [ $! ]; do kill -SIGINFO $! &amp;&amp; sleep 10 ; done&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-2225276856209739691?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/2225276856209739691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=2225276856209739691' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2225276856209739691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2225276856209739691'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/09/howto-dd-disk-and-watch-progress.html' title='HOWTO: dd a disk and watch progress'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-8319887557238363641</id><published>2011-09-01T15:22:00.000-07:00</published><updated>2011-09-01T15:22:58.135-07:00</updated><title type='text'>python datetime, strptime, strftime: working with datetime strings</title><content type='html'>I frequently find myself wanting to convert between a datetime object and a string representation.  Here is a quick code example of swapping between the two:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;t=datetime.datetime.now()&lt;br /&gt;astring = t.strftime("%Y-%m-%d %H:%M:%S")&lt;br /&gt;new_t = datetime.datetime.strptime(astring, "%Y-%m-%d %H:%M:%S")&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-8319887557238363641?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/8319887557238363641/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=8319887557238363641' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/8319887557238363641'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/8319887557238363641'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/09/python-datetime-strptime-strftime.html' title='python datetime, strptime, strftime: working with datetime strings'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-6127123432315882763</id><published>2011-08-11T09:58:00.000-07:00</published><updated>2011-08-11T09:58:52.542-07:00</updated><title type='text'>Is this Mac OS X app compiled with ASLR?</title><content type='html'>To determine if an OS X Mach-o binary is compiled with ASLR, look for the Position Independent Executable (PIE) flag in the Mach header:&lt;br /&gt;&lt;pre&gt;$ otool -hv MobileSafari &lt;br /&gt;&lt;br /&gt;MobileSafari:&lt;br /&gt;Mach header&lt;br /&gt;      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags&lt;br /&gt;   MH_MAGIC     ARM         V7  0x00     EXECUTE    40       4560   NOUNDEFS DYLDLINK TWOLEVEL PIE&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-6127123432315882763?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/6127123432315882763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=6127123432315882763' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6127123432315882763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6127123432315882763'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/08/is-this-mac-os-x-app-compiled-with-aslr.html' title='Is this Mac OS X app compiled with ASLR?'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-8203815792381329898</id><published>2011-08-09T12:52:00.000-07:00</published><updated>2011-08-09T12:52:35.045-07:00</updated><title type='text'>Python: add an entry to an dict of arrays or create one if it doesn't exist</title><content type='html'>I frequently am working with dictionaries of arrays and want to add an element to an existing array, or create one if it doesn't exist.  There is a &lt;a href="http://stackoverflow.com/questions/4143698/create-or-append-to-a-list-in-a-dictionary-can-this-be-shortened"&gt;neat, if not particularly easy to understand&lt;/a&gt;, way to do this with setdefault:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;result = {}&lt;br /&gt;for thisthing in alist:&lt;br /&gt;   result.setdefault(thisthing.somekey, []).append(thisthing.somevalue)&lt;br /&gt;&lt;/pre&gt;So you will end up with something like:&lt;br /&gt;&lt;pre&gt;{'key1':[value1, value2], 'key2': [value3]}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-8203815792381329898?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/8203815792381329898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=8203815792381329898' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/8203815792381329898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/8203815792381329898'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/08/python-add-entry-to-dict-of-arrays-or.html' title='Python: add an entry to an dict of arrays or create one if it doesn&apos;t exist'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-597229959254315617</id><published>2011-07-29T13:46:00.000-07:00</published><updated>2011-11-16T11:27:13.599-08:00</updated><title type='text'>HOWTO install OS X from a system image</title><content type='html'>To install OS X from a system image, first partition the disk using diskutil:&lt;br /&gt;&lt;pre&gt;diskutil partitionDisk disk0 2 GPT JHFS+ os 90% JHFS+ installer 10%&lt;br /&gt;&lt;/pre&gt;Download the install image onto the os partition:&lt;br /&gt;&lt;pre&gt;curl -o /Volumes/os/osximage.dmg -L http://mydomain.com/osximage.dmg&lt;br /&gt;&lt;/pre&gt;and restore it to the installer partition:&lt;br /&gt;&lt;pre&gt;asr restore --erase --noprompt --noverify --target /dev/disk0s3 --source /Volumes/os/osximage.dmg&lt;br /&gt;&lt;/pre&gt;Reboot!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-597229959254315617?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/597229959254315617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=597229959254315617' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/597229959254315617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/597229959254315617'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/07/howto-install-os-x-from-system-image.html' title='HOWTO install OS X from a system image'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-4712844719988991263</id><published>2011-07-26T22:24:00.000-07:00</published><updated>2011-07-26T22:24:54.314-07:00</updated><title type='text'>64-bit errors in real programs</title><content type='html'>There is a &lt;a href="http://software.intel.com/en-us/articles/collection-of-examples-of-64-bit-errors-in-real-programs/"&gt;great article on Intel's website&lt;/a&gt; about real programming errors in C/C++ that surfaced as bugs when the code was compiled and run as a 64-bit program.  A fair proportion involve some sort of type casting that makes assumptions about pointer size, and many are subtle bugs that will only be triggered when memory allocation is &gt; 4GB.  &lt;br /&gt;&lt;br /&gt;As 64-bit becomes the new norm I think we'll see a lot of buffer overflows and memory corruption bugs as a consequence of errors like these.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-4712844719988991263?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/4712844719988991263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=4712844719988991263' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4712844719988991263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4712844719988991263'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/07/64-bit-errors-in-real-programs.html' title='64-bit errors in real programs'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-7922328762313957265</id><published>2011-07-21T09:58:00.000-07:00</published><updated>2011-07-21T09:58:50.109-07:00</updated><title type='text'>Mac boot options</title><content type='html'>To &lt;a href="http://support.apple.com/kb/ht1492"&gt;enter single-user&lt;/a&gt;, hold down &amp;#8984;-S at boot.&lt;br /&gt;&lt;br /&gt;To get a menu of boot options (netboot, USB etc.) hold down option during boot.&lt;br /&gt;&lt;br /&gt;See the &lt;a href="http://support.apple.com/kb/ht1533"&gt;full list of boot options&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-7922328762313957265?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/7922328762313957265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=7922328762313957265' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7922328762313957265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7922328762313957265'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/07/mac-boot-options.html' title='Mac boot options'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-2854350253343108350</id><published>2011-07-21T09:54:00.000-07:00</published><updated>2011-10-07T12:29:20.269-07:00</updated><title type='text'>Remount a hfs partition read-write on a mac</title><content type='html'>To remount a partition read-write on linux you would use:&lt;br /&gt;&lt;pre&gt;mount -o remount,rw /dev/disk /mnt/point&lt;br /&gt;&lt;/pre&gt;On a mac the equivalent is:&lt;br /&gt;&lt;pre&gt;mount -u -w /dev/disk /mnt/point&lt;br /&gt;&lt;/pre&gt;In single user mode to get a writable root:&lt;br /&gt;&lt;pre&gt;mount -uw /&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-2854350253343108350?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/2854350253343108350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=2854350253343108350' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2854350253343108350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2854350253343108350'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/07/remount-hfs-partition-read-write-on-mac.html' title='Remount a hfs partition read-write on a mac'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-5639623592198238287</id><published>2011-07-21T09:51:00.000-07:00</published><updated>2011-07-22T23:38:46.714-07:00</updated><title type='text'>Ruby learnings</title><content type='html'>I had a brief foray into Ruby land recently, so thought I would record some lessons learnt here.&lt;br /&gt;&lt;br /&gt;Interactive ruby is like the really poor cousin to ipython.  Commandline completion is not on by default, you want to enable it using:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;alias irb='irb -r irb/completion'&lt;/pre&gt;and apparently the only way to get syntax highlighting is to &lt;a href="http://pablotron.org/software/wirble/"&gt;install the wirble gem&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;There are a &lt;a href="http://tech.natemurray.com/2007/03/ruby-shell-commands.html"&gt;bunch of ways to run shell commands&lt;/a&gt;.  The one I used was %x:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;cmd = "dscl . -read #{file} #{key} 2&gt; /dev/null"&lt;br /&gt;  output = %x{#{cmd}}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I was looking for a equivalent of the python string function 'startswith'.  The ruby equivalent actually has a ? in the function name (WTF?):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;if output.start_with?("#{key}: ")&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-5639623592198238287?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/5639623592198238287/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=5639623592198238287' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5639623592198238287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5639623592198238287'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/07/ruby-learnings.html' title='Ruby learnings'/><author><name>G</name><uri>http://www.blogger.com/profile/00562540281391628849</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-6581091498539039199</id><published>2011-07-12T17:32:00.000-07:00</published><updated>2011-07-12T17:32:38.974-07:00</updated><title type='text'>Useful Mac keyboard shortcuts</title><content type='html'>&lt;table cellpadding="10"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;General&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Fn-arrowkeys&lt;/span&gt;&lt;/td&gt;&lt;td&gt;PgUp and PgDown&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Control-Shift-⏏&lt;/span&gt;&lt;/td&gt;&lt;td&gt;Lock screen (sleep)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;#8984;-Space&lt;/span&gt;&lt;/td&gt;&lt;td&gt;Open Spotlight&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Terminal&lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;ESC-.&lt;/span&gt;&lt;/td&gt;&lt;td&gt;Paste last word of the last command under the cursor (equivalent of Alt-. in linux)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;#8984;-Shift-arrowkeys&lt;/span&gt;&lt;/td&gt;&lt;td&gt;Left right arrows switch between tabs&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;b&gt;Chrome&lt;/b&gt; (&lt;a href="http://www.google.com/support/chrome/bin/static.py?page=guide.cs&amp;guide=25799&amp;topic=28651"&gt;full list of shortcuts&lt;/a&gt;)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;#8984;-Option-arrowkeys&lt;/span&gt;&lt;/td&gt;&lt;td&gt;Let right arrows to switch between tabs.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-6581091498539039199?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/6581091498539039199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=6581091498539039199' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6581091498539039199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6581091498539039199'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/07/useful-mac-keyboard-shortcuts.html' title='Useful Mac keyboard shortcuts'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-2355813805599791121</id><published>2011-07-06T14:30:00.000-07:00</published><updated>2011-07-06T14:30:01.001-07:00</updated><title type='text'>HOWTO enable remote desktop for windows 7 users</title><content type='html'>The &lt;a href="http://technet.microsoft.com/en-us/magazine/ff404238.aspx"&gt;technet article&lt;/a&gt; has all the details on how to configure remote desktop, but the tl;dr to enable it for a user is:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Control Panel -&gt; System -&gt; Remote Settings -&gt; Select Users&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-2355813805599791121?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/2355813805599791121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=2355813805599791121' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2355813805599791121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2355813805599791121'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/07/howto-enable-remote-desktop-for-windows.html' title='HOWTO enable remote desktop for windows 7 users'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1094424901184809331</id><published>2011-07-06T14:27:00.000-07:00</published><updated>2011-07-06T14:27:16.646-07:00</updated><title type='text'>HOWTO list local administrators on the Windows commandline</title><content type='html'>To get a list of local admins:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;net localgroup administrators&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1094424901184809331?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1094424901184809331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1094424901184809331' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1094424901184809331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1094424901184809331'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/07/howto-list-local-administrators-on.html' title='HOWTO list local administrators on the Windows commandline'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-7273406866804146597</id><published>2011-06-13T18:36:00.000-07:00</published><updated>2011-06-13T18:36:33.235-07:00</updated><title type='text'>Installing the shitty Amazon MP3 downloader on Ubuntu Lucid</title><content type='html'>While it sucks to have to use a MP3 downloader app at all, it's good Amazon actually has a linux version (it wasn't always the case).  But it is a shame they did such a bad job of it.  They wrote the downloader for Ubuntu Jaunty (now a number of releases old) and haven't updated it since.  &lt;br /&gt;&lt;br /&gt;The correct way to distribute this app would have been to provide a PPA you could put in your apt sources, which would be updated for each new version of Ubuntu, and allow the full package management capability.  By using .debs any dependencies need to be manually satisfied, and you can't push updates or bug-fixes, although it looks like Amazon has written that functionality into the program itself.  The deb also depends on very specific versions of libboost, rather than just specifying a minimum version number, which would allow it to work on later releases.&lt;br /&gt;&lt;br /&gt;So installing it on lucid, or any other version is a bit of a pain.  Here is one solution, that grabs the original dependencies from launchpadlibrarian and installs them:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;wget https://launchpadlibrarian.net/26959932/libboost-signals1.34.1_1.34.1-16ubuntu1_i386.deb \&lt;br /&gt;https://launchpadlibrarian.net/26959936/libboost-thread1.34.1_1.34.1-16ubuntu1_i386.deb \&lt;br /&gt;https://launchpadlibrarian.net/26959922/libboost-iostreams1.34.1_1.34.1-16ubuntu1_i386.deb \&lt;br /&gt;https://launchpadlibrarian.net/26959918/libboost-filesystem1.34.1_1.34.1-16ubuntu1_i386.deb \&lt;br /&gt;https://launchpadlibrarian.net/26959916/libboost-date-time1.34.1_1.34.1-16ubuntu1_i386.deb \&lt;br /&gt;https://launchpadlibrarian.net/26959928/libboost-regex1.34.1_1.34.1-16ubuntu1_i386.deb \&lt;br /&gt;https://launchpadlibrarian.net/34165098/libicu40_4.0.1-2ubuntu2_i386.deb&lt;br /&gt;sudo dpkg -i *.deb&lt;br /&gt;sudo dpkg -i amazonmp3.deb&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-7273406866804146597?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/7273406866804146597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=7273406866804146597' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7273406866804146597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7273406866804146597'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/06/installing-shitty-amazon-mp3-downloader.html' title='Installing the shitty Amazon MP3 downloader on Ubuntu Lucid'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-2240838072843083686</id><published>2011-05-24T14:21:00.000-07:00</published><updated>2011-05-24T14:21:01.400-07:00</updated><title type='text'>Contacting file owners: using find, awk, and xargs to creating lists of files and operate on them</title><content type='html'>Say you want to contact a bunch of file owners to do some cleanup or housekeeping.  This will get you a list of files sorted by owner.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;find . -type f -name "*blah*" "%u %M %g %y %p\n" | sort&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But we can do better.  Here is a neat little awk command that will drop filenames into txt files named after the user.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;find . -type f -name "*blah*" "%u %M %g %y %p\n" | sort | awk 'BEGIN {FS=" "} { print $5 &gt;&gt;"/home/me/temp/"$1".txt" }'&lt;br /&gt;&lt;/pre&gt;So the end result is that /home/me/temp/mike.txt contains a list of files that mike owns.  You can then tell mike to do something with those files (in this example, delete) using xargs like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;xargs -a mike.txt rm -f&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;How do you tell mike? well you can get a list of addresses to drop into your mail client:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;find . -type f -name "*blah*" "%u@company.com\n" | sort | uniq&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;then drag and drop the USERNAME.txt files into the mail.  With a bit more effort you could automate the sending mail step too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-2240838072843083686?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/2240838072843083686/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=2240838072843083686' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2240838072843083686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2240838072843083686'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/05/contacting-file-owners-using-find-awk.html' title='Contacting file owners: using find, awk, and xargs to creating lists of files and operate on them'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-3134170846785909532</id><published>2011-05-20T18:27:00.000-07:00</published><updated>2011-05-20T18:27:24.427-07:00</updated><title type='text'>Adding other arguments when using *args and **kwargs in python</title><content type='html'>Sometimes you need to use *args and **kwargs to pass your positional and keyword args to another class.  But what if your class takes an additional argument you don't want to pass to the super class?  Here are a couple of options.&lt;br /&gt;&lt;br /&gt;Add a new positional argument&lt;br /&gt;&lt;pre class="prettyprint"&gt;  def __init__(self, a_list, *args, **kwargs):&lt;br /&gt;    super(MyClass, self).__init__(*args, **kwargs)&lt;br /&gt;    self._mylist = a_list&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Add a new keyword argument&lt;br /&gt;&lt;pre class="prettyprint"&gt;  def __init__(self, *args, **kwargs):&lt;br /&gt;    self._mylist = kwargs.pop('a_list', ['some', 'default', 'list'])&lt;br /&gt;    super(MyClass, self).__init__(*args, **kwargs)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-3134170846785909532?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/3134170846785909532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=3134170846785909532' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3134170846785909532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3134170846785909532'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/05/adding-other-arguments-when-using-args.html' title='Adding other arguments when using *args and **kwargs in python'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1649585848947092662</id><published>2011-05-16T17:13:00.000-07:00</published><updated>2011-05-16T17:13:13.725-07:00</updated><title type='text'>HOWTO: delete/rename files with special characters (! ~ %) on the linux commandline</title><content type='html'>Sometimes you (or your code) screws up and you end up with a filename that is hard to address on the filename because it has special characters in its name.  In some cases you can get away with prepending a ./ or quoting, or escaping with backslash.  When those don't work, this can get you out of trouble.  &lt;br /&gt;&lt;br /&gt;First, grab the file or directory's inode:&lt;br /&gt;&lt;pre&gt;ls -lhi&lt;br /&gt;&lt;/pre&gt;Then use the find command with the inode of the troublemaker:&lt;br /&gt;&lt;pre&gt;find . -type f -inum 25167125 -exec mv {} binary_safe \;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1649585848947092662?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1649585848947092662/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1649585848947092662' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1649585848947092662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1649585848947092662'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/05/howto-deleterename-files-with-special.html' title='HOWTO: delete/rename files with special characters (! ~ %) on the linux commandline'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-5230009594135898329</id><published>2011-05-05T22:36:00.000-07:00</published><updated>2011-05-05T22:36:43.893-07:00</updated><title type='text'>HOWTO tunnel through multiple boxes with SSH</title><content type='html'>Making ssh tunnels, even through multiple machines, is easy.  These two commands will effectively link localhost:9999 with box3:80, via box2.&lt;br /&gt;&lt;br /&gt;&lt;pre class=prettyprint&gt;user@box1:~$ ssh -L 9999:localhost:9999 box2&lt;br /&gt;user@box2:~$ ssh -L 9999:localhost:80 box3&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-5230009594135898329?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/5230009594135898329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=5230009594135898329' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5230009594135898329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5230009594135898329'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/05/howto-tunnel-through-multiple-boxes.html' title='HOWTO tunnel through multiple boxes with SSH'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1640742265487301284</id><published>2011-05-04T23:50:00.000-07:00</published><updated>2011-05-04T23:50:40.216-07:00</updated><title type='text'>Loving the Cyber Bomb?  Why don't we love the Cyber Security Bounties instead?</title><content type='html'>A paper &lt;i&gt;&lt;a href="http://mercatus.org/sites/default/files/publication/110421-cybersecurity.pdf"&gt;Loving the Cyber Bomb? The Dangers of Threat Inflation in Cybersecurity Policy&lt;/a&gt;&lt;/i&gt; by Brito and Watkins of the Mercatus Institute at Virginia's George Mason University makes the argument that the cyber threat is being overblown by government agencies and defence contractors in the chase for dollars.  It draws some analogies with the 'evidence' of WMDs that led to the invasion of Iraq.  &lt;br /&gt;&lt;br /&gt;I don't really buy the analogy that the cyber threat is as vaporous as Iraq's WMDs.  Brito and Watkins seem to be implying that the argument that anything less than the ability of an attacker to "derail trains, release chlorine gas, or bring down the power grid" doesn't matter that much.  We have &lt;a href="http://www.verizonbusiness.com/go/2011dbir"&gt;plenty of evidence&lt;/a&gt; that companies of all sizes are regularly compromised, and I'm sure they'd tell you the loss of business, and/or costs incurred, mattered.  I think the Estonian government and businesses would also argue with Brito and Watkins' downplaying of the &lt;a href="http://en.wikipedia.org/wiki/2007_cyberattacks_on_Estonia"&gt;2007 DDOS&lt;/a&gt;.  A cited lack of previous power outages provably due to electronic attack to-date doesn't mean it isn't possible, and it might be more likely to happen at the consumer level as the industry moves towards &lt;a href="http://www.patrickmcdaniel.org/pubs/critis09.pdf"&gt;smart metering&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;However, Brito and Watkins do highlight the dangers of poorly targeted government spending being poured into defence contractor's pockets for little gain in security.  It was interesting to read about the courtship of the newly-established US Cyber Command ('Cyber Pork' p. 26) by various US towns and states, in a bid to attract its billions of dollars of government investment.  Maryland eventually won that battle.&lt;br /&gt;&lt;br /&gt;How could these dollars be spent to get the best security for your dollar?  I would suggest bounties for specific, measurable, and product-agnostic security improvements.  Something like the items from &lt;a href="http://www.dsd.gov.au/_lib/pdf_doc/intrusion_mitigations.pdf"&gt;this list&lt;/a&gt; produced by the Australian government.  Government could offer to cover the costs of implementation (up to a fixed amount) of the top 5 security controls.  The offer could be restricted to select government agencies, as well as companies running important infrastructure such as power and water.  If you spent $500k on an application whitelisting rollout for a power company it would seem cheap when the next Conficker rolled around.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1640742265487301284?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1640742265487301284/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1640742265487301284' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1640742265487301284'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1640742265487301284'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/05/loving-cyber-bomb-why-dont-we-love.html' title='Loving the Cyber Bomb?  Why don&apos;t we love the Cyber Security Bounties instead?'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-3663724571135168219</id><published>2011-05-02T22:31:00.000-07:00</published><updated>2011-06-05T16:32:51.975-07:00</updated><title type='text'>HOWTO mount a remote luks encrypted volume on demand</title><content type='html'>I wanted to create a cron'd backup to a luks volume on a remote machine.  My preference was to not have the volume mounted automatically so if my friend rebooted the box it wouldn't block the boot process waiting for the password.  It would also be nice if it just mounted itself when necessary and was locked for the rest of the time.&lt;br /&gt;&lt;br /&gt;First authorise my user to mount and unlock the volume using specific sudo commands (in /etc/sudoers):&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;Cmnd_Alias CRYPTOPEN=/sbin/cryptsetup luksOpen /dev/disk/by-uuid/41885992-3f80-4aaa-bc60-9c5854017ca9 crypt-backup --key-file /tmp/keyfile&lt;br /&gt;Cmnd_Alias MOUNT=/bin/mount /dev/mapper/crypt-backup /mnt/backup&lt;br /&gt;Cmnd_Alias UMOUNT=/bin/umount /mnt/backup&lt;br /&gt;Cmnd_Alias CRYPTCLOSE=/sbin/cryptsetup luksClose crypt-backup&lt;br /&gt;&lt;br /&gt;myuser ALL=(root) NOPASSWD: CRYPTOPEN,MOUNT,UMOUNT,CRYPTCLOSE&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then, a script on my side:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;scp /data/backup/scripts/backup/hdd_keyfile.luks home:/tmp/keyfile &amp;&amp; \&lt;br /&gt;ssh home "chmod 600 /tmp/keyfile &amp;&amp; sudo /sbin/cryptsetup luksOpen /dev/disk/by-uuid/41885992-3f80-4aaa-bc60-9c5854017ca9 crypt-backup --key-file /tmp/keyfile"&lt;br /&gt;if [ $? -ne 0 ]; then&lt;br /&gt;    echo "cryptsetup failed."&lt;br /&gt;    ssh home "shred -u /tmp/keyfile"&lt;br /&gt;    exit 1&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;ssh home "sudo /bin/mount /dev/mapper/crypt-backup /mnt/backup"&lt;br /&gt;if [ $? -ne 0 ]; then&lt;br /&gt;    echo "mount failed."&lt;br /&gt;    exit 1&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;rsync -rtv --compress-level=4 /data/ home:/mnt/backup/data/&lt;br /&gt;rsync -rtv --compress-level=4 /mp3/ home:/mnt/backup/mp3/&lt;br /&gt;&lt;br /&gt;ssh home "sudo /bin/umount /mnt/backup &amp;&amp; sudo /sbin/cryptsetup luksClose crypt-backup"&lt;br /&gt;if [ $? -ne 0 ]; then&lt;br /&gt;    echo "umount failed."&lt;br /&gt;    exit 1&lt;br /&gt;fi&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Chuck it in a cron.  Done.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-3663724571135168219?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/3663724571135168219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=3663724571135168219' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3663724571135168219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3663724571135168219'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/05/howto-mount-remote-luks-encrypted.html' title='HOWTO mount a remote luks encrypted volume on demand'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-5113607726513914709</id><published>2011-04-25T09:53:00.000-07:00</published><updated>2011-04-25T09:53:07.271-07:00</updated><title type='text'>Dropbox authentication issues</title><content type='html'>There has been some discussion of whether the &lt;a href="http://dereknewton.com/2011/04/dropbox-authentication-static-host-ids/"&gt;dropbox authentication system is a vulnerability&lt;/a&gt;, or just as insecure as everything else.  At the very least: if changing your password doesn't change the underlying key stored on your machine, that an attacker could have copied, it makes denying access to an attacker post-compromise fairly difficult.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-5113607726513914709?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/5113607726513914709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=5113607726513914709' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5113607726513914709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5113607726513914709'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/04/dropbox-authentication-issues.html' title='Dropbox authentication issues'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-4469089866697117749</id><published>2011-04-13T19:28:00.000-07:00</published><updated>2011-04-13T19:28:01.794-07:00</updated><title type='text'>#ifdef DEBUG print statements in C</title><content type='html'>The #ifdef DEBUG design pattern for debug output is extremely common in C code.  Here is a nice DEBUG macro I have used in the past:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;#ifdef DEBUG&lt;br /&gt;#define DEBUG_PRINT(fmt, args...)  \&lt;br /&gt;       fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, __LINE__, __FUNCTION__, ##args)&lt;br /&gt;#else&lt;br /&gt;#define DEBUG_PRINT(fmt, args...)    /* Don't do anything in non-debug builds */&lt;br /&gt;#endif&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As suggested in &lt;a href="http://stackoverflow.com/questions/1644868/c-define-macro-for-debug-printing/"&gt;this post&lt;/a&gt;, letting the compiler see your debug code is important to ensure it isn't broken by people changing code without making debug builds.  This macro achieves that goal by letting the preprocessor insert a statement that will be pulled out by the optimiser for non-debug builds.  This is the best solution I have come across.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;#ifdef DEBUG&lt;br /&gt;#define DEBUG_TEST 1&lt;br /&gt;#else&lt;br /&gt;#define DEBUG_TEST 0&lt;br /&gt;#endif&lt;br /&gt;&lt;br /&gt;#define DEBUG_PRINT(fmt, args...) \&lt;br /&gt;        do { if (DEBUG_TEST) fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \&lt;br /&gt;                                __LINE__, __FUNCTION__, ##args); } while (0)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-4469089866697117749?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/4469089866697117749/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=4469089866697117749' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4469089866697117749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4469089866697117749'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/04/ifdef-debug-print-statements-in-c.html' title='#ifdef DEBUG print statements in C'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-3651831852509063077</id><published>2011-04-13T19:26:00.000-07:00</published><updated>2011-04-13T19:26:23.459-07:00</updated><title type='text'>Mingw example makefile for console app and DLL</title><content type='html'>Here is a basic Makefile to use with mingw to compile some common types of windows binaries - a windows console app, a non-console 'windows' subsystem app, and a DLL.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;# Example mingw makefile&lt;br /&gt;&lt;br /&gt;TARGETNAME=myapp&lt;br /&gt;&lt;br /&gt;CC = i586-mingw32msvc-gcc&lt;br /&gt;&lt;br /&gt;# A basic windows app (won't bring up a console window)&lt;br /&gt;CFLAGS = -Wall -O -Wl,--subsystem,windows&lt;br /&gt;&lt;br /&gt;# for debugging make this a console app (so we can write to stdout/stderr) easily;&lt;br /&gt;# turn off optimisations and include symbols to help with running in a debugger&lt;br /&gt;CFLAGS_DEBUG = -Wall -O0 -g -Wl,--subsystem,console -DDEBUG&lt;br /&gt;&lt;br /&gt;# Create a dll instead of an exe&lt;br /&gt;CFLAGS_DLL = -Wall -O0 -g -shared -Wl,--subsystem,windows -DDLL&lt;br /&gt;&lt;br /&gt;# Any libraries you need - in this case wininet for communicating to the internet&lt;br /&gt;LIBS = -lwininet&lt;br /&gt;&lt;br /&gt;# Strip the binary for our prod build&lt;br /&gt;STRIP = i586-mingw32msvc-strip&lt;br /&gt;&lt;br /&gt;# UPX pack to minimise size for our prod build&lt;br /&gt;UPX=upx -9&lt;br /&gt;&lt;br /&gt;# Leave symbols, turn off optimisation, and send output to console&lt;br /&gt;debug: $(TARGETNAME).c&lt;br /&gt;        $(CC) -o $(TARGETNAME)_dbg $(CFLAGS_DEBUG) $^ $(LIBS)&lt;br /&gt;&lt;br /&gt;# No debug symbols, debug statements removed, subsystem windows means we won't pop a window&lt;br /&gt;$(TARGETNAME): $(TARGETNAME).c&lt;br /&gt;        $(CC) -o $@ $(CFLAGS) $^ $(LIBS)&lt;br /&gt;&lt;br /&gt;$(TARGETNAME).dll: $(TARGETNAME).c&lt;br /&gt;        $(CC) -o $@ $(CFLAGS_DLL) $^ $(LIBS)&lt;br /&gt;&lt;br /&gt;release: $(TARGETNAME)&lt;br /&gt;        $(STRIP) $&lt;&lt;br /&gt;        $(UPX) $&lt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-3651831852509063077?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/3651831852509063077/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=3651831852509063077' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3651831852509063077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3651831852509063077'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/04/mingw-example-makefile-for-console-app.html' title='Mingw example makefile for console app and DLL'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1284914773420407459</id><published>2011-04-13T19:25:00.000-07:00</published><updated>2011-04-13T19:25:00.137-07:00</updated><title type='text'>Using a word macro to run an executable on Windows 7, Office 2007</title><content type='html'>To write a macro in Office 2007, you'll want the developer tab in the ribbon.&amp;nbsp; Turn it on by clicking the Office icon in the top left corner of Word and then 'Word Options'.&amp;nbsp; Find the 'Show Developer tab in the Ribbon' and check it.&lt;br /&gt;&lt;br /&gt;Use this macro code to run blah.exe when the document is opened (using &lt;a href="http://support.microsoft.com/kb/286310"&gt;AutoOpen&lt;/a&gt;):&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;Private Declare Function WinExec Lib "Kernel32.dll" (ByVal lpCmdLine As String, ByVal nShowCmd As Long) As Long&lt;br /&gt;&lt;br /&gt;Sub AutoOpen()&lt;br /&gt;&lt;br /&gt;    Call WinExec("C:\blah.exe", SW_NORMAL)&lt;br /&gt;&lt;br /&gt;End Sub&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1284914773420407459?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1284914773420407459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1284914773420407459' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1284914773420407459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1284914773420407459'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/04/using-word-macro-to-run-executable-on.html' title='Using a word macro to run an executable on Windows 7, Office 2007'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-4767520276995623382</id><published>2011-04-03T23:11:00.000-07:00</published><updated>2011-04-04T20:39:15.236-07:00</updated><title type='text'>Streaming internet radio with MythTV</title><content type='html'>Streaming internet radio with mythtv is, sadly, still confined to the realm of hacks.  One simple solution is to &lt;a href="http://www.gossamer-threads.com/lists/mythtv/users/26491?do=post_view_threaded"&gt;just drop ".pls" files into your videos directory&lt;/a&gt;.  Assuming you use mplayer to play your videos, that should just work.  Unfortunately I like to use the internal player so I can use the time stretch feature on videos as well as recordings.  The internal player doesn't play ".pls" files, so that option is out. &lt;br /&gt;&lt;br /&gt;The other approach is to hack in a new menu item and get it to run mplayer.  There are a few &lt;a href="http://www.mythtv.org/wiki/Streaming_Internet_Audio_Using_Mplayer"&gt;descriptions of how to do this&lt;/a&gt;, so here is my 2c.&lt;br /&gt;&lt;br /&gt;Edit &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/usr/share/mythtv/themes/defaultmenu/library.xml&lt;/span&gt; to add:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&amp;lt;button&amp;gt;&lt;br /&gt;    &amp;lt;type&amp;gt;MUSIC_RADIO&amp;lt;/type&amp;gt;&lt;br /&gt;    &amp;lt;text&amp;gt;Listen to Internet Radio&amp;lt;/text&amp;gt;&lt;br /&gt;    &amp;lt;description&amp;gt;Listen to Internet Radio&amp;lt;/description&amp;gt;&lt;br /&gt;    &amp;lt;action&amp;gt;MENU inetradio.xml&amp;lt;/action&amp;gt;&lt;br /&gt;    &amp;lt;depends&amp;gt;mythmusic&amp;lt;/depends&amp;gt;&lt;br /&gt;&amp;lt;/button&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And create &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;inetradio.xml&lt;/span&gt; in the same directory.&amp;nbsp; The Australian Broadcasting Corporation (ABC) links are a little hard to find - you can get them &lt;a href="http://www.abc.net.au/radio/listenlive.htm#directlinks"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;pre class="prettyprint"&gt;&amp;lt;mythmenu name="INETRADIO"&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;button&amp;gt;&lt;br /&gt;&amp;lt;type&amp;gt;MUSIC_PLAY&amp;lt;/type&amp;gt;&lt;br /&gt;&amp;lt;text&amp;gt;NPR&amp;lt;/text&amp;gt;&lt;br /&gt;&amp;lt;action&amp;gt;EXEC /usr/bin/mythradio http://npr.ic.llnwd.net/stream/npr_live24&amp;lt;/action&amp;gt;&lt;br /&gt;&amp;lt;/button&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;button&amp;gt;&lt;br /&gt;&amp;lt;type&amp;gt;MUSIC_PLAY&amp;lt;/type&amp;gt;&lt;br /&gt;&amp;lt;text&amp;gt;TripleJ&amp;lt;/text&amp;gt;&lt;br /&gt;&amp;lt;action&amp;gt;EXEC /usr/bin/mythradio http://www.abc.net.au/res/streaming/audio/aac/triplej.pls&amp;lt;/action&amp;gt;&lt;br /&gt;&amp;lt;/button&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;button&amp;gt;&lt;br /&gt;&amp;lt;type&amp;gt;MUSIC_PLAY&amp;lt;/type&amp;gt;&lt;br /&gt;&amp;lt;text&amp;gt;RawFM&amp;lt;/text&amp;gt;&lt;br /&gt;&amp;lt;action&amp;gt;EXEC /usr/bin/mythradio http://www.rawfm.com.au/stream/playlists/160kbitMP3.pls&amp;lt;/action&amp;gt;&lt;br /&gt;&amp;lt;/button&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;button&amp;gt;&lt;br /&gt;&amp;lt;type&amp;gt;MUSIC_PLAY&amp;lt;/type&amp;gt;&lt;br /&gt;&amp;lt;text&amp;gt;666 ABC Canberra&amp;lt;/text&amp;gt;&lt;br /&gt;&amp;lt;action&amp;gt;EXEC /usr/bin/mythradio http://www.abc.net.au/res/streaming/audio/aac/local_canberra.pls&amp;lt;/action&amp;gt;&lt;br /&gt;&amp;lt;/button&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;button&amp;gt;&lt;br /&gt;&amp;lt;type&amp;gt;MUSIC_PLAY&amp;lt;/type&amp;gt;&lt;br /&gt;&amp;lt;text&amp;gt;ABC Classic FM&amp;lt;/text&amp;gt;&lt;br /&gt;&amp;lt;action&amp;gt;EXEC /usr/bin/mythradio http://www.abc.net.au/res/streaming/audio/aac/classic_fm.pls&amp;lt;/action&amp;gt;&lt;br /&gt;&amp;lt;/button&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;button&amp;gt;&lt;br /&gt;&amp;lt;type&amp;gt;MUSIC_PLAY&amp;lt;/type&amp;gt;&lt;br /&gt;&amp;lt;text&amp;gt;Stop Playing&amp;lt;/text&amp;gt;&lt;br /&gt;&amp;lt;action&amp;gt;EXEC pkill -f mplayer&amp;lt;/action&amp;gt;&lt;br /&gt;&amp;lt;/button&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/mythmenu&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And create &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/usr/bin/mythradio&lt;/span&gt; (this wouldn't be necessary if you could give multiple commands to "EXEC" - unfortunately it seems to break the syntax and mythtv says it is an invalid XML file).  The include file is a one line mplayer config that tells mplayer to allow the screensaver to run, so you can avoid burn-in while listening to the radio.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;#!/bin/bash&lt;br /&gt;pkill -f mplayer&lt;br /&gt;/usr/bin/mplayer -include /etc/mythtv/mplayer_noscr.conf $1 &amp;amp;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and here is &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/etc/mythtv/mplayer_noscr.conf&lt;/span&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;stop-xscreensaver=no&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-4767520276995623382?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/4767520276995623382/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=4767520276995623382' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4767520276995623382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4767520276995623382'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/04/streaming-internet-radio-with-mythtv.html' title='Streaming internet radio with MythTV'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-7866080216473416917</id><published>2011-03-12T23:08:00.000-08:00</published><updated>2011-03-12T23:08:47.758-08:00</updated><title type='text'>HOWTO Troubleshoot windows sound problems (for parents using google video chat)</title><content type='html'>The good people at google, have a nice parent-friendly &lt;a href="http://www.youtube.com/watch?v=Ep1xhJK7CRg"&gt;intro to video chat&lt;/a&gt;.  Unfortunately, getting to the point of having a gmail account with the plugin installed, is, in my experience, the easy part.&lt;br /&gt;&lt;br /&gt;The bigger challenge is troubleshooting audio problems, and the &lt;a href="http://mail.google.com/support/bin/answer.py?hl=en&amp;amp;ctx=mail&amp;amp;answer=100173"&gt;google troubleshooting page doesn't offer much help&lt;/a&gt;, apart from a weird endorsement of Logitech products.&amp;nbsp; For the people I chat with, the problem is usually a muted microphone, and/or muted sound.&amp;nbsp; Instructions for modifying sound setup on Windows 7 are below. &lt;br /&gt;&lt;br /&gt;Look at the bottom right corner of the screen for the speaker icon&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh6.googleusercontent.com/-frO0Zle7izA/TXxmBBFZiJI/AAAAAAAAACE/DICQQRZpVO4/s1600/1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://lh6.googleusercontent.com/-frO0Zle7izA/TXxmBBFZiJI/AAAAAAAAACE/DICQQRZpVO4/s1600/1.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Left click the speaker, and make sure the volume is turned up&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh4.googleusercontent.com/-ECSVNrVtCa8/TXxmJrnZH3I/AAAAAAAAACI/y0pLtb7VTeM/s1600/2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://lh4.googleusercontent.com/-ECSVNrVtCa8/TXxmJrnZH3I/AAAAAAAAACI/y0pLtb7VTeM/s320/2.png" width="235" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Check if that solves the problem.&amp;nbsp; If not, right click the speaker and choose playback devices&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-o2HNPuaWdds/TXxmLEW0FKI/AAAAAAAAACM/oswyalMeKq4/s1600/3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://lh5.googleusercontent.com/-o2HNPuaWdds/TXxmLEW0FKI/AAAAAAAAACM/oswyalMeKq4/s1600/3.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Click Properties&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh6.googleusercontent.com/-JgfLOvZcJms/TXxmLYPA9VI/AAAAAAAAACQ/MpFhjEau0t8/s1600/4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://lh6.googleusercontent.com/-JgfLOvZcJms/TXxmLYPA9VI/AAAAAAAAACQ/MpFhjEau0t8/s320/4.png" width="286" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;and check the slider is turned up on the Levels tab.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh3.googleusercontent.com/-ALRDbjty6jA/TXxmL1CzybI/AAAAAAAAACU/ZM9o1_iPWY8/s1600/5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://lh3.googleusercontent.com/-ALRDbjty6jA/TXxmL1CzybI/AAAAAAAAACU/ZM9o1_iPWY8/s320/5.png" width="288" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Click OK, and get out to the desktop.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Right click on the speaker again to check your microphone.&amp;nbsp; Click recording devices.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-o2HNPuaWdds/TXxmLEW0FKI/AAAAAAAAACM/oswyalMeKq4/s1600/3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://lh5.googleusercontent.com/-o2HNPuaWdds/TXxmLEW0FKI/AAAAAAAAACM/oswyalMeKq4/s1600/3.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&amp;nbsp;The green bar should move up and down as it registers sound.&amp;nbsp; Try talking.&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh3.googleusercontent.com/-yM0FyoljdcA/TXxmMOYyqZI/AAAAAAAAACY/btgiMTpdjiw/s1600/6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://lh3.googleusercontent.com/-yM0FyoljdcA/TXxmMOYyqZI/AAAAAAAAACY/btgiMTpdjiw/s320/6.png" width="287" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: left;"&gt;If that all looks OK, google provides an interface for you to check your settings from within gmail.&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Login and click on the settings link on the top right corner&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh5.googleusercontent.com/-vSgVkKd5AKM/TXxqpnaCfmI/AAAAAAAAACc/oEMUz__k5Fg/s1600/1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="103" src="https://lh5.googleusercontent.com/-vSgVkKd5AKM/TXxqpnaCfmI/AAAAAAAAACc/oEMUz__k5Fg/s320/1.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Then click on the chat tab&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh6.googleusercontent.com/-6l1gq2bSB6I/TXxqp7parlI/AAAAAAAAACg/NGMnH-DZcZA/s1600/2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="134" src="https://lh6.googleusercontent.com/-6l1gq2bSB6I/TXxqp7parlI/AAAAAAAAACg/NGMnH-DZcZA/s320/2.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;and on the + sign next to "Verify your settings".&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://lh4.googleusercontent.com/-JuUtocC6QwE/TXxqqLF_zxI/AAAAAAAAACk/kv4gLXA7HEQ/s1600/3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="133" src="https://lh4.googleusercontent.com/-JuUtocC6QwE/TXxqqLF_zxI/AAAAAAAAACk/kv4gLXA7HEQ/s320/3.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;If you answer 'Yes' to all three questions in that box, and you still don't have working audio or video, you can tell the person on the other side that it is a problem on their end, and point them to these instructions :)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-7866080216473416917?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/7866080216473416917/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=7866080216473416917' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7866080216473416917'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7866080216473416917'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/03/howto-troubleshoot-windows-sound.html' title='HOWTO Troubleshoot windows sound problems (for parents using google video chat)'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh6.googleusercontent.com/-frO0Zle7izA/TXxmBBFZiJI/AAAAAAAAACE/DICQQRZpVO4/s72-c/1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1176534632550132046</id><published>2011-03-12T12:15:00.000-08:00</published><updated>2012-01-14T21:11:45.194-08:00</updated><title type='text'>HOWTO Create multiple chrome and firefox profiles on linux</title><content type='html'>I like using multiple browser profiles for security reasons.  I keep my valuable cookies, such as those for email etc. in one profile, and do regular web-browsing in another.  This means if I hit a XSS through regular browsing, the scope for cookie stealing is limited.  When using firefox with the noscript plugin it also makes sense to have different whitelists for these two usage scenarios.&lt;br /&gt;&lt;br /&gt;Creating firefox profiles is simple, just use the profile manager, which you can bring up with:&lt;br /&gt;&lt;pre&gt;firefox --no-remote -P&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Once you have created the profile, I copy the shortcut icon and change the target to point at the new profile like this:&lt;br /&gt;&lt;pre&gt;firefox %u --no-remote -P browse&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Chrome is almost as easy, but &lt;a href="http://www.google.com/support/accounts/bin/answer.py?answer=179236"&gt;the doco&lt;/a&gt; can be a little harder to find.  You just need to specify a new user data directory like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;/opt/google/chrome/google-chrome --enable-udd-profiles --user-data-dir=.config/google-chrome/Browse&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and change your shortcut icon to run the same command.  &lt;br /&gt;&lt;br /&gt;On Ubuntu natty and oneiric this got harder with the new launcher.  There are a &lt;a href="http://askubuntu.com/questions/13758/how-can-i-edit-create-new-launcher-items-in-unity-by-hand/30530#30530"&gt;lot of ways to get it done&lt;/a&gt;, but this seemed the simplest to me:&lt;br /&gt;&lt;pre&gt;sudo apt-get install alacarte &lt;a href="https://bugs.launchpad.net/ubuntu/+source/alacarte/+bug/826049"&gt;gnome-panel&lt;/a&gt;&lt;br /&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;Start "Main Menu" by searching for it in the dash.&lt;/li&gt;&lt;li&gt;Add an item for your application and close the editor.&lt;/li&gt;&lt;li&gt;Logout to refresh the dash (there must be a way to do this without a logout, but not sure what it is).&lt;/li&gt;&lt;li&gt;Start the application by searching for it in the dash.&lt;/li&gt;&lt;li&gt;Right-click on the icon and "Keep in launcher"&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;I also created a couple of (ugly) custom icons to keep my '&lt;a href="http://s12.postimage.org/qdu1qsv5l/chromium_browser_browse.png"&gt;Browse&lt;/a&gt;' and '&lt;a href="http://s13.postimage.org/s2loidrzn/chromium_browser_mail.png"&gt;Mail&lt;/a&gt;' profiles clearly marked.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1176534632550132046?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1176534632550132046/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1176534632550132046' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1176534632550132046'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1176534632550132046'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/03/howto-create-multiple-chrome-and.html' title='HOWTO Create multiple chrome and firefox profiles on linux'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-3104135927236803083</id><published>2011-01-24T23:51:00.000-08:00</published><updated>2011-01-24T23:51:02.955-08:00</updated><title type='text'>HOWTO add a directory to your python path</title><content type='html'>You can add to your python path like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;import sys&lt;br /&gt;sys.path.append("/home/me/mypy") &lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-3104135927236803083?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/3104135927236803083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=3104135927236803083' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3104135927236803083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3104135927236803083'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/01/howto-add-directory-to-your-python-path.html' title='HOWTO add a directory to your python path'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-6684464186870571796</id><published>2011-01-24T23:50:00.000-08:00</published><updated>2011-11-08T15:57:36.169-08:00</updated><title type='text'>The (python) way of the future: pip and virtualenv</title><content type='html'>I recently discovered the magic of pip and virtualenv.  &lt;a href="http://pip.openplans.org/"&gt;Pip&lt;/a&gt; is shaping up as a serious contender for replacement of distutils and easy_install.  I haven't used it much yet, and will have to reserve judgement until I package a decent-sized project with pip.  &lt;br /&gt;&lt;br /&gt;Using pip is easy, although there is a bootstrapping problem that, ironically, I used easy_install to solve.  If your distro packages a recent version of pip, you can use it to skip this bit.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;sudo apt-get install python-setuptools&lt;br /&gt;s easy_install pip&lt;br /&gt;s pip install virtualenv&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This gives you a &lt;a href="http://pypi.python.org/pypi/virtualenv"&gt;virtualenv&lt;/a&gt; install.  &lt;a href="http://www.clemesha.org/blog/modern-python-hacker-tools-virtualenv-fabric-pip"&gt;Virtualenv is brilliant&lt;/a&gt;, and has significantly influenced the way I write python.  Virtualenv allows you to build a complete python environment in a directory that you 'activate' by running an in-built shell script that sets your python path environment variables.  The are many advantages to this approach, but here are a few I have encountered:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Simplified testing - test your code against multiple versions of libraries and utilities&lt;/li&gt;&lt;li&gt;Keep separate dev and production environments on your dev machine, allowing you to test in a production environment without pushing the code to your actual production server.&lt;/li&gt;&lt;li&gt;The isolation provided by Virtualenv ensures you aren't depending on libraries on your dev box that aren't installed in production, and upgrading libraries won't break other applications&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;You can even create virtual environments with different versions of the python interpreter using:&lt;br /&gt;&lt;pre&gt;virtualenv -p python2.6 2.6ENV&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So, once you have a virtualenv, activate it and install yolk to give you a picture of what is inside the environment.&lt;br /&gt;&lt;pre class="prettyprint"&gt;source .testenv/bin/activate&lt;br /&gt;~&gt; pip install yolk&lt;br /&gt;~&gt; yolk -l&lt;br /&gt;Python          - 2.6.4        - active development (/usr/lib/python2.6/lib-dynload)&lt;br /&gt;distribute      - 0.6.14       - active&lt;br /&gt;pip             - 0.8.1        - active&lt;br /&gt;wsgiref         - 0.1.2        - active development (/usr/lib/python2.6)&lt;br /&gt;yolk            - 0.4.1        - active&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then go ahead and install the other packages you need:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;pip install django&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You can also build a &lt;a href="http://pip.openplans.org/#requirements-files"&gt;requirements file&lt;/a&gt; to install exactly the same versions somewhere else:&lt;br /&gt;&lt;pre class="prettyprint"&gt;pip freeze -E .testenv &gt; requirements.txt&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The holy trinity is apparently pip, virtualenv and &lt;a href="http://docs.fabfile.org/0.9.2/"&gt;fabric&lt;/a&gt;.  Fabric is something I'll have to play with soon.  There is a good tutorial on pip and virtualenv &lt;a href="http://www.saltycrane.com/blog/2009/05/notes-using-pip-and-virtualenv-django/"&gt;here&lt;/a&gt;, and using them with django &lt;a href="http://charlesleifer.com/blog/using-virtualenv-pip-and-django-site-gen-to-quickly-start-new-django-projects/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The only limitation/problem I have run into is that you can't move the virtual environment once it is created.  There is a "--relocatable" directive to address this, but the webpage says that it is somewhat &lt;a href="http://pypi.python.org/pypi/virtualenv"&gt;experimental at the moment&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-6684464186870571796?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/6684464186870571796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=6684464186870571796' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6684464186870571796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6684464186870571796'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/01/python-way-of-future-pip-and-virtualenv.html' title='The (python) way of the future: pip and virtualenv'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-525930311514291383</id><published>2011-01-24T21:37:00.001-08:00</published><updated>2011-01-24T21:41:12.617-08:00</updated><title type='text'>Syntax highlighting code in Blogger</title><content type='html'>Posting code in Blogger by default results in something that is inexcusably ugly.&amp;nbsp; How can you make code posted in blogger look pretty?&amp;nbsp; For me, syntax highlighting and scrollable text boxes are a must.&lt;br /&gt;&lt;br /&gt;The solution is: &lt;a href="http://code.google.com/p/google-code-prettify/"&gt;google-code-prettify&lt;/a&gt;, which does the highlighting for code.google.com (you could also consider &lt;a href="http://alexgorbatchev.com/SyntaxHighlighter/"&gt;SyntaxHighlighter&lt;/a&gt;).&amp;nbsp; Now the next problem is, how do you distribute the javascript and CSS for prettify?&amp;nbsp; Unfortunately &lt;a href="http://stackoverflow.com/questions/2294240/is-there-a-content-delivery-network-cdn-that-hosts-google-code-prettify"&gt;Google doesn't make it available&lt;/a&gt; via &lt;a href="http://code.google.com/apis/libraries/devguide.html"&gt;their CDN like they do for other libraries like jQuery&lt;/a&gt;.&amp;nbsp; This would obviously be the best option for users since:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;it would negate the need for additional hosting; and&amp;nbsp;&lt;/li&gt;&lt;li&gt;minimise load time since browsers could cache the code across many sites, and if needed download it from the closest CDN node.&lt;/li&gt;&lt;/ul&gt;So the remaining options are to &lt;a href="http://pkario.blogspot.com/2010/04/blogger-code-prettifier.html"&gt;slap it into your blogger template&lt;/a&gt;, host it yourself somewhere (like Google pages), use the &lt;a href="http://stackoverflow.com/questions/1852537/how-to-use-prettify-with-blogger-blogspot"&gt;subversion browse code link&lt;/a&gt; (ick), or figure out what code.google.com does, since it uses the same code.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;I opted for the last option, which works a treat.&amp;nbsp; Put this in your blogger template, right after the &amp;lt;head&amp;gt; tag:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&amp;lt;link type=&amp;quot;text/css&amp;quot; rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;http://www.gstatic.com/codesite/ph/3799605220899551948/css/ph_core.css&amp;quot;&amp;gt;&lt;br /&gt; &lt;br /&gt;&amp;lt;link type=&amp;quot;text/css&amp;quot; rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;http://www.gstatic.com/codesite/ph/3799605220899551948/css/ph_detail.css&amp;quot; &amp;gt;&lt;br /&gt; &lt;br /&gt;&amp;lt;link type=&amp;quot;text/css&amp;quot; rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;http://www.gstatic.com/codesite/ph/3799605220899551948/css/d_sb_20080522.css&amp;quot; &amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then add an &lt;a href="http://pkario.blogspot.com/2010/04/blogger-code-prettifier.html"&gt;onload event to the body tag to call the PrettyPrint function&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&amp;lt;body onload="prettyPrint()" &amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;and, since the prettyprint CSS doesn't give you a scrolling box by default (!?), add this to the CSS in your template to avoid your code being chopped off:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;/* Override prettyprint CSS, which doesn't allow scrolling box */&lt;br /&gt;pre.prettyprint {&lt;br /&gt;  overflow: auto;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Once you have done all that, you just need to wrap the code in your posts in:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&amp;lt;pre class="prettyprint"&amp;gt;&lt;br /&gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In summary, much harder than it needs to be.  Blogger team, please build this functionality in!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-525930311514291383?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/525930311514291383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=525930311514291383' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/525930311514291383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/525930311514291383'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/01/syntax-highlighting-code-in-blogger.html' title='Syntax highlighting code in Blogger'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-6472218522762326709</id><published>2011-01-19T18:05:00.000-08:00</published><updated>2011-01-19T18:05:38.251-08:00</updated><title type='text'>List of DNS Providers</title><content type='html'>Just came across a list of DNS providers I made a while ago, and thought I'd post it here.  They all seem to still be in business.&amp;nbsp; The top three I have heard good reports about:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://www.dnsmadeeasy.com/"&gt;DNS Made Easy&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://changeip.com/"&gt;changeip.com&lt;/a&gt;&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;a href="http://zoneedit.com/"&gt;zoneedit.com &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://bur.st/"&gt;bur.st&lt;/a&gt; (non-profit based in Perth)&lt;/li&gt;&lt;li&gt;&lt;a href="http://dnspark.com/"&gt;dnspark.com&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://xname.org/"&gt;xname.org&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-6472218522762326709?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/6472218522762326709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=6472218522762326709' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6472218522762326709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6472218522762326709'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/01/list-of-dns-providers.html' title='List of DNS Providers'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-5741863590227958854</id><published>2011-01-19T17:42:00.000-08:00</published><updated>2011-01-19T17:42:35.747-08:00</updated><title type='text'>GPG HOWTO</title><content type='html'>Here is a good, &lt;a href="http://www.madboa.com/geek/gpg-quickstart/"&gt;quick intro to using GPG&lt;/a&gt;, including generating and publishing keys, encrypting and signing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-5741863590227958854?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/5741863590227958854/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=5741863590227958854' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5741863590227958854'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5741863590227958854'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/01/gpg-howto.html' title='GPG HOWTO'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-2252276044979334107</id><published>2011-01-18T22:24:00.000-08:00</published><updated>2011-01-18T22:24:27.391-08:00</updated><title type='text'>The Google Apps administrator control panel</title><content type='html'>The Google Apps administrator control panel for "your_domain.com" can be found at the fairly un-intuitive address:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;https://www.google.com/a/your_domain.com&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-2252276044979334107?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/2252276044979334107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=2252276044979334107' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2252276044979334107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2252276044979334107'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/01/google-apps-administrator-control-panel.html' title='The Google Apps administrator control panel'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-548300266202487181</id><published>2011-01-12T03:33:00.000-08:00</published><updated>2011-01-12T03:33:32.957-08:00</updated><title type='text'>Linux boot process digram</title><content type='html'>Finally got around to converting my RHCE notes on the linux boot process into a diagram.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_F9g0uOhDKzM/TS2RSXvG1GI/AAAAAAAAAB0/p1GVCG1bHMI/s1600/rhce_linux_boot_diagram.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="320" width="226" src="http://3.bp.blogspot.com/_F9g0uOhDKzM/TS2RSXvG1GI/AAAAAAAAAB0/p1GVCG1bHMI/s320/rhce_linux_boot_diagram.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-548300266202487181?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/548300266202487181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=548300266202487181' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/548300266202487181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/548300266202487181'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/01/linux-boot-process-digram.html' title='Linux boot process digram'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_F9g0uOhDKzM/TS2RSXvG1GI/AAAAAAAAAB0/p1GVCG1bHMI/s72-c/rhce_linux_boot_diagram.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1661348686772826032</id><published>2011-01-05T21:21:00.000-08:00</published><updated>2011-01-05T21:21:09.706-08:00</updated><title type='text'>Creating a HTML DIV that adjusts its size to automatically fit the content</title><content type='html'>To create a div that automatically adjusts its size to fit the content, use this in your CSS:&lt;br /&gt;&lt;pre&gt;margin: 0 auto;&lt;br /&gt;&lt;/pre&gt;Using 'margin' for this purpose doesn't seem particularly intuitive to me, and isn't mentioned in CSS doco I read, but it works.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1661348686772826032?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1661348686772826032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1661348686772826032' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1661348686772826032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1661348686772826032'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/01/creating-html-div-that-adjusts-its-size.html' title='Creating a HTML DIV that adjusts its size to automatically fit the content'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-5245934849464270503</id><published>2011-01-05T14:49:00.001-08:00</published><updated>2011-01-05T15:00:55.137-08:00</updated><title type='text'>Rendering a django queryset as a html table (like form.as_table) using a custom template filter</title><content type='html'>Django has some nice helpers for forms (&lt;a href="http://docs.djangoproject.com/en/dev/topics/forms/#displaying-a-form-using-a-template"&gt;forms.as_p and forms.as_table&lt;/a&gt;) that you can use in your template to minimise boilerplate HTML.  Unfortunately, despite &lt;a href="http://thedjangoforum.com/board/thread/409/as_table-for-normal-objects/"&gt;some&lt;/a&gt; &lt;a href="http://efreedom.com/Question/1-2283611/Output-Django-Model-Table"&gt;discussion/confusion&lt;/a&gt;, and at least &lt;a href="https://github.com/miracle2k/django-tables"&gt;one project&lt;/a&gt;, there doesn't appear to be a similar elegant solution for querysets.&lt;br /&gt;&lt;br /&gt;My approach to the problem was to implement a custom &lt;a href="http://docs.djangoproject.com/en/dev/ref/templates/builtins/"&gt;template filter&lt;/a&gt; you can use in a template like this (where object_list is your queryset):&lt;br /&gt;&lt;pre&gt;{{ object_list|result_as_table }}&lt;br /&gt;&lt;/pre&gt;i.e. you hand it a queryset, and it gives you back a table.&lt;br /&gt;&lt;br /&gt;Here is the code for the filter.  I'm using this for a number of subclasses of a class called resultdata, so that they can share an identical template and just provide different querysets in urls.py.  &lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;def result_as_table(queryset, fieldnames=None):&lt;br /&gt;    &amp;quot;&amp;quot;&amp;quot;Take a resultdata queryset and return it as a HTML table.&lt;br /&gt;    Columns will be returned in the order they are declared in the model.&lt;br /&gt;    &lt;br /&gt;    Optionally, provide a list of fieldnames, which will be used to limit the output.&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    dictlist = queryset.values()&lt;br /&gt;    output = &amp;quot;&amp;lt;table&amp;gt;\n&amp;quot;&lt;br /&gt;    output_keys = []&lt;br /&gt;&lt;br /&gt;    if fieldnames:&lt;br /&gt;        names = fieldnames&lt;br /&gt;    else:&lt;br /&gt;        names = dictlist.field_names&lt;br /&gt;&lt;br /&gt;    for name in names:&lt;br /&gt;&lt;br /&gt;        if not name.endswith(&amp;quot;_id&amp;quot;):&lt;br /&gt;            output_keys.append(name)&lt;br /&gt;            output = &amp;quot;&amp;quot;.join( (output, &amp;quot;&amp;lt;th&amp;gt;%s&amp;lt;/th&amp;gt;\n&amp;quot; % escape(name.replace(&amp;quot;_&amp;quot;,&amp;quot; &amp;quot;).capitalize())) )&lt;br /&gt;&lt;br /&gt;    for rddict in dictlist:&lt;br /&gt;&lt;br /&gt;        output = &amp;quot;&amp;quot;.join( (output, &amp;quot;&amp;lt;tr&amp;gt;\n&amp;quot;) )&lt;br /&gt;&lt;br /&gt;        for key in output_keys:&lt;br /&gt;            val = rddict[key]&lt;br /&gt;            if not key.endswith(&amp;quot;_id&amp;quot;):&lt;br /&gt;&lt;br /&gt;                display_func = get_display_method(rddict, queryset, key)&lt;br /&gt;&lt;br /&gt;                if display_func:&lt;br /&gt;                    output = &amp;quot;&amp;quot;.join( (output, &amp;quot;&amp;lt;td&amp;gt;%s&amp;lt;/td&amp;gt;\n&amp;quot; % escape(display_func())) )&lt;br /&gt;                else:&lt;br /&gt;                    output = &amp;quot;&amp;quot;.join( (output, &amp;quot;&amp;lt;td&amp;gt;%s&amp;lt;/td&amp;gt;\n&amp;quot; % escape(val)) )&lt;br /&gt;&lt;br /&gt;        output = &amp;quot;&amp;quot;.join( (output, &amp;quot;&amp;lt;/tr&amp;gt;\n&amp;quot;) )&lt;br /&gt;&lt;br /&gt;    return mark_safe(&amp;quot;&amp;quot;.join( (output, &amp;quot;&amp;lt;/table&amp;gt;\n&amp;quot;) ))&lt;br /&gt;&lt;br /&gt;result_as_table.is_safe = True&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This filter introspects the column headers, strips out any id fields (since users don't care about them), converts underscores to spaces in column headers, and finds the corresponding display methods for any &lt;a href="http://www.djangoproject.com/documentation/models/choices/"&gt;'choices' fields&lt;/a&gt; so you can still get the nice human-readable output.  It outputs HTML, so it uses django's own 'django.utils.html.escape' method and marks the output as safe so django doesn't escape all the HTML.&lt;br /&gt;&lt;br /&gt;Finding the display methods was a little harder than I expected, since the python inspect code was dying when given a django model object.  This code is unfortunately tied to the resultdata object due to the naming of the keys in the values() dictionary, making it less generic than I would like.&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;def get_display_method(rddict, queryset, key):&lt;br /&gt;    """Re-implementation of inspect.getmembers(rddict,inspect.ismethod) and &lt;br /&gt;    a test to see if this is a get_field_status method.  Had to reimplement inspect&lt;br /&gt;    because it was bombing on the object - expecting some property that is not present."""&lt;br /&gt;&lt;br /&gt;    rdobj = queryset[0].__class__.objects.filter(resultdata_id = rddict["resultdata_id"]).get()&lt;br /&gt;    targetname = "get_%s_display" % key&lt;br /&gt;    display_func = False&lt;br /&gt;&lt;br /&gt;    for name in dir(rdobj):&lt;br /&gt;        if name == targetname:&lt;br /&gt;            try:&lt;br /&gt;                display_func = getattr(rdobj, name)&lt;br /&gt;                break&lt;br /&gt;            except Exception,e:&lt;br /&gt;                pass&lt;br /&gt;&lt;br /&gt;    return display_func&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There was a major gotcha with using the field_names property of the queryset.values() dictionary.  If you passed a queryset with annotations like this is your urls.py:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;list_rd = {&lt;br /&gt;    'extra_context': {'fieldnames': ['status','first','total']},&lt;br /&gt;    'queryset': ResultData.objects.annotate(total = Count('link__clickback'), &lt;br /&gt;                                            first = Min('link__clickback__timestamp')),&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;urlpatterns += patterns('project.app.views',&lt;br /&gt;    url(r'^result/detail/$', 'detailed_results', kwargs=list_rd, name='detailed_results'),&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The annotations would not get added into the field_names property.  This was solved by providing the optional fieldnames parameter.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-5245934849464270503?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/5245934849464270503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=5245934849464270503' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5245934849464270503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5245934849464270503'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2011/01/rendering-django-queryset-as-html-table.html' title='Rendering a django queryset as a html table (like form.as_table) using a custom template filter'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-4182229257142153186</id><published>2010-12-22T16:29:00.000-08:00</published><updated>2010-12-22T16:29:50.880-08:00</updated><title type='text'>HOWTO add headers to the Django test client</title><content type='html'>To mess with the HTTP headers used by the Django web test client, make your request with your custom headers in a dict. From inside a django test method it looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;self.client.get('/some/path/', **{'HTTP_USER_AGENT':'silly-human', 'REMOTE_ADDR':'127.0.0.1'})&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-4182229257142153186?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/4182229257142153186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=4182229257142153186' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4182229257142153186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4182229257142153186'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/12/howto-add-headers-to-django-test-client.html' title='HOWTO add headers to the Django test client'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-2129573052493888137</id><published>2010-12-17T17:43:00.003-08:00</published><updated>2010-12-17T17:44:16.866-08:00</updated><title type='text'>Import multiple vcf files into gmail</title><content type='html'>You can import contacts into gmail - it currently accepts csv files or vcf files.  Unfortunately you can only upload one file at a time.  If you are trying to import a full phone backup of hundreds of vcf files, that isn't useful.  It turns out vcf's have their own internal structure and you can just combine them all into one giant file (using cat on linux):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;cat *.vcf &gt; ../allinone.vcf&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-2129573052493888137?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/2129573052493888137/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=2129573052493888137' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2129573052493888137'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2129573052493888137'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/12/import-multiple-vcf-files-into-gmail.html' title='Import multiple vcf files into gmail'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1886240997009645585</id><published>2010-12-12T20:53:00.000-08:00</published><updated>2010-12-12T20:53:32.064-08:00</updated><title type='text'>HOWTO: Convert a darcs repository to mercurial</title><content type='html'>It seems the "easiest" way to convert a darcs repo to a mercurial repo is via git =( This uses &lt;a href="http://vmiklos.hu/project/darcs-fast-export/"&gt;darcs-fast-export&lt;/a&gt;, git-fast-import and hg convert. Other solutions such as &lt;a href="http://mercurial.selenic.com/wiki/Tailor"&gt;tailor&lt;/a&gt; and "darcs2hg.py" exist but seem hard(er) to setup or have errors.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Get darcs fast-export from bzr-fast-import:&lt;br /&gt;&lt;pre&gt;git clone git://vmiklos.hu/bzr-fastimport&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;The only thing you care about in the entire bzr-fast-import repo is "darcs-fast-export" (a python script) in bzr-fastimport/exporters/darcs.&lt;/li&gt;&lt;li&gt;Checkout the darcs project&lt;br /&gt;&lt;pre&gt;mkdir project; cd project; darcs get codebox:/code/project project.darcs; cd .. &lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Convert darcs to git (in Ubuntu karmic git-fast-import isn't in PATH)&lt;br /&gt;&lt;pre&gt;mkdir project/project.git; cd project/project.git; git init&lt;br /&gt;../../darcs-fast-export.py ../project.darcs | /usr/lib/git-core/git-fast-import; cd .. &lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Convert git to hg&lt;br /&gt;&lt;pre&gt;hg convert project.git project.hg; cd project.hg; hg update&lt;br /&gt;&lt;/pre&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1886240997009645585?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1886240997009645585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1886240997009645585' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1886240997009645585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1886240997009645585'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/12/howto-convert-darcs-repository-to.html' title='HOWTO: Convert a darcs repository to mercurial'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-9159828494335275391</id><published>2010-12-08T21:21:00.000-08:00</published><updated>2010-12-08T21:21:16.051-08:00</updated><title type='text'>Generate SSL certificates for openvpn with easy-rsa</title><content type='html'>Easy-rsa is distributed with openvpn (on Ubuntu anyway), and makes generating SSL certs a lot easier.&lt;br /&gt;&lt;br /&gt;Here is typical usage:&lt;br /&gt;&lt;pre class="prettyprint"&gt;cd /usr/share/doc/openvpn/examples/easy-rsa/2.0&lt;br /&gt;[edit vars with your site-specific info]&lt;br /&gt;source ./vars&lt;br /&gt;./clean-all&lt;br /&gt;./build-dh     -&gt; takes a long time, consider backgrounding&lt;br /&gt;./pkitool --initca&lt;br /&gt;./pkitool --server myserver&lt;br /&gt;./pkitool client1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Keys and certs are written to the "keys" directory.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-9159828494335275391?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/9159828494335275391/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=9159828494335275391' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/9159828494335275391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/9159828494335275391'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/12/generate-ssl-certificates-for-openvpn.html' title='Generate SSL certificates for openvpn with easy-rsa'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-6850061510393849937</id><published>2010-12-07T01:34:00.000-08:00</published><updated>2010-12-07T01:34:00.906-08:00</updated><title type='text'>HOWTO rotate large numbers of images in Ubuntu</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_F9g0uOhDKzM/TP3-8iY4XWI/AAAAAAAAABk/b18RgzZErcg/s1600/rotate+image+dialog.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="165" src="http://3.bp.blogspot.com/_F9g0uOhDKzM/TP3-8iY4XWI/AAAAAAAAABk/b18RgzZErcg/s200/rotate+image+dialog.png" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;I needed a way for my wife to rotate a whole bunch of JPEG images.&amp;nbsp; It had to be simple to use (i.e. GUI not command line).&lt;br /&gt;&lt;br /&gt;I stumbled across a blog that suggested the nautilus-image-converter plugin, which worked perfectly.  It has a simple right-click interface that allows you to rotate images in place or use a renaming scheme.  It can also do resizing.&lt;br /&gt;&lt;br /&gt;Brilliant.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-6850061510393849937?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/6850061510393849937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=6850061510393849937' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6850061510393849937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6850061510393849937'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/12/howto-rotate-large-numbers-of-images-in.html' title='HOWTO rotate large numbers of images in Ubuntu'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_F9g0uOhDKzM/TP3-8iY4XWI/AAAAAAAAABk/b18RgzZErcg/s72-c/rotate+image+dialog.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-3579869425098930708</id><published>2010-12-02T21:27:00.000-08:00</published><updated>2010-12-02T21:27:20.454-08:00</updated><title type='text'>Apache and client side SSL certificate verification</title><content type='html'>To require client SSL certificate verification, add this to your apache config:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;SSLVerifyClient require&lt;br /&gt;SSLVerifyDepth 1&lt;br /&gt;SSLCipherSuite HIGH:MEDIUM&lt;br /&gt;SSLCACertificateFile /etc/ssl/ca_that_signed_client_certs.pem&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And to log what is going on with the SSL client cert verification, use something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;ErrorLog /var/log/apache2/error.log&lt;br /&gt;LogLevel info&lt;br /&gt;&lt;br /&gt;CustomLog /var/log/apache2/access.log combined&lt;br /&gt;&lt;br /&gt;CustomLog /var/log/apache2/ssl.log "%t %h %{SSL_PROTOCOL}x verify:%{SSL_CLIENT_VERIFY}x %{SSL_CLIENT_S_DN}x \"%r\" %b"&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-3579869425098930708?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/3579869425098930708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=3579869425098930708' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3579869425098930708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3579869425098930708'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/12/apache-and-client-side-ssl-certificate.html' title='Apache and client side SSL certificate verification'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-8365522439585035213</id><published>2010-11-30T21:13:00.000-08:00</published><updated>2010-11-30T21:13:58.990-08:00</updated><title type='text'>Commercial SSL certificate untrusted - what did I pay for?</title><content type='html'>I recently bought a commercial SSL certificate, and was slightly mystified as to why the browser was calling it untrusted.  How could they possibly be selling certs that Firefox doesn't trust?  After some head scratching I realised the answer was that I needed to install the intermediate certificates (provided by the CA) on the &lt;i&gt;server side&lt;/i&gt;, to complete the chain of trust.&lt;br /&gt;&lt;br /&gt;During the SSL certificate exchange the web server (in this case Apache) can provide the client with additional certificates to enable it to establish a chain of trust.&amp;nbsp; Use the &lt;a href="http://httpd.apache.org/docs/2.0/mod/mod_ssl.html#sslcertificatechainfile"&gt;SSLCertificateChainFile&lt;/a&gt; directive in your site config, something like:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;    SSLCertificateChainFile /etc/apache2/ssl/ExternalCARoot1.crt&lt;br /&gt;    SSLCertificateChainFile /etc/apache2/ssl/CACompanySecureServerCA.crt&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;According to the &lt;a href="http://httpd.apache.org/docs/2.0/mod/mod_ssl.html#sslcertificatechainfile"&gt;apache help&lt;/a&gt;, you can cat these two together and just specify one file.&amp;nbsp; Say the browser trusts RootCA1, it can check that RootCA1 signed ExternalCARoot1.crt, which signed CACompanySecureServerCA.crt, which signed my certificate.  Without those intermediate certificates, the browser cannot establish trust.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-8365522439585035213?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/8365522439585035213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=8365522439585035213' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/8365522439585035213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/8365522439585035213'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/12/commercial-ssl-certificate-untrusted.html' title='Commercial SSL certificate untrusted - what did I pay for?'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-7886740316767515759</id><published>2010-11-27T03:29:00.000-08:00</published><updated>2010-11-27T03:29:47.453-08:00</updated><title type='text'>Making blogger look prettyish: removing the attribution footer and increasing the post width</title><content type='html'>The new templates provided by blogger go a long way to making it look prettier.  There are IMHO a few fundamental problems.  The first is the attribution footer gadget - that is nice for the original designer, but I don't need to advertise for them on my blog.  A lot of people seem to be &lt;a href="http://blogger-hints-and-tips.blogspot.com/2010/04/removing-attribution-gadget-from.html"&gt;trying to change this behaviour&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To remove the attribution footer, search in your css for 'attribution' and use html comments to comment out those sections.  Check with preview to see if they are gone.  When you click 'save template' blogger will ask if you want to delete the attribution gadget.  You can delete it, and it will stay gone.&lt;br /&gt;&lt;br /&gt;Next, making the post wider.  Blogger is stuck being optimised for small screen sizes no-one uses any more.  To increase the post width, change the 'value' attribute of this tag (search for 'content.width'):&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;b:variable default='930px' name='content.width' type='length' value='1000px'/&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;And to change the width of your gadget panel, change value of:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;b:variable default='360px' name='main.column.right.width' type='length' value='370px'/&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-7886740316767515759?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/7886740316767515759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=7886740316767515759' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7886740316767515759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7886740316767515759'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/11/making-blogger-look-prettyish-removing.html' title='Making blogger look prettyish: removing the attribution footer and increasing the post width'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-1779728878800320557</id><published>2010-11-24T21:20:00.001-08:00</published><updated>2011-01-18T17:43:07.152-08:00</updated><title type='text'>Set file modification time of a JPEG to the EXIF time</title><content type='html'>After editing a photo, it is nice to be able to set the file modification time back to its original so filesystem date sorting is still sensible.  This can be achieved by reading the "Exif.Photo.DateTimeOriginal" or "Exif.Image.DateTime" out of the JPEG header.  &lt;i&gt;exiv2&lt;/i&gt; will do this for you:&lt;br /&gt;&lt;pre&gt;exiv2 -T rename *.JPG&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To do every file recursively under a directory, cd into the directory and use this:&lt;br /&gt;&lt;pre&gt;find . -type f -iname "*.jpg" -print0 | xargs -0 exiv2 -T rename&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-1779728878800320557?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/1779728878800320557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=1779728878800320557' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1779728878800320557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/1779728878800320557'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/11/set-file-modification-time-of-jpeg-to.html' title='Set file modification time of a JPEG to the EXIF time'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-3296076243476519485</id><published>2010-10-04T23:06:00.000-07:00</published><updated>2010-10-04T23:06:06.102-07:00</updated><title type='text'>HOWTO do a DNS zone transfer</title><content type='html'>Use dig to get a list of nameservers and then perform a DNS zone transfer:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;dig -t NS transfer.me.com&lt;br /&gt;dig -t AXFR transfer.me.com @ns1.transfer.me.com&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-3296076243476519485?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/3296076243476519485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=3296076243476519485' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3296076243476519485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3296076243476519485'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/10/howto-do-dns-zone-transfer.html' title='HOWTO do a DNS zone transfer'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-498806153745199089</id><published>2010-09-27T06:26:00.000-07:00</published><updated>2010-09-27T06:26:19.144-07:00</updated><title type='text'>World meeting time planner</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_F9g0uOhDKzM/TKCarjFzYaI/AAAAAAAAAA8/nKzojCnqM6o/s1600/ZonesWindow_Screenshot.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://2.bp.blogspot.com/_F9g0uOhDKzM/TKCarjFzYaI/AAAAAAAAAA8/nKzojCnqM6o/s640/ZonesWindow_Screenshot.png" width="196" /&gt;&lt;/a&gt;&lt;/div&gt;Planning a meeting or phonecall across multiple timezones can be tough.&lt;br /&gt;&lt;br /&gt;I've used a few &lt;a href="http://www.timeanddate.com/worldclock/meeting.html"&gt;online tools&lt;/a&gt;, but my current favourite is a gnome app called &lt;a href="http://blogs.operationaldynamics.com/andrew/software/slashtime/slashtime-the-graphical-version.html"&gt;slashtime&lt;/a&gt; by Andrew Cowie.  I saw Andrew speak at Linux Conf Au in 2009 on GUI design, using slashtime as an example, and it was a great talk.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Highly recommend.&amp;nbsp; Would be great to see a debian package so it is apt-gettable.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-498806153745199089?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/498806153745199089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=498806153745199089' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/498806153745199089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/498806153745199089'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/09/world-meeting-time-planner.html' title='World meeting time planner'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_F9g0uOhDKzM/TKCarjFzYaI/AAAAAAAAAA8/nKzojCnqM6o/s72-c/ZonesWindow_Screenshot.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-6226596278080751646</id><published>2010-09-19T20:11:00.003-07:00</published><updated>2010-09-23T16:33:07.153-07:00</updated><title type='text'>HOWTO list windows shares from a linux box using smbclient</title><content type='html'>To get a list of all SMB shares exposed by a windows box, use smbclient:&lt;br /&gt;&lt;pre class="prettyprint"&gt;smbclient -L my.windows.host --user=myfirst.mylast&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-6226596278080751646?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/6226596278080751646/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=6226596278080751646' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6226596278080751646'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/6226596278080751646'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/09/howto-list-windows-shares-from-linux.html' title='HOWTO list windows shares from a linux box using smbclient'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-7917762907116381672</id><published>2010-09-17T02:44:00.000-07:00</published><updated>2010-09-17T02:44:35.641-07:00</updated><title type='text'>jQuery: host locally or use googleapis.com CDN?</title><content type='html'>There are two main ways to host your blob of jQuery minimised javascript: on your own webserver or, on &lt;a href="http://code.google.com/apis/libraries/devguide.html"&gt;Google's&lt;/a&gt;.  Which is better?  A &lt;a href="http://stackoverflow.com/questions/208869/what-are-advantages-of-using-google-loadjquery-vs-direct-inclusion-of-ho"&gt;large amount&lt;/a&gt; of &lt;a href="http://encosia.com/2008/12/10/3-reasons-why-you-should-let-google-host-jquery-for-you/"&gt;time has been spent&lt;/a&gt; debating &lt;a href="http://paulirish.com/2009/caching-and-googles-ajax-libraries-api/"&gt;that very topic&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;What are the pros and cons of using Google?&lt;br /&gt;&lt;h4&gt;Pros&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;Fast, geographically distributed, reliable CDN&lt;/li&gt;&lt;li&gt;Free, saves using your bandwidth&lt;/li&gt;&lt;li&gt;If many people use the Google version of jQuery (and they do), it is highly likely the user will have it in their browser cache, given the long expiry times Google sets when they serve the file (although there are &lt;a href="http://paulirish.com/2009/caching-and-googles-ajax-libraries-api/"&gt;some caveats&lt;/a&gt;&lt;a href="http://paulirish.com/2009/caching-and-googles-ajax-libraries-api/"&gt;&lt;/a&gt;).&amp;nbsp; This means the user probably won't have to request the file at all.&amp;nbsp; Even if users regularly clear their browser cache it is likely to be cached by a proxy.&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;Cons&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;The CDN might be down, or slow, which will impact your site.&lt;/li&gt;&lt;li&gt;If there is no Internet connection it won't work (definitely not the best choice for internal webservers)&lt;/li&gt;&lt;li&gt;If you already have other javascript bundled into a minimised file (common practice), it is an extra web request that needs to be made, when you could just include it in the bundle.&lt;/li&gt;&lt;li&gt;You are giving Google information about your customers (i.e. forcing them to make a request) to Google.&amp;nbsp; Given the large amount of caching, this will not be comprehensive, and there is a reasonable chance you are running Google analytics anyway.&amp;nbsp; &lt;/li&gt;&lt;/ul&gt;On balance, I think using Google's version is the better option.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-7917762907116381672?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/7917762907116381672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=7917762907116381672' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7917762907116381672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/7917762907116381672'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/09/jquery-host-locally-or-use.html' title='jQuery: host locally or use googleapis.com CDN?'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-3642389396948598143</id><published>2010-09-17T02:22:00.001-07:00</published><updated>2010-09-23T16:34:26.987-07:00</updated><title type='text'>Using the django-admin time and date widgets in your own django app: too hard, use jQuery</title><content type='html'>The &lt;a href="http://docs.djangoproject.com/en/dev/topics/forms/media/"&gt;django doco&lt;/a&gt; encourages you to use the django admin widgets (such as the time and date picker) in your own apps.  Unfortunately actually doing this &lt;a href="http://stackoverflow.com/questions/38601/using-django-time-date-widgets-in-custom-form/2818128#2818128"&gt;turns out to be more work&lt;/a&gt; than using external widgets like the excellent &lt;a href="http://jqueryui.com/demos/datepicker/"&gt;jQuery-ui&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;jQuery comes with good &lt;a href="http://www.authenticsociety.com/blog/jQueryPluginTutorial_Beginner"&gt;tutorials&lt;/a&gt; and doco.  jQuery-ui, which builds on jQuery, has a &lt;a href="http://jqueryui.com/docs/Getting_Started"&gt;great array of helpful widgets&lt;/a&gt;.  If, like me, you just want a &lt;a href="http://docs.jquery.com/UI/Datepicker"&gt;date picker widget&lt;/a&gt;, it is super easy.&lt;br /&gt;&lt;br /&gt;You'll want to add something like the following to your template (in your base template if it will be used on every page):&lt;br /&gt;&lt;pre class="prettyprint"&gt;&amp;lt;script src=&amp;quot;http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script src=&amp;quot;http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.5/jquery-ui.min.js&amp;quot; type=&amp;quot;text/javascript&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;  jQuery(function()&lt;br /&gt;    {&lt;br /&gt;      jQuery(&amp;#39;.vDateField&amp;#39;).datepicker({ &lt;br /&gt;          dateFormat: &amp;#39;yy-mm-dd&amp;#39;,&lt;br /&gt;          constrainInput: &amp;#39;true&amp;#39;, &lt;br /&gt;          maxDate: &amp;#39; 1m&amp;#39;,&lt;br /&gt;          minDate: &amp;#39;0d&amp;#39; })&lt;br /&gt;    });&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;To make it look pretty jQuery has you covered, with &lt;a href="http://jqueryui.com/themeroller/"&gt;ThemeRoller&lt;/a&gt;.  Pick a style you like, customise it if you need to, and download your new CSS.  Drop that in your template too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-3642389396948598143?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/3642389396948598143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=3642389396948598143' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3642389396948598143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3642389396948598143'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/09/using-django-admin-time-and-date.html' title='Using the django-admin time and date widgets in your own django app: too hard, use jQuery'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-2419090191603907079</id><published>2010-09-14T00:18:00.000-07:00</published><updated>2010-09-14T00:18:57.710-07:00</updated><title type='text'>Taking a disk image and creating a hash of the data with one read of the source disk</title><content type='html'>I have previously blogged about how to &lt;a href="http://ilostmynotes.blogspot.com/2010/02/copying-compressed-disk-image-across.html"&gt;take a disk image over the network&lt;/a&gt;.  The more common case is you want to make a forensic copy of a locally-connected disk.  Usually this is a disk you connect using a write blocker, such as one from &lt;a href="http://www.wiebetech.com"&gt;wiebetech&lt;/a&gt;, to prevent any changes being made to the source disk.&lt;br /&gt;&lt;br /&gt;This command takes a forensic image and a hash of the original disk at the same time, requiring only one read of the source disk:&lt;br /&gt;&lt;pre&gt;mkfifo /tmp/disk.dat; sha1sum /tmp/disk.dat &amp; dd bs=256k if=/dev/sdc | tee /tmp/disk.dat &gt; /mnt/destination/disk.dd&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-2419090191603907079?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/2419090191603907079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=2419090191603907079' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2419090191603907079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/2419090191603907079'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/09/taking-disk-image-and-creating-hash-of.html' title='Taking a disk image and creating a hash of the data with one read of the source disk'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-917779730972134790</id><published>2010-09-13T18:31:00.000-07:00</published><updated>2010-09-13T18:31:52.807-07:00</updated><title type='text'>Chrome (chromium) browser makes random 10 character HEAD requests on startup</title><content type='html'>I recently saw this in a proxy log:&lt;br /&gt;&lt;pre&gt;http://yyvssjupua/ 192.168.20.1/- - HEAD - from squid.&lt;br /&gt;http://mskwuzkkpu/ 192.168.20.1/- - HEAD - from squid.&lt;br /&gt;http://dfoigxiyyl/ 192.168.20.1/- - HEAD - from squid.&lt;br /&gt;&lt;/pre&gt;What the?  After talking to the user, who told me he was running chromium, I found out this was &lt;a href="http://groups.google.com/a/chromium.org/group/chromium-discuss/browse_thread/thread/17bd3e93f3c68448/5891e258e6015fc5?show_docid=5891e258e6015fc5"&gt;legit chromium behaviour&lt;/a&gt;.  Apparently some ISPs will send you to a page with their advertising if you visit a url that has a DNS lookup failure.  Bastards.  To combat this, on startup chrome makes three requests to random domains that are guaranteed to generate lookup failures.  If they get a HTML page back, chrome knows to disable the 'did you mean' functionality that asks if you meant to visit the host or perform a search query for the host so it doesn't keep pointing you to the ISP's ad page.  Smart!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-917779730972134790?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/917779730972134790/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=917779730972134790' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/917779730972134790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/917779730972134790'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/09/chrome-chromium-browser-makes-random-10.html' title='Chrome (chromium) browser makes random 10 character HEAD requests on startup'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-5240270118868029173</id><published>2010-09-11T19:04:00.001-07:00</published><updated>2010-09-23T16:36:53.713-07:00</updated><title type='text'>Cisco 'show everything' and password cracking</title><content type='html'>To do a 'show everything' on a cisco device, use 'show tech-support'.  This includes show run, process listings, interface info, and basically &lt;a href="http://training.teksystems.com/blog/cisco-show-tech-support-command-36.post"&gt;every bit of information&lt;/a&gt; you can get through running other commands.  Note that user type 7 passwords (see below) are automatically sanitised from the output.&lt;br /&gt;&lt;br /&gt;Cisco still uses a &lt;a href="http://www.cisco.com/en/US/tech/tk59/technologies_tech_note09186a00809d38a7.shtml"&gt;terrible password encryption scheme&lt;/a&gt; for user passwords that can be &lt;a href="http://www.tech-faq.com/decrypt-cisco-passwords.html"&gt;trivially cracked&lt;/a&gt;.  The following user password uses the weak encryption (you can tell by the number 7 preceeding the hash):&lt;br /&gt;&lt;pre&gt;username jdoe password 7 07362E590E1B1C041B1E124C0A2F2E206832752E1A01134D&lt;br /&gt;&lt;/pre&gt;While user passwords are encrypted using this weak scheme, enable passwords are MD5 hashes that look like this (note the 5):&lt;br /&gt;&lt;pre&gt;enable secret 5 $1$iUjJ$cDZ03KKGh7mHfX2RSbDqP.&lt;br /&gt;&lt;/pre&gt;Cisco is stuck using the reversible encryption scheme for the near future &lt;a href="http://www.cisco.com/en/US/tech/tk59/technologies_tech_note09186a00809d38a7.shtml"&gt;due to the need to support certain authentication protocols&lt;/a&gt; (notably CHAP).&lt;br /&gt;&lt;br /&gt;Enable (MD5) passwords can be cracked using standard tools such as &lt;a href="http://www.soldierx.com/tutorials/Using-John-Crack-Cisco-md5"&gt;John the Ripper&lt;/a&gt; or rainbow tables.&lt;br /&gt;&lt;br /&gt;Type 7 passwords can be cracked with the following simple perl script.&lt;br /&gt;&lt;pre class="prettyprint"&gt;#!/usr/bin/perl -w&lt;br /&gt;# $Id: ios7decrypt.pl,v 1.1 1998/01/11 21:31:12 mesrik Exp $&lt;br /&gt;#&lt;br /&gt;# Credits for orginal code and description hobbit@avian.org,&lt;br /&gt;# SPHiXe, .mudge et al. and for John Bashinski &lt;jbash@CISCO.COM&gt;&lt;br /&gt;# for Cisco IOS password encryption facts.&lt;br /&gt;#&lt;br /&gt;# Use for any malice or illegal purposes strictly prohibited!&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;@xlat = ( 0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f, 0x41,&lt;br /&gt;0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72, 0x6b, 0x6c,&lt;br /&gt;0x64, 0x4a, 0x4b, 0x44, 0x48, 0x53, 0x55, 0x42 );&lt;br /&gt;while (&lt;&gt;) {&lt;br /&gt;  if (/(password|md5)\s+7\s+([\da-f]+)/io) {&lt;br /&gt;    if (!(length($2) &amp; 1)) {&lt;br /&gt;      $ep = $2; $dp = "";&lt;br /&gt;      ($s, $e) = ($2 =~ /^(..)(.+)/o);&lt;br /&gt;      for ($i = 0; $i &lt; length($e); $i+=2) {&lt;br /&gt;        $dp .= sprintf "%c",hex(substr($e,$i,2))^$xlat[$s++];&lt;br /&gt;      }&lt;br /&gt;      s/7\s+$ep/$dp/;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  print;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-5240270118868029173?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/5240270118868029173/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=5240270118868029173' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5240270118868029173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5240270118868029173'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/09/cisco-show-everything-and-password.html' title='Cisco &apos;show everything&apos; and password cracking'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-4390418555470885557</id><published>2010-09-11T18:31:00.000-07:00</published><updated>2010-09-11T18:31:42.124-07:00</updated><title type='text'>Booting and/or mounting a raw disk image under windows</title><content type='html'>&lt;a href="http://www.cert.org/"&gt;CERT&lt;/a&gt; has developed a cool tool called &lt;a href="http://liveview.sourceforge.net/"&gt;LiveView&lt;/a&gt; that allows you to boot a raw disk image (such as one produced by 'dd') using VMWare.  LiveView preserves disk integrity by writing all disk changes to a separate file.  The tool works under windows and linux, and boots a range of Windows versions.&lt;br /&gt;&lt;br /&gt;Alternatively, if you just want to mount a disk image in windows (something that is trivial in linux using the loopback device), there is a &lt;a href="http://www.ltr-data.se/opencode.html#ImDisk"&gt;tool&lt;/a&gt; called &lt;a href="http://www.ltr-data.se/files/imdiskinst.exe"&gt;imdiskinst&lt;/a&gt; that can help you out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-4390418555470885557?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/4390418555470885557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=4390418555470885557' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4390418555470885557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/4390418555470885557'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/09/booting-andor-mounting-raw-disk-image.html' title='Booting and/or mounting a raw disk image under windows'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-3346104752709966733</id><published>2010-09-09T23:21:00.001-07:00</published><updated>2010-09-09T23:21:30.435-07:00</updated><title type='text'>HOWTO dump out all email attachments from a Microsoft PST archive</title><content type='html'>On ubuntu install 'readpst' and 'uudeview', then:&lt;br /&gt;&lt;pre&gt;readpst -o mbox -j4 mpst.pst&lt;br /&gt;&lt;/pre&gt;Which will use 4 processes to give you a bunch of mbox files in the 'mbox' directory.  Then, extract all the attachments:&lt;br /&gt;&lt;pre&gt;cd mbox&lt;br /&gt;uudeview -p ../pst_attachments *&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-3346104752709966733?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/3346104752709966733/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=3346104752709966733' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3346104752709966733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3346104752709966733'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/09/howto-dump-out-all-email-attachments.html' title='HOWTO dump out all email attachments from a Microsoft PST archive'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-8594504579700845540</id><published>2010-08-25T05:20:00.001-07:00</published><updated>2010-08-26T03:32:28.160-07:00</updated><title type='text'>Where there is awk, there is sed</title><content type='html'>I couldn't do a post on awk without also quickly covering sed.  Bruce Barnett has written &lt;a href="http://www.grymoire.com/Unix/Sed.html"&gt;a great tutorial for sed&lt;/a&gt; that is worth reading.&lt;br /&gt;&lt;br /&gt;Sed is your friend for applying regex's to files (well, streams really, since it is the 'stream editor').  The regex syntax is the same as for vim, and since that is my primary editor I only tend to use sed where the files are large and will take ages to load into vim.&lt;br /&gt;&lt;br /&gt;Some quick examples to illustrate what I'm talking about:&lt;br /&gt;&lt;pre&gt;sed s'/user root/user nothingtoseehere/g' &lt; /var/log/auth.log&lt;br /&gt;&lt;br /&gt;sed s'!session closed for user \([^ ]*\)!\1 closed a session!g' &lt; \&lt;br /&gt;/var/log/auth.log&lt;br /&gt;&lt;br /&gt;sed s'!session closed for user \([^ ]*\)!&amp;, allegedly!g' &lt; \&lt;br /&gt;/var/log/auth.log&lt;br /&gt;&lt;/pre&gt;Escaped parenthesis &lt;pre&gt;\(\)&lt;/pre&gt;capture a value, and &lt;pre&gt;&amp;&lt;/pre&gt;refers to the whole match.You can also use sed like grep.  By default it prints every line, but that can be disabled with "-n" and you can cause matching lines to be printed by appending a "p" option:&lt;pre&gt;sed -n 's/pattern/&amp;/p' &lt; file.txt&lt;br /&gt;&lt;/pre&gt;OR, if we aren't making a substitution&lt;pre&gt;sed -n '/pattern/p' &lt; file.txt&lt;br /&gt;&lt;/pre&gt;OR, you can just use grep -e, which is less confusing:&lt;pre&gt;grep -e "pattern" file.txt&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-8594504579700845540?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/8594504579700845540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=8594504579700845540' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/8594504579700845540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/8594504579700845540'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/08/where-there-is-awk-there-is-sed.html' title='Where there is awk, there is sed'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-9112899120609379223</id><published>2010-08-25T03:48:00.001-07:00</published><updated>2010-08-26T04:00:33.912-07:00</updated><title type='text'>AWK - selecting columns for output</title><content type='html'>AWK is a super-handy old-skool UNIX tool.  There are plenty of &lt;a href="http://www.grymoire.com/Unix/Awk.html"&gt;good tutorials&lt;/a&gt; out there for it, but I'm jotting down some basic uses here for my own benefit.&lt;br /&gt;&lt;br /&gt;I have used AWK mainly to select and print certain columns from input, like this, which will print the 1st and 7th columns:&lt;br /&gt;&lt;pre&gt;awk '{print $1,$7}' &lt; /var/log/syslog&lt;br /&gt;&lt;/pre&gt;Columns break-up is determined by the value of the FS (input field separator) variable, which is space by default (in POSIX mode this actually means space and tab but not newline).  You can change this with:&lt;pre&gt;awk 'BEGIN {FS=";"}{print $1,$7}' &lt; /var/log/syslog&lt;br /&gt;&lt;br /&gt;OR&lt;br /&gt;&lt;br /&gt;awk -F: '{print $1,$7}' &lt; /var/log/syslog&lt;br /&gt;&lt;/pre&gt;The output from awk is separated by the OFS (output field separator) variable, also a space by default.  To write out CSV you might use:&lt;pre&gt;cat /var/log/syslog | awk -F: 'BEGIN{OFS=","}{print $1,$3}'&lt;br /&gt;&lt;/pre&gt;There is plenty more you can do with awk, including simple programming tasks such as counting, summing etc.cut is a simple alternative if all you want to do is cut fields from an input stream.  It is doesn't take much to hit its limitations however.  Consider the output of last, the first two columns of which look like this:&lt;pre&gt;user     pts/0&lt;br /&gt;user     pts/1&lt;br /&gt;reboot   system boot&lt;br /&gt;&lt;/pre&gt;This awk command will print the first two columns correctly:&lt;pre&gt;last | awk '{print $1,$2}'&lt;br /&gt;&lt;/pre&gt;Whereas this cut command:&lt;pre&gt;last | cut -d" " -f1-5&lt;br /&gt;&lt;/pre&gt;Won't produce the first two columns cleanly and we need to specify 5 columns to try and skip the empty fields.  The problem is there are variable numbers of spaces between the username and the tty line.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-9112899120609379223?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/9112899120609379223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=9112899120609379223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/9112899120609379223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/9112899120609379223'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/08/awk-selecting-columns-for-output.html' title='AWK - selecting columns for output'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-5572989640704548362</id><published>2010-08-23T06:08:00.000-07:00</published><updated>2010-08-23T06:08:13.486-07:00</updated><title type='text'>Tips for hardening apache on ubuntu for django deployment</title><content type='html'>There is good doco for deploying django on apache with &lt;a href="http://docs.djangoproject.com/en/dev/howto/deployment/modpython/"&gt;mod_python&lt;/a&gt; or &lt;a href="http://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/"&gt;wsgi&lt;/a&gt;.  Here are a couple of extra tips for Ubuntu.  First, edit &lt;pre&gt;/etc/apache2/conf.d/security&lt;/pre&gt;and enable:&lt;br /&gt;&lt;pre&gt;ServerTokens Prod&lt;br /&gt;ServerSignature Off&lt;br /&gt;TraceEnable Off&lt;br /&gt;&lt;/pre&gt;And in the apache config in your "Location /" directive with the other django stuff:&lt;br /&gt;&lt;pre&gt;Options -Indexes -Includes -Multiviews SymLinksIfOwnerMatch&lt;br /&gt;&lt;/pre&gt;Take a look at &lt;a href="http://httpd.apache.org/docs/2.0/misc/security_tips.html"&gt;Apache's security tips&lt;/a&gt; and it is also worth understanding how the &lt;a href="http://httpd.apache.org/docs/2.0/sections.html"&gt;Apache configuration directives (Directory, Location, etc.) work&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-5572989640704548362?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/5572989640704548362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=5572989640704548362' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5572989640704548362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5572989640704548362'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/08/tips-for-hardening-apache-on-ubuntu-for.html' title='Tips for hardening apache on ubuntu for django deployment'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-3344458075737135479</id><published>2010-08-20T20:31:00.000-07:00</published><updated>2011-04-02T15:32:00.649-07:00</updated><title type='text'>SSH client config</title><content type='html'>For Internet-connected hosts, running SSH on a different port is a really good idea since it cuts down the noise of authentication attempts from bots looking for weak passwords.  Running on a different port is not a substitute for a secure configuration (ie. no root login, key-only auth) - it is purely useful in cutting down log noise.&lt;br /&gt;&lt;br /&gt;Unfortunately you have to remember which port you chose :)  To minimise the hassle you should add entries in your client /etc/ssh/ssh_config:&lt;br /&gt;&lt;pre&gt;Host nickname&lt;br /&gt;    Port 43210&lt;br /&gt;    HostName mysshserver&lt;br /&gt;    User myuser&lt;br /&gt;&lt;/pre&gt;Now you can use "ssh nickname" and ssh will translate that to:&lt;br /&gt;&lt;pre&gt;ssh -p 43210 mysshserver&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-3344458075737135479?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/3344458075737135479/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=3344458075737135479' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3344458075737135479'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/3344458075737135479'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/08/ssh-client-config.html' title='SSH client config'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5385036587194404038.post-5147277473662988963</id><published>2010-08-16T06:41:00.000-07:00</published><updated>2010-08-16T06:41:02.151-07:00</updated><title type='text'>Installing Windows 7 onto a netbook using USB</title><content type='html'>I wanted to install Windows 7 onto a netbook to replace an aging desktop as my only windows-on-metal box.  This is a &lt;a href="http://www.ubuntu.com/netbook"&gt;breeze with modern linux distros&lt;/a&gt;, but is of course far harder than it needs to be for windows.&lt;br /&gt;&lt;br /&gt;I had a crack at using &lt;a href="http://unetbootin.sourceforge.net/"&gt;unetbootin&lt;/a&gt; on Linux with the Windows 7 ISO, despite a suspicious lack of mention of support for windows, and sure enough it didn't boot (unetbootin didn't give me any errors, it just didn't boot).&lt;br /&gt;&lt;br /&gt;More googling turned up the &lt;a href="http://store.microsoft.com/help/iso-tool"&gt;Windows 7 USB/DVD Download Tool&lt;/a&gt;, which converts a Windows install ISO into a bootable USB installer - exactly what I wanted.  After half an hour of downloading and installing dependencies (due to the &lt;a href="http://ilostmynotes.blogspot.com/2010/04/microsofts-attempt-to-fix-windows.html"&gt;lack of windows package management&lt;/a&gt; and a bizarre need to do the Genuine Windows check), I had the tool installed and it happily created a bootable USB for me.&lt;br /&gt;&lt;br /&gt;This one worked perfectly, and dropped Windows 7 starter onto the netbook.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5385036587194404038-5147277473662988963?l=ilostmynotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ilostmynotes.blogspot.com/feeds/5147277473662988963/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5385036587194404038&amp;postID=5147277473662988963' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5147277473662988963'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5385036587194404038/posts/default/5147277473662988963'/><link rel='alternate' type='text/html' href='http://ilostmynotes.blogspot.com/2010/08/installing-windows-7-onto-netbook-using.html' title='Installing Windows 7 onto a netbook using USB'/><author><name>a blogger</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
