Maintaining session between SSL and non-SSL pages in CakePHP

It’s funny, in a way, that cms34 has been around for nearly five years now, and it’s only just become a real issue that we were not maintaining sessions between SSL and non-SSL pages. This is somewhat understandable: practically speaking, the only time it really matters to carry over the session between the two is when a user is logged in. (This might not be the case with all web applications, but for us, at least, there’s rarely enough happening in the session when a user is not logged in for it to matter.)

As it happens, not that many cms34 sites use SSL; not that many cms34 sites use the user login capability on the front end. And very few use both. But we’ve had a couple of new sites come online lately that do use both, and it’s become a bit of an issue.

The issue was exacerbated by the fact that I recently modified the Users controller to require SSL on the login page, if the site has an SSL certificate. Consequently there were issues with trying to access login-restricted, but non-SSL pages… redirect loops and other such fun.

What’s the problem?

The problem is simple: for obvious security reasons, sessions and cookies cannot be shared directly between two different domains. It’s possible (although less secure) to share them between both SSL and non-SSL on the same domain, and it’s also relatively easy to set them up to work between different subdomains. But if your SSL pages use a different domain name than the non-SSL pages, even if they’re on the same server, there’s no way to get them to automatically use the same session.

The solution (though still not ideal, as it can introduce the risk of session hijacking), as you’ll find in lots of places, is to pass the session ID as a query string variable. Then you can use that to restore the same session ID, even if it’s on another domain — as long as it’s on the same physical server.

Some improvements

There are two key improvements I made to the basic “pass the session ID in the query string” scenario.

First, when the session is created I am writing the user’s IP address (using $_SERVER['REMOTE_ADDR']) as a session variable. Then, when I am attempting to restore the session with the ID passed as a query string variable, I read the session file on the server first, and make sure the IP address in the file matches still matches the user’s current IP address. Only then do I restore the session.

Second, and this is an aesthetic issue almost as much as a security one, once the session has been re-established, and before any response has been sent, I strip the session ID out of the requested URL and redirect to that new URL. It’s all invisible to the user, and the session ID never actually appears in the browser’s address bar.

A look at the code

There’s a lot going on in the cms34 code, much of which is highly specific to this application. But in short the keys to making this work happen in two places:

UsersController::login()

I have a login() action in UsersController that handles all of the special functionality that needs to happen when a user logs in. The actual login itself happens “automagically” via AuthComponent, but Auth doesn’t know everything I need to have happen when a user logs in, so after Auth does its work, my login() action takes it from there.

Honestly not a lot needs to happen here to make this work. Just two things: you have to write the user’s IP address to the session as I noted above, and you have to pass the session ID in a query string variable on the redirect that happens when login is successful. My code looks a little something like this (note that I have an array in the session called Misc that I use for… miscellaneous stuff like this):

class UsersController extends AppController {

  var $name = 'Users'
  // Other controller variables go here, of course.

  function login() {

    // All of this should only run if AuthComponent has already logged the user in.
    // Your session variable names may vary.
    if ($this->Session->read('Auth.User')) {

      // Various session prep stuff happens here.

      // Write IP address to session (used to verify user when restoring session).
      $this->Session->write('Misc.remote_addr(',$_SERVER['REMOTE_ADDR']);

      // Some conditionals for special redirects come here but we'll skip that.

      // Redirect user to home page, with session ID in query string.
      // Make up a query string variable that makes sense for you.
      $this->redirect('/?cms34sid=' . session_id());

    }
  }
}

So far, so good. The rest of the excitement happens in…

AppController::beforeFilter()

Ah yes, the magical beforeFilter() method. There’s a whole lot of stuff going on in AppController::beforeFilter() in cms34, most of which is highly specific to our application. But this is where you will need to put your code to retrieve the session ID from the query string and restore the session… this function runs at the beginning of every page load on your site.

I’ve put this logic almost at the beginning of beforeFilter(), because we really do want that session restored as soon as possible.

Here’s a look…

class AppController extends Controller {

  function beforeFilter() {

    // Additional code specific to your app will likely come before and after this.

    // Only run if session ID query string variable is passed and different from the existing ID.
    // Be sure to replace cms34sid with your actual query string variable name.
    if (!empty($this->params['url']['cms34sid']) && $this->params['url']['cms34sid'] != session_id()) {

      // Verify session file exists.
      // I am using CakeSession; your session files may be elsewhere.
      $session_file = TMP.DS.'sessions'.DS.'sess_'.$this->params['url']['cms34sid'];

      if (file_exists($session_file)) {
        $session_contents = file_get_contents($session_file);

        // Find user's IP address in session file data (to verify identity).
        // The CakePHP session file stores a set of serialized arrays; we're reading raw serialized data.
        // If you used a different session variable name than remote_addr, change it AND the 11 to its string length.
        $session_match = 's:11:"remote_addr";s:'.strlen($_SERVER['REMOTE_ADDR']).':"'.$_SERVER['REMOTE_ADDR'] .'";';

        // User's IP address is in session file; so we can continue.
        if (strpos($session_contents,$session_match) !== false) {

          // Set session ID to restore session
          $this->Session->id($this->params['url']['cms34sid']);

          // Redirect to this same URL without session ID in query string
          $current_url = rtrim(preg_replace('/cms34sid=[^&]+[&]?/','',current_url()),'?&');
          $this->redirect($current_url);
        }
      }
    }
  }
}

A few final thoughts

