Text

IPv6 Validator for Cocoa

I’ve been spending quite a bit of time trying to find a regex match that will allow me to verify IPv6 addresses. I finally found one that works very well in Cocoa:

- (BOOL)isIPv6:(NSString *)candidate
{
    /*
     fe80:0000:0000:0000:0204:61ff:fe9d:f156        // full form of IPv6
     fe80:0:0:0:204:61ff:fe9d:f156                  // drop leading zeroes
     fe80::204:61ff:fe9d:f156                       // collapse multiple zeroes to :: in the IPv6 address
     fe80:0000:0000:0000:0204:61ff:254.157.241.86   // IPv4 dotted quad at the end
     fe80:0:0:0:0204:61ff:254.157.241.86            // drop leading zeroes, IPv4 dotted quad at the end
     fe80::204:61ff:254.157.241.86                  // dotted quad at the end, multiple zeroes collapsed

     In addition, the regular expression matches these IPv6 forms:

     ::1        // localhost
     fe80::     // link-local prefix
     2001::     // global unicast prefix
     */

    NSString *regex = @"^\\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}))|:)))\\s*$";

    NSPredicate *test = [NSPredicate predicateWithFormat:@"SELF MATCHES[c] %@", regex];

    return [test evaluateWithObject:candidate];
}

I’ve written a unit test verifying all the cases mentioned above and it works great.

Text

Removing subviews from an NSView

Typically, the solution involves iterating through NSView’s - [NSArray subviews] and invoke the child’s - (void)removeFromSuperview method. This is tedious. A much easier solution is to set an empty list of childs on the parent NSView, like so:

    [self setSubviews:[NSArray array]];


It’s simple, clean and better yet… won’t crash while you iterate the array and destroy the objects while you’re ennumerating ;-)

Text

Converting an NSColor to a CGColor

Here’s an easy way to convert an NSColor to a CGColor:

- (CGColorRef)NSColorToCGColor:(NSColor *)color
{
    NSInteger numberOfComponents = [color numberOfComponents];
    CGFloat components[numberOfComponents];
    CGColorSpaceRef colorSpace = [[color colorSpace] CGColorSpace];
    [color getComponents:(CGFloat *)&components];
    CGColorRef cgColor = CGColorCreate(colorSpace, components);

    return cgColor;
}


Easy.

Text

Reverting a local commit (that hasn’t been pushed to the remote repo)

How can I undo an accidental commit that hasn’t been pushed yet? Easy:

git reset --soft HEAD^


This will revert the commit and leave the changes in your local repo.

Text

Copying a Raspberry OS image to the SD card in Mac OS X

