Category Archives: Software

Jailbreak 2nd Gen iPod Touch with GreenPois0n

Spent a couple of hours today trying to jailbreak my iPod. After numerous attempts, I was on the point of giving up when I found this forum post with a solution: Run greenpois0n from the command line, rather than from the GUI.

While the forum post refers to RC5_2, I can confirm that it works with RC6 also. Here’s my method.

  1. Make sure that your iPod is connected to your computer.
  2. Shut down iTunes if it’s open.
  3. Turn off your iPod.
  4. Hold the power button and home button for 10 seconds.
  5. Release the power button, keep holding the home button for a further 10 seconds.
  6. Open Terminal.
  7. Change directory to the location of the greenpois0n app.
  8. Type open ./greenpois0n.app/Contents/MacOS/greenpois0n
  9. A new Terminal window will open and greenpois0n should now be able to jailbreak your iPod.
  10. Wait for your iPod to restart.
  11. Find the green Loader icon on your iPod and use it to install Cydia.

And that’s it – you’re good to go!

WordPress and the”filesize() [function.filesize]: stat failed”Error

I’ve been working on a website that includes a download button. When clicked the button would prompt to open or save the file. The prompt appeared on cue and the file downloaded, but for some reason the file was empty.

Checking the php_error.log, showed that this error was being generated:

PHP Warning: filesize() [function.filesize]: stat failed for http://localhost:8888/ringstone/wp-content/uploads/docs/brochure.pdf in /Applications/MAMP/htdocs/ringstone/wp-content/themes/ringstone/frontpage.php on line 26

Normally if the filesize function fails it’s because the directory where the file is stored is not writeable or the file is larger than 2GB.

In this case, the directory was writeable and the file was a lot less than 2GB in size. So I was stumped.

Going over my code, the only thing that I could see that might be causing the problem was the link to the file.

I was using the following code to get the WordPress uploads directory:

$uploads = wp_upload_dir();$url = $uploads['baseurl'];$filename = $url . ‘/docs/brochure.pdf’;

This generated the url for the document as: http://localhost:8888/ringstone/wp-content/uploads/docs/brochure.pdf

According to the PHP manual for filesize, as of PHP 5.0.0 the filesize function supports using some URL wrappers, including HTTP. The version of MAMP that I’m using includes PHP 5.3.2, so this shouldn’t have been a problem. It turns out that I was wrong.

I updated my code to:

$uploads = wp_upload_dir();$path = $uploads['basedir'];$filename = $path . ‘/docs/brochure.pdf’;

And it worked.

The lesson is that if you’re seeing filestat error in your PHP error log, then go through the following checklist:

  1. Pass filestat the directory path to the file, not the URL. (Even though the manual says that it should work.)
  2. Check that the directory is writeable.
  3. Check that the file is smaller than 2GB in size.

Creating A Linux USB Boot Drive on Mac OS X

I recently needed to boot a laptop from Linux, but didn’t have any of my Linux boot disks with me. Luckily I had my USB flash drive, so I decided to install a mini-version of Linux. A quick Google searched led me to Recovery is Possible, or RIPLinuX.

Here’s how to install the .iso onto the flash drive:

Open Terminal under Applications → Utilities.

We’ll be using the diskutil command to write the .iso contents to the flash drive. So the first thing to do is determine the block device associated with our flash drive.

Before inserting the drive typediskutil listand hit enter. Insert your drive and run the diskutil list command again.

You should get something like this:

Results of the diskutil list command

As you can see, the flash drive is connected via /disk/dev1, though this may be different on your system. Before you can start writing the data to the flash drive, you need to unmount the drive.

diskutil unmountDisk /dev/disk1

Unmounting the flash drive using diskutil

Now, you’re ready to start writing the data to the drive.

sudo dd if=/path/to/linux.iso of=/dev/disk1 bs=1m

Data has been successfully written to the drive

Once the data has been written to the drive, all that remains is to eject it.diskutil eject /dev/disk1

Eject the flash drive

And you’re done! Remember that in order to boot from the USB drive, the computer that you’re using must support booting from USB devices and that you need to change the boot order in the BIOS.

PHP Code Snippet

Because of the re-design, there’s a lot of broken links – mainly because the blog used to live under the /whatithink/ folder on the server and now resides in the root folder. So all those Google links now point to a part of the site that no longer exists.

So anyone coming here from Google is going to get a 404 error. Not good.

While I get my head around using .htaccess to automatically rewrite the broken URLs, I’ve created a 404 page that will, (hopefully), correct the URL.

Here’s the PHP:

$requested = $_SERVER['REQUEST_URI'];$parts = explode('/', $requested);foreach ($parts as $part) {switch($part) {case ('whatithink'):break;case (''):break;default:$out .= '/' . $part;}}$out = 'http://' . $_SERVER['HTTP_HOST'] . $out;

Because all my broken URLs have an extra “/whatithink/” section, I can just break the requested URL into parts, and rebuild it without that section.

MyBook World Edition – Time Machine – OSStatus Error 2

If Time Machine is unable to connect to your backup disk with an error message containing “OSStatus Error 2″, then check the permissions on your NAS.

SSH as root into your MBWE and check the permissions for /var and /var/lib.

Use chmod 755 on /var and /var/lib to apply the correct permissions.

Use the Time Machine System Preferences to set your backup disk to your MBWE.

GeekTool

I’ve been playing around with GeekTool for a couple of days and I’ve finally gotten everything I want on my desktop.

Here’s what my desktop looks like at the moment:

My GeekTool Desktop

My GeekTool Desktop

For reference, here’s my list of GeekTool Scripts:

  • Computer Name: hostname -s
  • Login Name: whoami
  • Day: date “+%A”
  • Month: date “+%b”
  • Day (numerical): date “+%e”
  • Time: date +”%I:%M”
  • AM/PM: date +”%p”
  • Mac OS X Version: sw_vers | awk -F’:t’ ‘{print $2}’ | paste -d ‘ ‘ – - – ;
  • Disk Usage: df -H | grep disk0s2 | awk ‘{print “Disk:”, $3, “/”, $2, “-”, $4, “available”}’
  • Uptime: uptime | awk ‘{print “Up: ” $3 ” days”}’
  • Airport Network Name: airport -I | grep -e “bSSID:” | awk ‘{print $2}’
  • Airport Channel: airport -I | grep -e “channel:” | awk ‘{print “Channel: ” $2}’
  • Airport Max Rate: airport -I | grep -e “maxRate:” | awk ‘{print “Max Rate: ” $2}’
  • Airport Link Authorisation: airport -I | grep -e “link auth:” | awk ‘{print “Auth: ” $3}’
  • External IP: echo `curl -s http://checkip.dyndns.org/ | sed ‘s/[a-zA-Z<>/ :]//g’`
  • Running Processes: ps -c -U pmac -o command,%cpu,%mem -r
  • Airport IP: ipconfig getifaddr en1
  • Calendar: cal
  • Network Location: scselect 2>&1 | grep ‘^ *’ | sed -e ‘s:^[^(]*(([^)]*))$:1:g’

Most of these commands were culled from various websites, while I came up with the rest myself.

“custom_domain is null”error message in Firefox

Problem: When opening a “localhost” address using Firefox, a JavaScript error message is displayed with the error message “current_domain is null”.

Description: Using Firefox version 3.0.11. Error message only appears when connecting to a site hosted on the local machine. Disabling all add-ons resolves the problem. Re-enabled add-ons one by one. Re-enabling LongURL Expander causes the problem to re-appear. Error message is known issue with version 2.0.0 of the add-on.

Solution: As per the comments on the the add-on page, edit the longurlmobileexpander.js file to make the requirement for the second part of the domain name optional.

  • On Mac OS X, open home folder and browse to Library/Application Support/Firefox/Profiles/[profile].default/extension/{a7101e54-830c-4d33-a3ed-bedc17ec44da}/content
  • Open longurlmobileexpander.js in TextEdit.
  • Edit line 78 to read:

var current_domain = document.location.href.match(/^https?://(?:www.)?([^.]+(.[^/]+)?)/i);

  • Save changes.

Thanks to Mathias Jansen for the solution.

WordPress 2.8 – New Widget API

WordPress 2.8 and the new Widget API

WordPress 2.8 is due sometime this month, and one of the major changes is the new Widget API.

Hand in hand comes the new Widget Panel which uses AJAX to update your sidebars. The latest beta has the new Widget Panel included:

WordPress 2.8 Widget Panel

WordPress 2.8 Widget Panel

Still very much a work in progress, the Panel doesn’t fully work yet and there’s a bit of work to be doen on the presentation side.

Multi Widgets

The biggest change is going to be for plugin writers. The new Widget API is designed to make the process of writing widgets, especially multi widgets easier.

As anyone who has ever written a multi-widget will tell you, the documentation is virtually non-existent and what tutorials are available are cryptic.1

The Widget API

As 2.8 will be released in the near future, now is the time to start thinking about updating your widgets to take advantage of the new API. As the Widget API isn’t fully documented yet, I decided to have a look at the source files to see what’s involved in writing a widget using the API.

The relevant files are:

  • /wp-includes/widgets.php
  • /wp-includes/default-widgets

Using the Widget API

The new Widget API provides a WP_Widget class and it’s by extending this class that you create your own widget. Your widget then over-rides 3 three methods within WP_Widget:

  1. widget()
  2. update()
  3. form()

The easiest way to demonstrate this is by creating a basic text widget. So we’ll build a WordPress 2.8 Text Widget.

Building Your Widget

As with the current version of WordPress, your widget needs to contain the some basic information so that WordPress will recognise it as a plugin:

<?php/*Plugin Name: New Widget APIPlugin URI: http://www.paulmc.org/whatithink/Description: Demonstration of the WordPress 2.8 Widget APIVersion: 1.0Author: Paul McCarthyAuthor URI: http://www.paulmc.org/whatithink*/

The first step is to create your widget class by extending WP_Widget:

class WP_My_Widget extends WP_Widget {

Your widget needs a constructor, that is, a function that will be called when the widget is loaded. Your constructor must have the same name as your widget. Within the constructor, specify an array to hold your widget options, control options and call the WP_Widget constructor.

function WP_My_Widget() {$widget_ops = array ('classname' => 'my_widget', 'description' => __('The description for your Widget') );$control_ops = array ('width' => '300', 'height' => '400');$this->WP_Widget('my_widget', __('My Widget'), $widget_ops, $control_ops);}

Once you’ve created your constructor, it’s time to over-ride the methods needed to make your widget work. The first method to over-ride is widget().

The widget() method is where your widget does it’s work. The widget() method takes two parameters. The first provides you with access to the widget display settings and the second provides access to that particular instance settings.

As this is a simple text widget, we’ll use just two settings – title and text.

function widget($args, $instance) {extract ($args);$title = empty($instance['title']) ? __('My Widget Title') : apply_filters('widget_title', $instance['title']);$text = apply_filters('widget_text', $instant['text']);echo $before_widget . $before_title . $title . $after_title;echo $text;echo $after_widget;}

The next method that we’ll over-ride is the update() method. This method provides us with the means to update and save our widget settings. It takes two parameters, the first is an array that contains the settings provided by the user via the widget form, and the second is an array containing the old settings for the widget.

function update ($new_instance, $old_instance) {$instance = $old_instance;$instance['title'] = strip_tags($new_instance['title']);$instance['text'] = $new_instance['text'];return $instance;}

That’s it. All the method does is store the old settings in an array, update the array with the new settings and then pass the new settings back to the WP_Widget class. The WP_Widget class handles the actual updating and saving.

Our next method to over-ride is form(). This method is used to display the widget control form. It takes one parameter, an array with the current settings.

function form ($instance) {$instance = wp_parse_args( (array) $instance, array('title' => '', 'text' => ''));$title = strip_tags($instance['title']);$text = format_to_edit($instance['text']);?><p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?><input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo attribute_escape($title); ?>" /></label><textarea class="widefat" rows="16" cols="20" id="<?php echo $this->get_field_id('text'); ?>" name="<?php echo $this->get_field_name('text'); ?>"><?php echo $text ?></textarea></p><?php}}

That’s it. A simple text widget written using the WordPress 2.8 Widget API.

If you’d like to review the full code, with comments, then you can download it here:

New Widget API Plugin File

  1. I’ve been looking into transforming one of my widgets into a multi-widget, but given the hassle involved, I’m just going to hold off until 2.8 is released. []

New WordPress Plugin – Email Post Activation

I was looking into blogging via email1, and I couldn’t get it to work. Until I discovered that WordPress has to be told to check for any new emails.2.

In order to process the email post, WordPress uses wp-mail.php. Loading this page in your browser will tell WordPress to check for new email posts. There are three ways to call the file:

  • By visiting the URI to wp-mail.php in your browser,
  • By using Cron to automatically load the file after a set period of time, or
  • By including a hidden iframe in your Blog footer that links to wp-mail.php.

Not all WordPress users have the ability to edit their crontab and even more have no interest in editing their theme files. So I wrote a simple plugin that will add the iframe to the the blog footer.

When I say simple, I actually mean simple – there’s all of 3 lines of code in this plugin, so not much can go wrong with it.3

You can read more about it here.

  1. The reason for which I’ll go into in a later post []
  2. I should of realised this, but it was so obvious that I didn’t even consider it []
  3. Having just re-read that, it looks like I’m tempting fate. []