I didn’t really discuss cookies at all here, but suffice to say there’s a cookie containing the session ID that gets written. If you’re only using cookies for the session ID (which is probably a good idea), then you don’t really need to do anything else with them. But if you’re writing certain cookies when a user logs in (like I do), you’ll need to write additional logic to restore them in AppController::beforeFilter(). In my case, the relevant cookies are all duplicates of session data, but are intended for a few edge cases where I need to access that information through JavaScript or in .htaccess files that are protecting login-restricted downloadable files — in other words, places where I can’t use PHP to look at session data.

You may also notice near the end of the code in the AppController::beforeFilter() example above that I am calling a function called current_url(). This is not a built-in part of PHP or CakePHP; it’s a simple little function I have in my config/functions.php file. Here it is:

function current_url() {
  return (!empty($_SERVER['HTTPS']) ? 'https://' : 'http://') . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
}

From the Stupid PHP Tricks files: rounding numbers and creeping inaccuracy

This morning as I walked to the studio I was doing what geeks do best: pondering a slightly esoteric mathematical quandary.

Glass Half Full by S_novaIngraining the American spirit of optimism at a young age, and under dubious circumstances, our schools always taught rounding numbers in a peculiar way. You always round your decimal values to the nearest integer. That part makes sense. But what if the decimal is .5 — exactly half? In my education, at least until late in high school (or was it college?), we were always taught to round up! The glass is half full. Optimism.

Eventually — far later than it should have been, I think — the concept was introduced that always rounding .5 up is not really that accurate, statistically speaking. It might be nice in the case of a single number to be an optimist and think a solid half is good as a whole, but in aggregate this thinking introduces a problem.

If you have a whole lot of numbers, and you’re always rounding your halves up, eventually your totals are going to be grossly inaccurate.

Of course, the same would happen if you were ever the pessimist and always rounded down.

The solution, I later learned, was to round halves up or down, depending upon the integer value that precedes them. Which way you go doesn’t really matter, as long as you’re consistent, but as it happens, I learned it as such: if the integer is odd, round up; if it is even, round down.

In my work, I write a lot of PHP code. Most of it is of the extremely practical variety; I’m building websites for clients, after all. But every once in a while I like to indulge my coding abilities in a bit of frivolous experimentation, and so today I produced a little PHP script that generates 10,000 random numbers between 1 and 100, with one decimal place, and then it shows the actual sum and average of those numbers, along with what you get as the sum and average if you go through all 10,000 numbers and round them to whole integers by the various methods described above. Try it for yourself!

Any time the rounded average is different from the “precise” (and I use that term somewhat loosely) average, it is displayed in red. Interestingly, and not at all surprisingly, when you always round halves in one direction or the other, at least one of those directions will (almost) always yield an incorrect average. Yet if you use the “even or odd” methods, both of those methods will almost always yield a correct average.

It’s all about the aggregate.

Discovering the Driftless

What if you lived in the middle of a geological curiosity and didn’t even know it?

Well, maybe not the middle, but just beyond the western edge? That was me, growing up in Austin, Minnesota. Austin is on the eastern edge of the prairie, flat and surrounded by corn and soybean fields. It’s a small company town, headquarters of Hormel Foods. A union town. And as a kid, the only thing I knew about the area that was noteworthy was that we invented Spam.

But I did also know that just a bit farther to the east, the terrain got… weird. Flat cornfields turned into rolling hills, and then into steep bluffs as you approached the Mississippi River. On the other side of the river, in Wisconsin, things got even weirder, with strange rock formations dotting the hilly landscape, until eventually farther to the east things flattened out again. And I knew the place was weird below the surface too, with caves and underground streams.

I often wondered what made the areas just to the east of my hometown so much different than where I lived, or anywhere else I had ever seen, for that matter. But not enough to really explore or investigate it. Even as an adult. After all, the Midwest is boring. If you want interesting landscapes, you go to Utah or Arizona or really anywhere besides what feels like the least exotic place on the planet.

Catch My Drift

Last year, while working on the Land Stewardship Project website, I encountered a term I had never heard before: “Driftless.” Specifically, the “Driftless Area,” a name applied to that “weird” part of southeastern Minnesota and southwestern Wisconsin near where I had grown up.

I wondered why it was called “Driftless.” I assumed it had to do with drifting snow. That would seem to be a logical assumption: from Austin west to the South Dakota border, snow drifting across the windswept prairie is such a problem that there are permanent gates at most entrances to I-90, so the road can be shut down easily during big winter storms. Drifting snow is not as much of a problem farther to the east, where the hilly terrain keeps it (somewhat) in check.

But I found it a bit strange that the area would be called “Driftless” for that reason. And it’s not.

Drift, in geological terms, refers to sediment and rocks left behind by retreating glaciers, which in addition to leaving behind drift, tend to flatten out and otherwise disrupt whatever landscapes had previously existed before them.

It’s no surprise to anyone who understands even the most basic principles of geology that most of the Upper Midwest was covered by glaciers in the last ice age. But, strangely, a large area was completely untouched by the glaciers, bounded roughly by the cities of Eau Claire, Wisconsin on the north; Rochester, Minnesota on the west; Madison, Wisconsin on the east; and the Quad Cities of Iowa and Illinois on the south. This is the Driftless Area, so named because it was untouched by the drift left behind as the glaciers of the most recent ice age retreated.

The Driftless Area is so different, then, primarily for two reasons: first, its landscape and features were not flattened and transformed by the glaciers themselves; and second, because the runoff from the melting glaciers further carved and shaped the already odd landscape. Where the retreating glaciers had left behind prairies dotted with lakes, the untouched Driftless Area was left with deep river gorges, sinkholes, bluffs and monadnocks. The Mississippi River runs right through the middle of the Driftless Area, and its gorge and present course were formed during the melting period.