These commands and actions need to be performed from an account that has administrator privileges.

  1. Download the image from a mirror or torrent:

    http://www.raspberrypi.org/downloads
    


  2. Verify if the the hash key is the same (optional), in the terminal run:

    shasum ~/Downloads/2012-12-16-wheezy-raspbian.zip
    


  3. Double click the zip, it will extract the image automatically.

  4. From the terminal run

    df -h
    


  5. Connect the SD card reader with the SD card inside. Run df -h again and look for the new device that wasn’t listed last time. Record the device name of the filesystem’s partition, for example, /dev/disk3s1. Example:

    TurboMonkey:Desktop tciuro$ df -h
    Filesystem                          Size   Used  Avail Capacity  iused    ifree %iused  Mounted on
    /dev/disk0s2                       233Gi  185Gi   48Gi    80% 48594722 12474718   80%   /
    devfs                              197Ki  197Ki    0Bi   100%      682        0  100%   /dev
    map -hosts                           0Bi    0Bi    0Bi   100%        0        0  100%   /net
    map auto_home                        0Bi    0Bi    0Bi   100%        0        0  100%   /home
    localhost:/mxqCAh80ehTrmCCc-8n_X5  233Gi  233Gi    0Bi   100%        0        0  100%   /Volumes/MobileBackups
    /dev/disk1s1                        15Gi  2.2Mi   15Gi     1%        0        0  100%   /Volumes/NO NAME
    


  6. Unmount the partition so that you will be allowed to overwrite the disk:

    sudo diskutil unmount /dev/disk3s1
    


  7. Using the device name of the partition work out the raw device name for the entire disk, by omitting the final “s1” and replacing “disk” with “rdisk” (this is very important: you will lose all data on the hard drive on your computer if you get the wrong device name). Make sure the device name is the name of the whole SD card as described above, not just a partition of it (for example, rdisk3, not rdisk3s1. Similarly you might have another SD drive name/number like rdisk2 or rdisk4, etc. — recheck by using the df -h command both before & after you insert your SD card reader into your Mac if you have any doubts!). Example:

    /dev/disk1s1 => /dev/rdisk1
    


  8. In the terminal write the image to the card with this command, using the raw disk device name from above (read carefully the above step, to be sure you use the correct rdisk# here!):

    sudo dd bs=1m if=~/Desktop/2012-12-16-wheezy-raspbian.img of=/dev/rdisk1
    

If the above command report an error(dd: bs: illegal numeric value), please change bs=1M to bs=1m (note that dd will not feedback any information until there is an error or it is finished, information will show and disk will re-mount when complete. However if you are curious as to the progress - ctrl-T (SIGINFO, the status argument of your tty) will display some en-route statistics).

  1. After the dd command finishes, eject the card:

    sudo diskutil eject /dev/rdisk1
    

Insert it in the Raspberry Pi, and have fun!

Quote
Why is it easier to say there’s some God that always existed, as opposed to the Universe always existed? How is it that a God could always exist, but not a Universe? Or conversely, how is it that a God could come from nothing, but not a Universe?
Text

How to commit selectively using Git

Problem

Oftentimes, we’re fixing a bug and as we go along we see other issues which end being fixed as well. The problem results in a different set of changes which would typically end up committed at once.

Solution

Commit selectively using git add -p …

Example

Locate the Git directory and check its status:

git status


It will list the files with changes, such as:

ipanema:MyProject tciuro$ git status
'# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   foo.m
#   modified:   bar.m
#
no changes added to commit (use "git add" and/or "git commit -a")


For each of the files, issue the following command (we’ll start with foo.m):

git add -p foo.m


It’ll display each of the changes separately:

@@ -113,21 +113,15 @@ typedef enum {

 -    // Preflight
-    NSAssert(username.length > 0, @"the user name is required");
-    
     self.username = username;
-    self.password = (password.length > 0 ? password : @"");
+    self.password = password;
     self.authType = SSH;
 }

Stage this hunk [y,n,q,a,d,/,j,J,g,s,e,?]? y


Type y or no and continue until you’re done. Repeat the same step with the other modified files.

Text

How to enable tag search in your Tumblr blog

By default, Tumblr doesn’t allow to search by tags. Assuming you have a theme with a search bar, chances are that even though you tagged your posts, nothing comes up when you search by tag.

No problem. It’s quite easy to fix this. Just follow these steps:

1) Open your blog and click “Customize.” A configuration panel opens to the right of the window.
2) Click “Edit HTML.”
3) Hit Command-F (i.e. Find…) and search for “body” (without the quotes).
4) Right after “body” paste the following script:

<body>
<script type="text/javascript">
<!--
function handleThis(formElm)
{
    window.location="http://yourtumblrURLhere.tumblr.com/tagged/"+formElm.number.value+"";
    return false;
}
</script>
...
...


Some users have their own custom domain (e.g. www.yourdomain.com). If this the case, replace the window.location URL above:

window.location="http://yourtumblrURLhere.tumblr.com/tagged/"+formElm.number.value+"";


with this:

window.location="http://www.yourdomain.com/tagged/"+formElm.number.value+"";


That’s it really! Just save the HTML changes, reload your blog, tag something and search. Happy tagging!

Text

How to setup SSH keys

