Yearly Archives: 2010

Thursday Quote: Dan Wineman

December 16, 2010 » Life

You say “looks like somebody has too much time on their hands” but all I hear is “I’m sad because I don’t know what creativity feels like.”

– Dan Wineman

Thursday Quote: William Gibson

December 9, 2010 » Geek, Life

“My problem is that all things are increasingly interesting to me.”

– William Gibson
During A Talk On “Zero History”

Tail In PHP

December 3, 2010 » Geek

So I’m working on a little admin interface and I decided to tail some logs. It’s in PHP and Google came up with some stuff, but they were all a bit finickey and not well documented. So I wrote my own!

Here’s the basic concept:

  1. Open File
  2. Seek To End
  3. Loop:
    1. Seek Back By Chunk Size
    2. Read Chunk
    3. Count Newlines
    4. Stash In Buffer
    5. Break If Enough Newlines Total
  4. Trim Extra Line & Cruft
  5. Done!

Here’s the code:

function tail ( $file, $lines, $max_chunk_size = 4096 ) {

  // We actually want to look for +1 newline so we can get the whole first line
  $rows = $lines + 1;

  // Open up the file
  $fh = fopen( $file, 'r' );

  // Go to the end
  fseek( $fh, 0, SEEK_END );
  $position = ftell( $fh );

  $buffer = '';
  $found_newlines = 0;

  $break = false;
  while( ! $break ) {
    // If we are at the start then we are done.
    if( $position <= 0 ) { break; }

    // We can't seek past the 0 position obviously, so figure out a good chunk size
    $chunk_size = ( $max_chunk_size > $position ) ? $position : $max_chunk_size;

    // Okay, now seek there and read the chunk
    $position -= $chunk_size;
    fseek( $fh, $position );
    $chunk = fread( $fh, $chunk_size );

    // See if there are any newlines in this chunk, count them if there are
    if( false != strpos( $chunk, "\n" ) ) {
      if( substr( $chunk, -1 ) == "\n" ) { ++$found_newlines; }
      $found_newlines += count( explode( "\n", $chunk ) );
    }

    // Have we exceeded our desired rows?
    if( $found_newlines > $rows ) { $break = true; }

    // Prepend
    $buffer = $chunk . $buffer;
  }

  // Now extract only the lines we requested
  $buffer = explode( "\n", $buffer );
  return implode( "\n", array_slice( $buffer, count( $buffer ) - $lines ) );
}

You can give it a try on some junk data here: http://static.velvetcache.org/pages/2010/12/03/tail-in-php/

Thursday Quote: C. Scott Andreas

December 2, 2010 » Geek

“If you are afraid of your program, troche you have to break it until you are not afraid of it anymore.”

– C. Scott Andreas
You Have to Break It

Headless VirtualBox

December 2, 2010 » Geek

Updated (2010-12-02)

So, duh, multiple interfaces. One NAT one Host-Only. All done.

I recently set up a VirtualBox VM to test BlankSMTP locally, but it’s annoying to have the GUI up all the time when I’m just SSH’ing in. To get around this I set it up to work headless.

The biggest hangup is networking. I had to switch it to Host-Only so that the interface would remain consistent. Other wise with bridged I would get new IP’s all the time, and even then only when the networking init script got triggered somehow.

After that was set I just wrote two quick bash scripts to start and stop. An init script would also be an option if I wanted to make sure it shut down when I power off the laptop, but I decided it wasn’t worth the trouble.

The key commands are VBoxHeadless -startvm [vm name] and VBoxManage controlvm [vm name] savestate

blanksmtp-start

#!/bin/bash

COUNT=$( ps aux | grep 'VBoxHeadless -startvm BlankSMTP' | grep -v grep | wc -l)

if [ "$COUNT" == "0" ]; then
        echo "Starting BlankSMTP..."
        nohup VBoxHeadless -startvm BlankSMTP > /dev/null 2>&- &
else
        echo "Found a running instance!"
fi

blanksmtp-stop

#!/bin/bash

COUNT=$( ps aux | grep 'VBoxHeadless -startvm BlankSMTP' | grep -v grep | wc -l)

if [ "$COUNT" == "0" ]; then
        echo "No running instance!"
else
        echo "Shutting down..."
        VBoxManage controlvm BlankSMTP savestate
fi

Works like a charm!