“That Sounds Like a Desert or Something”

The biggest question I have now is not how did this place get the way it is, but why had I never heard of it before? I’m still just beginning to explore the answer to this new question, but I suspect partly it’s because the geology and geography of the area are still being studied, just beginning to be understood.

A documentary film project is underway, exploring Mysteries of the Driftless Zone. The filmmakers are exploring the area both above and below the surface, studying its strange topography, rock formations, caves and unique life forms that survived the ice age and now exist here and nowhere else.

As this clip shows, they’re also touching on the other mystery of the Driftless Area: how people who live in it (and La Crosse, Wisconsin is as “in it” as you can get) don’t even know it exists.

It’s fascinating how giving something a name can give it importance and meaning. Although I’ve always liked and been interested in this area, I find it much more compelling now that I can think of it as a distinct thing with a name. Why is that?

Geo(logical)-Politics

As another final curiosity, and harkening back to a blog post I wrote after the 2008 election — discussing the fact that the curious distribution of votes for President Obama in the Deep South in that year’s election closely followed the contours of the Atlantic coastline from the Cretaceous Period, 85 million years ago — we have this blog post by Scott Sumner.

While Mitt Romney carried most rural parts of the country except those that have a specific historical or demographic reason to favor the Democrats (African-American voters in the Deep South, non-whites in the Southwest, miners in northern Minnesota’s Iron Range), there was one fairly large, weird blob in the rural Upper Midwest, an area populated largely by white farmers, that is uniformly blue on the 2012 election map… the Driftless Area.

Sumner gives no explanation or theory for why the Driftless Area favored Obama — simply noting that it did. The county I grew up in is on the edge of that blob. It’s always gone for the Democrats as far back as I can remember, but that’s always been primarily because of the strong union presence in Austin. And I’ve always felt that farmers in Minnesota might favor the Democrats more than their counterparts in other states because of our state’s peculiar political history: we don’t have the Democratic Party. We have the Democratic-Farmer-Labor Party, or DFL, resulting from the 1944 merger of the Democrats with the Farmer-Labor Party, a left-wing third party that was fairly successful in the early 20th century and was a key to the enduring progressive populist bent of the state’s politics to the present day.

But that’s a bit of a tangent here… I still don’t really know or even have a theory as to why the Driftless Area — all of it, not just the part in Minnesota — went for Obama. (Especially when you consider that Romney’s running mate, Paul Ryan, is from the Driftless Area, or just east of it.) I just think it’s interesting and… weird, like the place itself.

Into the storm

It began like many other Friday evenings. Our kids were on their way to “Kids’ Night Out,” a 3-hour activity at Lake Hiawatha Park, about a mile from our house. It was going to be a more exciting evening than most, as the whole group was going to walk over to nearby Lake Nokomis Park for a small neighborhood carnival-type event that was going on there.

Meanwhile, SLP and I did what we often do for those few hours: got takeout from a Thai restaurant and went home to watch some Netflix. (What can I say? We’re well on our way to old and boring. It’s even worse if you know what we watched.)

All indications for us were that there might be some rain on the way, and we thought it might force the carnival indoors. Unfortunate, but… oh well.

Around 7:40, just as our show was ending, we got a couple of weather alerts on our iPhones — not the usual Notification Center alerts from our weather apps of choice, but the serious government/emergency alerts the cellular networks send out for things like kidnappings or natural disasters.

There were two alerts, in fact: a Flash Flood Warning and a Severe Thunderstorm Warning. I don’t worry too much about floods where we live (though I realize a flash flood is different), and although the skies had definitely darkened considerably, it wasn’t even raining yet at our house.

We took a look at the weather maps, saw a bright patch of red and orange heading our way, and decided we’d better hurry off to the park to pick up the kids. It looked like we had about 20-30 minutes before the storm would hit.

Turns out, it was just a little bit less than that.

By the time we backed the car out of the garage at about 7:45, it had started raining, and by the time we had gone the mile to Lake Hiawatha (calculating that they had either canceled their plans to go to Lake Nokomis, or that they would have already returned by now) the torrents were unleashed and the trees were whipping in the wind.

We were drenched as we ran to the door of the park building. Locked. No one inside. Damn. They were at Lake Nokomis after all.

The storm was coming on fast, so we ran back to the car and prepared to high-tail it to Lake Nokomis, a trip that was made considerably longer by the fact that the main street between the two parks, 28th Avenue, has been torn up for weeks while CenterPoint installs new gas lines.

But that didn’t really matter. By the time we had gone a block and a half from the park, cars ahead of us at the intersection of 42nd Street abruptly stopped. Cars going on 42nd Street were stopped too, pointing in various unexpected directions.

Then, I saw it. Just ahead on the next block, a large piece of a tree — larger than the small Prius we were driving in, in fact — flew across the street about 20 feet in the air. I looked down 42nd Street and saw more trees down in the road.

Cars around us were stopped, but I had no intention of staying there! I carefully made my way around the obstacles — stopped vehicles and giant tree limbs — and drove on another block. I turned and raced down 41st Street. At least I think it was 41st Street. I wasn’t really taking the time to look.

28th Avenue was still under construction at that point, not that it would have mattered, because half a block away a giant tree was downed on top of the construction equipment, blocking the entire street.

I went on another block, and then another, turning down streets and then turning back as one street after another became impassable. All the while I was looking up, trying to make sure nothing was about to fall on us.

At one point we arrived at a dead-end street that we thought was a street some friends of ours live on, and we prepared to go to their door, but it wasn’t their street after all, so we turned back.