This brief tutorial explains how to generate SSH keys and publish them to a server. It’s been tested on Mac OS X Mountain Lion (10.8).

Objective
Generate an SSH key and upload them to a server. In our example, we’ll upload it to server.example.com.

Step #1
Launch Terminal.app and type:

ipanema:~ jdoe$ ssh server.example.com
The authenticity of host 'server.example.com (xx.xxx.xx.xxx)' can't be established.
RSA key fingerprint is xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:.


Type yes to add the host to your list of known hosts:

Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'server.example.com,xx.xxx.xx.xxx' (RSA) to the list of known hosts.


Enter the password. This will create an .ssh directory in your home directory with the proper permissions.

Password:
Last login: Tue Nov  6 20:33:46 2012 from xx.xxx.xx.xxx

Welcome to server.example.com.

This server is managed by the SEO Puppet configuration management system.
Local ad-hoc changes to this system are strictly discouraged.  Any files 
that contain an auto-generated header will be updated via puppet and local
changes will be overwritten.  Please contact admin@example.com for more info.

server:~ jdoe$


We can close the connection for now:

server:~ jdoe$ exit
logout
Connection to server.example.com closed.


Step #2
Now we’ll generate the SSH key:

ipanema:~ jdoe$ ssh-keygen -t rsa


This will prompt you for a secret passphrase:

Generating public/private rsa key pair.
Enter file in which to save the key (/Users/jdoe/.ssh/id_rsa): 
Created directory '/Users/jdoe/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /Users/jdoe/.ssh/id_rsa.
Your public key has been saved in /Users/jdoe/.ssh/id_rsa.pub.
The key fingerprint is:
15:db:96:0d:92:bc:51:4d:bf:d6:43:89:98:98:fb:c8 jdoe@ipanema.example.com
The key's randomart image is:
+--[ rsa 1024]----+
|         .oooo.  |
|          *=o+o..|
|         oo=+..o.|
|         .o.  . o|
|        S.     +.|
|        . o   . .|
|         E .     |
|                 |
|                 |
+-----------------+
ipanema:~ jdoe$ 


IMPORTANT
Always use a good passphrase and never leave it blank. If this works right you will get two files called id_rsa and id_rsa.pub in your .ssh directory.

Step #3
Now it’s time to upload the credentials to server.example.com:

scp ~/.ssh/id_rsa.pub server.example.com:.ssh/authorized_keys


This command copies the id_rsa.pub file to the other host’s .ssh directory with the name authorized_keys2. Now server.example.com is ready to accept your ssh key.

How to tell it which keys to use?
The ssh-add command will allow us to confirm which SSH key will be used:

bash-3.2$ ssh-agent sh -c 'ssh-add < /dev/null && bash'
Identity added: /Users/jdoe/.ssh/id_rsa (/Users/jdoe/.ssh/id_rsa)


The moment of truth
Everything looks good, so let’s try to ssh into server.example.com once again. This time, no prompt should appear because the magic of SSH keys will take over:

bash-3.2$ ssh serverexample.com
Last login: Tue Nov  6 20:18:18 2012 from 17.226.33.162

Welcome to serverexample.com.

This server is managed by the SEO Puppet configuration management system.
Local ad-hoc changes to this system are strictly discouraged.  Any files 
that contain an auto-generated header will be updated via puppet and local
changes will be overwritten.  Please contact seo@example.com for more info.

server:~ jdoe$


Did you gain access without a prompt? If so, congratulations! Otherwise, start over and pay attention to the instructions ;-)

Quote
Bacteria produce a new generation every 20 minutes. And every time they reproduce, which is they copy themselves, they make little copying errors. So when those little copying changes make the bacteria stronger as opposed to weaker then that means they are better able to defend themselves against those compounds, antibiotics.
CDC (Centers for Disease Control and Prevention) Drug-Resistant Gonorrhea: Is The Antibiotic Era Coming To An End?

mixpanel.track("Main Page");