Beginning to panic, we considered going to the door of one of the houses in the area that had lights on, but it didn’t seem like the right choice. While I was sure (or at least hopeful) they’d take us in, then what? Our car might have a tree land on it; we might be stuck there. Then how would we get to the kids once the storm passed?

Somehow having gotten to this point without colliding with another car, flying trees, or getting a flat tire from driving over all of the debris, I noticed we were by a school. What school, I wasn’t quite sure, and didn’t care to figure out. I realized in an instant that we were on the side of the building sheltered from the storm, and that there were no trees around. So I raced across the school’s parking lot, up near the building, where I found a small, fenced-in alcove where a number of other cars were parked. We drove through the open gate and I tucked the car into a corner.

And we waited.

We were wet, and cold, and shivering more from fear than from anything else. We turned on the radio, and listened as the announcers cracked jokes about the irony of how the storm was making it so dark on the longest day of the year.

“Sure,” I thought. “You’re comfortable and safe in your studio in downtown St. Paul. You have no idea what it’s like to be in the middle of this.”

We turned the radio off.

We checked our weather apps. We wanted to call the park, or hoped they’d call us, but in our haste to leave home SLP had left her phone on the kitchen counter, and it was her number the park staff had. Well, that and my old cell number, which now rings at my office.

At this point I finally pieced together the clues that we must be at Roosevelt High School. I could see the lights of the football field peeking up over the side of the building. I realized that all of the other cars parked around us — empty — in the fenced-in area were neither storm refuge seekers nor school employees’ cars. We were in front of the school’s auto shop.

A few minutes later I heard a roar of an engine behind us. Someone in a black sports car was in the parking lot, squealing tires, racing back and forth, doing donuts. At once I thought both that I wished I was as carefree in the moment as they were, but also that it was idiots like that who go out in these kinds of storms and get themselves hurt or killed. We continued to cower in our little Prius, hazard lights flashing, tucked into our relatively safe little corner by the Roosevelt High School auto shop.

The National Weather Service had issued a Severe Thunderstorm Warning for our area until 8:15. We had about 15 minutes to go. I kept turning around and looking at the large tree across the street from the school, maybe 100 feet away. It was my indicator of the current wind speed. Every time its movements would slow, we’d start to wonder if, despite the still-pounding rain, maybe things had tapered off enough that we could either get home or get to the park to pick up the kids. But before we could act, the tree whipped up into a frenzy again.

So we waited.

Even in my fear and panic, I was still myself. There were two doors to the school, a few feet from each other, directly in front of us, numbered 11 and 12. I noticed, and pointed out to SLP, that the “11″ was in Arial and the “12″ was in Helvetica. It’s the ones. I hate how ones look in Arial. I was ready to take a picture of it to post on Instagram, but I thought better of it. SLP was shaking and upset — and so was I — and I think there was maybe even a brief flash in my mind of, “What if the worst happens to us tonight? Is this really the last statement I’d want to leave the world?”

At one point the weather seemed to have calmed enough that we could leave, but as soon as I turned the corner and was beyond the protective wall of the school, we realized that this was not over.

8:15 finally came, but the weather didn’t seem done with us yet, so we waited a few more minutes. At 8:20 we finally pulled out of the parking lot and headed towards… well, where should we go? And where could we go? We debated going home and waiting out the rest of the storm, or going to Lake Nokomis to find the kids.

We decided that we needed to go home first, because who knew if this was over, whether we’d even be able to get to the kids, etc. We knew the kids were far safer in a fallout-shelter-grade Minneapolis park building than we were in our car. I was also hoping the park staff might have left a message for us on SLP’s phone, and I wanted to at least be able to get word to them that we were OK.

I managed to navigate by a circuitous and mildly treacherous route back to 42nd Street, where this all had begun for us. In addition to the large branches blocking part or all of some streets, we noticed several uprooted trees, tipped against buildings. All of the construction signs on 28th Avenue were flattened. 42nd Street itself was relatively clear, so we got back to 34th Avenue and headed towards our house. At one point I had to accelerate and pass someone who apparently was out for a leisurely drive. As we turned onto Minnehaha Parkway, we noticed more damage, although not as bad as what we had seen a half mile to the north, until we got to the house on the corner of our street and noticed its front boulevard tree, a very large, old tree, was uprooted and on the house. At least the house appeared not to have sustained much damage, but something this close to our house? What did that mean for us?

We were lucky. We had a few large tree branches down on our driveway, but our trees were still standing and our house was intact. We got out of the car and cleared a path to the garage, parked the car and ran into the house.

I checked SLP’s phone. Two messages from the park staff, one of which had been left within a minute of us leaving the house. I called the park and let them know we were OK — and exactly what had ensued over the past 45 minutes — and that we were on our way.

I elected to take 50th Street to Lake Nokomis and loop around the back of the park building, and I’ve never so greatly exceeded the speed limit on 50th Street in my life. We were at the park within 3 minutes, and I was glad I’d taken the route I had. Just to the west, the parkway was blocked completely by a large tree, and there were a few uprooted trees in the park by the building where the kids were waiting for us. I’m not sure we’d have even been able to get through if we’d gone another way.

We ran into the building, embraced the kids, and realized that neither they nor the park staff, who greeted us with smiles and laughter, had any idea of the extent of what had just happened, nor what it felt like to witness it through a car windshield.

We rushed the kids into the car and raced back home. More storms were on the way, we had seen, and we weren’t about to repeat the last hour.

At 8:45, we were home. It was over. Barely more than an hour had passed, but it’s an hour that will be burned into my memory for years to come.

I know now just how lucky we were. We were in the middle of the storm’s path of destruction, as it was happening, in a tiny car. We’re safe, our car is fine, our house is unscathed. Many others in the city and the surrounding metro area weren’t so lucky. I haven’t heard any reports of deaths or injuries, but there’s plenty of damage, and hundreds of thousands of people were without power for at least part of the night. There were gas leaks and fires.

And there were tireless and fearless first responders — police, firefighters and EMTs — not to mention crews from Xcel and CenterPoint who were on the scene restoring power and fixing gas lines. I have rarely had more appreciation for their dedication and courage than I did last night.

This morning, SLP and I took a walk around our neighborhood to survey the damage. Our neighborhood was lucky… the damage was significantly worse about a mile to the north, and also farther to the east. But these photos show how bad it was even within a half mile of us.

jpeg

jpeg-1

jpeg-2

The Raspberry Pi Arcade Project: An Interlude

I’m currently at Part 8 of my Raspberry Pi Arcade project. That is, my own Raspberry Pi Arcade project is at the point of what I have planned as part 8 in the blog series. The blog series itself is stalled out after Part 3. And while the risk of getting too far ahead of myself is there — I don’t keep copious notes, so by the time I write a blog post my own project is so far removed from the topic of that post that I may forget key details — the real threat to the project is coming from what I’m experiencing around my own “Part 8″: polishing the user experience.

I’ve come to realize that while the Raspberry Pi is unequivocally an awesome piece of technology — a complete computer that fits in an Altoids tin, runs on a cellphone charger, plugs into your TV and costs less than $50 — it’s not a powerful computer.

Yes, I always knew it was not a powerful computer. And for a lot of applications it doesn’t need to be. But the main thing you gain by sacrificing that power is its diminutive size. It fits anywhere.

The thing is… for some applications you don’t need a computer to be tiny. And if there’s any application where you can afford for your computer to be huge, it’s a full-size arcade cabinet. I originally had visions of opening up my X-Arcade Tankstick and mounting the Raspberry Pi inside it. That would be cool — amazing, in fact — if I weren’t also mounting the Tankstick onto a full-size cabinet.

So… as I struggle with tweaking settings in my advmame.rc configuration file at the command line, trying to eke every last bit of processing power out of the Pi just so it can render simple early ’80s video games at full screen, I begin to wonder why, and whether or not it’s worth it.

Clearly my emulation dreams would be better served by powering my cabinet with a more robust PC. And the whole thing would probably be a lot easier to set up.

But as I stayed awake last night until well past 1 AM, sitting in front of my living room television, typing arcane commands on a black screen in that classic ’80s DOS font, I realized that this experience is part of what it’s all about. Not just having an arcade cabinet, but hardcore geeking out on Linux. Using a computer the way I used my first computer back in the 1980s.

As much as I’ve embraced the “it (usually) just works” ethos of iOS and modern mobile computing devices, app stores and touchscreens and nary a file system or command line in sight, sometimes I miss computing the old way, when it was a tinkerer’s hobby.

That’s what the Raspberry Pi Arcade project is really about. And maybe it will be the stepping stone to even more creative electronics projects with the Raspberry Pi as their brain. I could see, at some point in the future, replacing the Raspberry Pi in my arcade cabinet with a more powerful PC running Ubuntu Linux, and finding a new, even crazier project where the Pi would be right at home.

The Raspberry Pi Arcade Project, Part 3: Get Raspbian

Now that you have your Raspberry Pi and assorted accessories, it’s time to get it up and running. The Raspberry Pi doesn’t have a hard drive… that’s what the SD card is for. The Raspberry Pi includes an ARM CPU, so in principle any operating system that has been ported to the ARM architecture should be able to run on it.

In practice… I’m already in over my head trying to explain CPU architectures. But you don’t need to know anything about that to get your Raspberry Pi running. Several “flavors” of Linux have been ported and modified specifically to work well with the Raspberry Pi but the gold standard is Raspbian, a variant of the popular Debian distro, and the preferred choice for starting out on the Raspberry Pi. If you really know what you’re doing and have very specific requirements, other OSes may be preferable over Raspbian, but if you just want to get your Raspberry Pi up and running with a stable, easy-to-use Linux, Raspbian is the way to go.

Get Raspbian

The first step in setting up Raspbian is to download it. This of course assumes you have another computer to download the disk image to. Any Windows, Mac or Linux PC should do. The key is having a PC with an SD card slot, because you’ll need to use it to get Raspbian onto the SD card.

If you don’t have a PC with an SD card slot, or you just don’t want to mess around with it, you can buy an SD card preloaded with Raspbian for not much more than the cost of the card itself. Note that the preloaded SD cards are probably only going to be 4 GB however, not the 16 GB card I recommended in Part 2 of this series.

Assuming you’re going to install Raspbian yourself, the first thing you need to do is download it. This download link includes a few other options for different OSes that will also work on the Raspberry Pi, so if you are inclined to ignore my advice, check them out!

Install Raspbian on Your SD Card

Once you have Raspbian downloaded, you’ll need to install it on your SD card. The process for doing this varies depending on whether you’re on Windows, or using a UNIX-based OS like Mac OS X or Linux. More detailed Windows instructions are available on the download page I linked to above. Being a die-hard Mac user, I am going to describe the Mac/Linux process, which I recommend doing at the command line.

1. Insert the SD card into your SD card slot.
This should be fairly self-explanatory. On most MacBook Pro’s the SD card slot is on the side near all of the other ports; on other Macs like my Mac mini, it’s in the back. Not all Macs have an SD card slot, e.g. the MacBook Air. If your computer doesn’t have an SD card reader, USB add-ons are available.

2. Open Terminal and become a superuser.
If you’ve never used Terminal before… well, to be honest, if you’ve never used Terminal before, this whole project is going to be a bit of a challenge. But solider on! Terminal is located in your /Applications/Utilities folder. It’s your way to access the command line on the Mac. You’re going to be doing some things that require root (“superuser”) access. The “safer” way to do this is to prepend any of those commands with sudo but I prefer not to mess around with that. Type sudo -s Enter to enter superuser mode. Note the command prompt will change from $ to #. Now you can do some real damage. Consider yourself warned. (And do not, under any circumstances, type rm -Rf / ever. For real.) Proceed at your own risk, or just prepend commands with sudo along the way if the system says you don’t have permission.

3. Identify your SD card in the filesystem.
In Terminal, type df Enter. You’ll get a list of all of the disks (“volumes”) on your Mac. You’re looking for the SD card. The name it displays in the Finder will be shown in the far right column, “Mounted on”. But you need to know what its name is in the “Filesystem”, the far left column. On my Mac mini it comes up as /dev/disk2s1. You don’t need to worry about the s1 part; that’s the partition. We just need the disk number, e.g. /dev/disk2. Make note of this for future reference. Now you need to unmount the volume so you’ll be able to write to it. Take a look at the disk name under “Mounted on” (starting with /Volumes/). Type umount -f [disk name] Enter, replacing [disk name] with exactly what was listed under “Mounted on.” Important: if there are any spaces, you’ll need to edit the name and put that portion, between slashes, in quotation marks. For example, if the name is /Volumes/My Awesome SD Card you’ll need to type umount -f /Volumes/"My Awesome SD Card" instead. And if this doesn’t work, check here for another tip on unmounting the volume.

4. Identify your Raspbian disk image.
Now you want to switch to the directory where your downloaded Raspbian disk image is. This is likely to be the Downloads folder in your home directory. If so, then in Terminal you’ll type cd ~/Downloads Enter. Then type ls -al Enter to see a list of the files in this directory. You’re looking for one with a .img file extension. In my case it’s 2013-02-09-wheezy-raspbian.img. If you don’t see that, but you see something similar with a .zip extension, you just need to unzip it. Type unzip [filename] Enter (using the real filename, of course) and then type ls -al Enter again, and you should see another file with the same name but ending in .img. That’s the one.

5. Write the image to the SD card.
Now that you know the name of your Raspbian disk image and the disk you’re writing to, you can run the dd command to copy the image over. This command includes a lot of different options for setting the block size, etc. The kinds of technical details about computers most of us haven’t thought about since the early days of MS-DOS, if ever. In my experience these settings don’t appear to matter here, however, as I was able to prepare my SD cards with only the basic parameters of if (input file) and of (output file). Here’s the command I would use in my exact situation. Adjust your if and of according to your results of steps 3 and 4 above.

dd if=2013-02-09-wheezy-raspbian.img of=/dev/disk2

Then hit Enter and… wait.

And wait.

And wait.

This is the command line. You will get no feedback that any progress has been made, or that anything is happening at all. So just leave Terminal open and go about your business. Some substantial amount of time later (in the realm of a half hour, in my experience), the process will have completed, and you’ll get your command prompt again. That’s how you know it’s done. Now, go back to the comfortable confines of the Finder and see if the SD card is showing up as a mounted volume. If it is, eject it. Now you can take out the SD card and insert it into your Raspberry Pi. You’re ready to power up!

Next time… powering up your Raspberry Pi with Raspbian for the first time.

The Raspberry Pi Arcade Project, Part 2: The Essential Gear

The first thing you need when building your Raspberry Pi Arcade is… well… a Raspberry Pi. When they were first released, they were hard to come by, but now they’re readily available in the U.S., for about $45, on Amazon.com.

Unfortunately the Raspberry Pi, by itself, is completely useless. Fortunately, the other stuff you need to make a Raspberry Pi work is also fairly inexpensive and readily available on Amazon, so with an expenditure of about $150 and a few days’ wait for UPS to drop everything at your door (and a TV, which I’ll assume you have), you’ll have your complete Raspberry Pi set-up.

While this blog series is focused specifically on building an arcade cabinet powered by the Raspberry Pi, this post will serve well as a general introduction to the basics you’ll need (or at least want) to put together a core Raspberry Pi setup for any purpose.

The bare minimum you need to use a Raspberry Pi is:

  • Raspberry Pi
  • 5V 700mA (or greater) Micro USB power supply
  • HDMI (or RCA video and 1/8-inch stereo audio) cable
  • 4 GB or larger SD card
  • USB keyboard and mouse
  • Ethernet cable

Practically speaking, however, you’re going to also need the following:

  • TV or monitor with HDMI or RCA audio/video input
  • PC or Mac with an SD card slot (or get your SD card with Raspbian Linux preinstalled)
  • USB WiFi adapter (instead of Ethernet)
  • USB wireless all-in-one keyboard/trackpad (instead of separate keyboard and mouse)
  • USB hub (at least 3 ports; powered is better)
  • A case

I strongly recommend HDMI instead of RCA video if possible, as HDMI delivers an all-digital signal for a much clearer picture. I have not tested the Raspberry Pi with RCA video output, so from here on out we’ll just assume you’re using HDMI.

While you don’t need a case for the Raspberry Pi, it sure looks nicer (and will be better protected from damage) inside one.

Get the Goods

As noted above, everything you need is available on Amazon, which is where I got all of my components. My preferred options for each are shown below, but bear in mind that a lot of these exact parts and suppliers come and go, so the links may not continue to work in the future. Where this is especially a concern, I have included general notes on what to look for when picking an alternative.

This list cuts to the chase, and includes the things I think you need, including the WiFi adapter, wireless keyboard/trackpad combo, and USB hub.

TV not included.

(All images shown here are from the respective Amazon product pages. And, full disclosure, all of the Amazon links herein include my affiliate code. It won’t cost you any more, but if you use these links Amazon will throw a few pennies my way. Thanks!)

raspberrypiRaspberry Pi
There are a few different options for the Raspberry Pi itself, but don’t mess around: get Model B Rev. 2.0, which adds Ethernet and a second USB port missing from Model A, resolves a couple of technical issues with the first versions, and bumps up the built-in RAM from 256 MB to 512 MB.

power5V 700mA Micro USB Power Supply
There are lots of different options for these power supplies, many of which seem to come and go quickly on Amazon. But don’t sweat it. This is a de facto standard charger for many cell phones these days. As long as the charger is 5 volts with at least 700 milliamps and a Micro USB connector, it will power the Raspberry Pi, regardless of the brand or what devices it is advertised as working with.

hdmiHDMI Cable
Don’t get me started on HDMI cables. An HDMI cable is an HDMI cable. The only thing you need to concern yourself with is how long it is and whether or not your Raspberry Pi will be that close to your TV. Well, that and whether or not you’re dealing with a reputable seller. That’s why I like to go with the Amazon Basics cable. It’s cheap, it works, and it’s direct from Amazon.

sdcardSanDisk Extreme 16GB SD Card
Unlike HDMI cables, there is a difference between SD cards. You want one that’s fast, reliable, and spacious. 4 GB is considered the minimum for a Raspberry Pi, but I like to go with 16 GB, since it seems to be today’s best balance between size and affordability. (Translation: the price difference between an 8 GB and a 16 GB SD card is much smaller than the price difference between a 16 GB and a 32 GB.)

wifiEdimax EW-7811Un USB WiFi Adapter
There are a few options here as well, but I love this particular adapter because it’s cheap (about ten bucks) and tiny… which is essential for the Raspberry Pi. Don’t worry about software. It just works… or at least, it will once you get Raspbian installed (see my next blog post for that) and run the included WiFi setup app.

keyboardLogitech K400 Wireless Keyboard/Trackpad
OR FAVI Entertainment SmartStick Wireless Keyboard/Trackpad

It didn’t take long after I got my Raspberry Pi to realize two things: 1) I want as few wires connected to it as possible, and 2) two USB ports get filled quickly. The second is mitigated somewhat by using a USB hub, which you’ll eventually need for the X-Arcade Tankstick in the MAME cabinet project, but even if you’re not doing that, without a USB hub, the only way to use a Raspberry Pi with WiFi is to get an all-in-one keyboard and trackpad.

For practical purposes, the full-size keyboard of the Logitech K400 is the only way to go. The K400 is cheap plastic, but hey… it’s only about $35, and it works. I love it.

On the other hand, if you’re really trying to stay true to the micro-sized spirit of the Raspberry Pi, the FAVI SmartStick or something similar may be the only way to go. About the size of a TV remote control, the SmartStick includes a reasonably usable thumb keyboard and built-in mini trackpad, with the added bonus of a laser pointer so you can mess with your cat when not playing with the Raspberry Pi. In practice I’ve found the SmartStick is a bit touchy… thumb typing on it often requires looking down, and sometimes key presses infuriatingly don’t register. But it’s still fun to have.

hubBelkin USB 2.0 4-Port Powered Ultra-mini Hub
This is the one item on the list that I don’t actually own, as I am relying on an older USB hub I already had lying around. But if I were to buy a new hub specifically for this project, this is probably the one I’d choose. In practice, so far I have been able to do what I need to do with an unpowered hub, but a lot of what I’ve read on the subject suggests a powered USB hub is preferable for use with the Raspberry Pi, to keep the Pi itself from overheating.

caseSB Raspberry Pi Case (assorted colors)
There are a ton of Raspberry Pi cases out there, but this one is my favorite, because it’s nearly indestructible, it’s super-tiny, the Raspberry Pi snaps snugly into it with no tools, it includes slots for all connectors plus two mounting screw slots, and best of all comes in a variety of translucent colors, plus black and white.

I currently own two Raspberry Pi’s, and I have one of these cases for each, one in pink and one in orange.

The Bottom Line

So, how much is all of this going to cost you? I created an Amazon “Listmania!” list (with only the Logitech keyboard, not both), and the subtotal is $143.86. Not bad for all of the essentials (except a display) you need to run a reasonably capable general-purpose Linux computer.

Next time we’ll take a closer look at the SD card, or more specifically, what’s going to go on it: Raspbian, a modified version of the popular Debian Linux distribution that’s been tailored for an optimal experience on the Raspberry Pi.

Update: It’s come to my attention that the Belkin USB hub I have recommended actually is not powered. I will update this post in the near future with an alternate, powered hub recommendation.

The Raspberry Pi Arcade Project, Part 1: Introduction

If you’re bothering to read this, I probably don’t need to explain either the Raspberry Pi or emulators (specifically, MAME and Stella), but for the sake of completeness, I will.

Raspberry Pi

The Raspberry Pi is a tiny, inexpensive Linux-based computer that, after years of anticipation, was finally released to the public last year. It’s designed to be versatile and to encourage creative, educational programming and electronics projects.

Emulation Software

Emulators are software programs designed to run on modern computers that emulate the physical hardware of older, simpler video game and computer systems. When combined with ROM files, the programs that ran on those old systems, it is possible to play near-perfect recreations of those classic games on modern equipment.

Of course, while the emulators themselves are (usually) perfectly legal, there is a (charcoal) gray area of legality regarding the distribution and even the possession of these ROM files. Legally, you should only possess ROM files for games you physically own. In the case of home video game consoles, that would be the original cartridges or disks. For arcade games, that would be the actual hardware cabinet with all of its electronic guts… or, at least, the ROM chip from said cabinet that contains the actual game program. (I do actually own an original Asteroids arcade cocktail table, and a very large collection of original game cartridges for the Atari 2600, 5200 and 7800; the Intellivision; the Nintendo Entertainment System [NES] and others. These will be the focus of my efforts with this project.)

There are numerous emulation programs, representing dozens of arcade and home video game systems, and most have been ported to a variety of different modern platforms, including Windows, Mac OS X and Linux. My interest primarily lies with the classic games of the late 1970s and early 1980s; specifically, arcade coin-op games which are emulated by the Multiple Arcade Machine Emulator (MAME) project, and the Atari 2600 which is emulated by the Stella project.

One of the dreams of many aficionados of early arcade games is to own a “MAME cabinet” — a real arcade game cabinet (or modern recreation thereof) with a modern PC and display inside, programmed to work with an arcade-style control panel, and loaded with emulation software.

The Project

I’ve wanted to build a MAME cabinet for years. The biggest hurdle for me has been a willingness to dedicate an expensive (or even semi-expensive) and significantly overpowered PC to use solely as the “brains” of such a cabinet.

I’ve also been interested in the Raspberry Pi ever since I first heard of it. The idea of a credit card-sized Linux computer that could be embedded in a creative electronics project sounded amazing! But possessing a woeful lack of knowledge of the circuit board-level details about electronics, and being equally woefully inept at either soldering or construction, I wasn’t sure what I could really do with it.

But then it hit me… I could build a MAME cabinet! What’s really great about attempting a project like this today is that you don’t really need to solder or build anything. The X-Arcade Tankstick is an (almost) plug-and-play, arcade-quality control panel, and the Xtension Arcade Cabinet is a prefabricated arcade-style cabinet designed to work perfectly with the Tankstick, the PC of your choice, and a 22-inch TV or LCD monitor to create a MAME cabinet that’s still a fun DIY project without requiring the same levels of skill that have previously made this kind of thing unapproachable for me.

The Road Map

I am already well underway with this project, but from the beginning it has been my intention to create a series of blog posts detailing the process, so others who, like me, have an intermediate-or-better level of knowledge of command line Linux; a rudimentary understanding of electronics — at least, which plugs go into which ports; and above all a deep and abiding love of classic ’80s video games, can make this kind of thing happen.

I owe a huge debt of gratitude to Shea Silverman, who is several steps ahead of me in working with and blogging about using the Raspberry Pi for emulation, but whose blog posts come with a tad steeper of a learning curve than what I am hoping to lay out for the readers of these posts. I’ll tell you what I think you need to know to make this stuff work, but for a more in-depth exploration of the details, please check out his blog.

Now then, here’s an outline of the posts I intend to include in this series. (I’ll update this page to make each a clickable link as the posts get published.)

Part 1: Introduction
Part 2: The Essential Gear
Part 3: Get Raspian
An Interlude
Part 4: Up and Running with Raspbian
Part 5: Emulator Set-up — Stella
Part 6: Emulator Set-up — MAME
Part 7: Configuring the X-Arcade Tankstick
Part 8: Polishing Your User Experience
Part 9: Preparing the Cabinet
Part 10: The Finished Product

How to keep Internet Explorer from displaying your site in “Compatibility View”

Fortunately this is an edge case for me, but… there’s a time for everything. And that time was today.

If you build websites using modern, open standards-based techniques, the last thing you want is to have your Internet Explorer-using visitors see your site in the dreaded “compatibility view”. This monstrosity was created by Microsoft with the advent of IE8, to allow sites (mostly corporate intranets) that require the quirks of IE6 to still look like they’re supposed to when viewed in IE8.

The problem is, IE6 sucks, and it makes modern sites look terrible. So if your users accidentally view your site in compatibility view, it’s going to suck too.

The good news is, it’s easy to force IE8 and later to display your site the way you intended. You can disable compatibility view with this simple meta tag:

<meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE" />

(Source: http://stackoverflow.com/a/10365780)

How to get iWork (Pages, Numbers, Keynote) apps to stop defaulting to iCloud when saving

Ever since I semi-fully embraced iCloud, I’ve found that the iWork apps — Pages, Numbers and Keynote — always default to wanting to save every new document in iCloud, which I never — well, OK, almost never — want to do. It’s fine that it’s an option, but I want the default to be saving to my local hard drive (which, actually, means saving to my Dropbox account).

It didn’t take much effort to find this thread on Apple’s support forums, but the first suggested solution — turning off “Documents and Data” in System Preferences → iCloud — seemed draconian. With this option you can never sync your documents to iCloud.

A little further down the thread I found the “real” solution, courtesy of “Bernie_uk”, which was important enough for me to want to share here.

It requires opening up Terminal, but it’s not too scary. You just have to run this command:

defaults write NSGlobalDomain NSDocumentSaveNewDocumentsToCloud -bool false

This command doesn’t turn off anything in iCloud; it just tells the system that your default should be saving files to disk, not to iCloud. Note that since this is a global setting, it will affect not just iWork, but any other apps that use iCloud’s “Documents and Data” syncing. (I guess.)