Running Teamspeak 3 Server As a Regular User

In my previous article on How to run Teamspeak3 on Digital Ocean the instructions have you create a teamspeak3 user and change ownership of the files. I noticed in some of the comments over there that people noticed it was running as root, not the greatest thing for security.

I noticed my server was also running as root, here’s how to fix it if you used my instructions:

Shut down Teamspeak:

sudo service teamspeak3 stop

Remove the /etc/init.d/teamspeak3 soft link:

sudo rm /etc/init.d/teamspeak3

Now edit /etc/init.d/teamspeak3 and set the contents to this:


su -c "/usr/local/teamspeak3/ $@" teamspeak3

Set the file to be executable:

sudo chmod u+x /etc/init.d/teamspeak3

Fix permissions, many of the Teamspeak files are probably owned by root now which would prevent the server from starting:

sudo chown -R teamspeak3:teamspeak3 /usr/local/teamspeak3

Start the server back up:

sudo service teamspeak3 start

Use your client software to connect and make sure everything is operating properly and you’re done.

Embarassing Old Code

The Inspiration

We just switched to Slack at work and a friend created some integrations using PHP. This reminded me of a personal PHP project I’d worked on and thought I should dig it up.

The Setup

Back in 2005 I was doing C# WinForms work for a day job and just dealing with falling out of love with Perl. I hadn’t done any serious web development since college. I got into GTD pretty heavily and was looking around for tools that I could use anywhere. Of course a web app was the best solution for that time since there really wasn’t much in the way of smart phones or devices out1.

I found a great project run by BSAG2 called Tracks. It was built using Ruby on Rails. I didn’t know Ruby or Rails so of course the logical thing to do was to rewrite it in PHP.

I’ve been using Rails off and on from 2008 to 2012 and from 2012 mostly full time. Ruby is now one of my favorite languages and I think this project helped me understand what a good web framework Rails is.

Let’s see what gems we can discover in this treasure trove of old code.


Overall this code doesn’t match my current sense of code cleanliness. There’s a mix of tabs and spaces everywhere and tons of trailing whitespace. There’s lots of dead code, mostly around database access. It looks like I was working on multiple different techniques at once.

$query = $this->db->prepare('UPDATE todos SET context_id=:context_id, description=:description, notes=:notes, due=:due, project_id=:project_id WHERE id=:id');
$query->bindParam(':id', $id);
$query->bindParam(':context_id', $context_id);
$query->bindParam(':description', $description);
$query->bindParam(':notes', $notes);
$query->bindParam(':due', $due);
$query->bindParam(':project_id', $project_id);

About the only thing I have going for me in this code is that I’m doing variable replacement in my SQL statements properly so it’s at least not one giant SQL injection attack.

Project Structure

Project Structure

Man, I had no concept of organization in this thing.

The tpl files are actually just PHP files I was using as templates, I guess the idea is that they were kind of like erb’s. I remember thinking how clever I was to use PHP as the templating language (because that’s what it was developed for) and not something like Smarty.

My Idea of MVC

<?php while($row = $completed->fetch(PDO::FETCH_ASSOC)): ?>
    <td valign="top"><img src='<?=$c->BASE_URL?>/img/done-checkmark.gif' alt="done checkmark" /></td><td valign="top"><?=htmlentities($row["description"],ENT_QUOTES, 'utf-8');?> (<?=$row['context_name'];?>, <?=$row['project_name'];?>)</td>
<?php endwhile; ?>

So… there’s really no division between models and views. I have one giant model that sets up the queries, the views actually execute it and use the raw results.

I remember trying to figure out why people needed models since if I wrote them it would basically just be querying the database and filling in an object with what I already had in my associative array.

class AgingController extends MvcController
  public function route($options, $tpl)
    global $db;
    $model = new TodoModel();

    $tpl->set('title', 'Portage - Aging');

    $body = & new Template('aging.tpl');
    $body->set('c', Config::singleton());
    $body->set('completed', $model->getLastCompleted());

    $agingQuery = $model->getSortedByCreated();

    $body->set('todos', $agingQuery);

    $tpl->set('content', $body->fetch());


My controllers at least load the view and combine some of the data and inject it into the views. I can appreciate some of the magic that Rails does by automatically matching views to controller actions after seeing how much boiler plate code is copied everywhere in here (not that I couldn’t have done better with the language that I had…).

My Crazy Router

else if($options[$c->offset] == "todo")
  if($options[$c->offset+1] == "edit")
    $todoEdit = new TodoEditController();
    $todoEdit->route($options, $tpl);
    if($options[$c->offset+1] == 'submit')
      //set some cookies
      setcookie("last_project", $_REQUEST["project_id"], time()+$c->COOKIE_TIMEOUT, "/");
      setcookie("last_context", $_REQUEST["context_edit_id"], time()+$c->COOKIE_TIMEOUT, "/");

    $todo = new TodoController();
    $todo->route($options, $tpl);

my IndexController.php3 contains a giant nested if statement that handles all the routing for the site. I remember one of the issues I ran into was trying to figure out where I was. If I was hosted at vs I had a global offset variable to figure out where the parts of the URL I cared about started (i.e. /todo/12). I spent a good bit of time reading CakePHP source code trying to figure out how they did it (I obviously never got around to fixing that up).

Death of a Project

I abandoned the project sometime in 2010 then I learned Ruby on Rails and how to deploy it. I used the main Tracks project for quite a while until I setup a task syncing system using gitdocs. Now I’ve moved onto using Taskpaper and Dropbox.


  • I’ve obviously come a long way in my development as a programmer / software engineer / software architect.
  • It’s nice to keep these bits of old projects around as yard sticks with which to measure growth and progress.
  • I hope I see just as much growth in my coding style in another couple years.
  1. My Handspring Visor Platinum didn’t count. Though graffiti worked pretty well.

  2. I even managed to contribute back a little code (my first ever OSS contribution).

  3. Redundant comment! “Redundant comments are just places to collect lies and misinformation.” - Clean Code

Seven Years is too Long

I was at my last company for seven years. I moved between locations, projects, positions and responsibilities but I was at the same company for seven years, not really even thinking about moving.

I worked for one of the major defense contractors and at the time it was fun and we were doing interesting work. It was mostly short lived research contracts for the service labs and the DoD so it was always something new. It stopped being fun though when the money started to dry up and belts started to get tightened. I could see the writing on the wall and it was time to make a move1.

My interview skills were rusty, my resume was completely neglected and it took time to get everything in line before I started breezing past the phone screens and into interviews at companies I could really work for.

Looking back now after a year working at my new company here’s what I would’ve done differently.

1. Know the Companies in the Area

Keep up with what the great companies are in the area, the technologies they use and the kind of positions they look for the most. Shop for companies that match what you want as far as benefits, culture and your skill set. If you target a specific set of companies you know already match what you want you will save a lot of time by not peppering Monster with a million resumes and getting a ton of replies from people who don’t know how much you’re worth.

Go to the user groups in your area. If you want to stay in the same technologies or branch out, it’s a perfect way to find out who is in the area. Many companies sponsor these as a way to recruit new employees. This is also a great way sharpen your presenting skills. You can start with a lightning talk and move from there.

2. Interview at Least Every Other Year

You might not be ready to leave your current company but you should at least stay in practice. Most programmers have enough recruiters calling that you could answer the phone every once in a while and do a phone screen and see how it goes.

Doing this regularly helps you overcome the interview jitters.

3. Practice

  • Find a sample interview programming question on the web and work through a few with a timer.
  • Review the Big-O notation of some of the common algorithms.
  • Work with a whiteboard to talk through an overview of some software you wrote recently.

4. Perfect Your Pitch

You know the companies now, you’ve talked to a few people, now change your pitch.

Incorporate what you’ve learned from your practice interviews. For me people were worried that I worked on some ancient radar system mad had no relevant skills. I emphasized that I worked for a research group and worked on new technology like Ruby on Rails and did networking research.

Another important area I had to work on was how to concisely describe the projects I worked on and how to taylor that description to technical and non-technical people. This is where face time is great, if you start seeing someone’s eyes start glazing over while you’re telling them about the distributed test infrastructure you setup and the long list of all the technologies you used you know that you have to change tact.

5. Time Your Move

Don’t leave a job you love for no good reason but also don’t blindly trust that they are paying you what you’re worth and will take care of you for the next forty years. Dan Benjamin of 5by5 and Quit! fame emphasizes this point: when push comes to shove, if they have to let you go they will.

If you see the business going downhill or in a direction you don’t agree to you can make your move quickly before everyone sees the writing on the wall and starts peppering local companies with resumes. You won’t have to blindly apply to all the job board postings you can if you’ve already established good contacts in your local user groups and know exactly for which companies you work.

6. Wear a Suit

Make more excuses to wear a suit or get dressed up. This will make you feel more comfortable and less out of place when you do have to put one on to go to an interview. It will also limit the surprises when something doesn’t fit or the TSA zipped your suit pants into your suitcase ruining your favorite suit 2.


Being on top of the above items can save you months worth of hassle and get you onto your next job more quickly and painlessly.

  1. About all I got right was the timing.

  2. Not that I’m bitter or anything.

Bought and Unread Books

The Inspiration

I also have a lot of books I’ve purchased and barely cracked the binding. This is an awesome goal to shoot for so I started thinking about how I would do it, here are my thoughts.

My Books

Scary Books

These aren’t separated out but they warrant talking about. These books have been raised to such a level through fame and infamy that I’m scared to touch them. GEB and SICP and are firmly in this category for me. So is The Annotated Turing, even though Charles Petzold is a great writer (go read Code), then chapter two starts talking about transcendental numbers and degrees of infinity my long seated math fear comes to the surface.

I need to get over this fear and dive into one of them. If you’re in the Philadelphia area the Clojadelphia user group is starting a SICP study group set to meet Febuary 5th.

The Projects

Project Books

This pile mainly consist of books that I need to do projects and exercises along with reading the content to really learn.


Reference Books

I will probably never read these books straight through but it would be good to skim through so I know what is in them so I can use them more effectively.1

Branching out

Branching Out Book

This stack is mostly about reading outside my field though somewhat tangentially. I tried to start the Black Swan a while back but couldn’t get into it. I also got about half way through GEB on vacation one year but got pretty lost when I picked it up again a few months later.

Get organized

Get Organized Books

Here’s my attempt to get better organized and learn more about project management. I’ve read through David Allen’s Getting Things Done several times but I can always read it again. It’s packed full of useful information and you don’t have to take the whole system as written, you can start using some parts and go from there.


Sci-Fi / Fantasy Books

I’m actually surprised that this stack is so short. I really thought I had way more fiction books in the physical / already bought queue (not shown here: Catch 22).

Math and Poor Perl

Math and Perl Books

Here are a few math books I’ve meant to read. I used a fair bit of linear algebra in my masters program even though I sucked at it in my under grad days. Discrete math always seemed the most relevant but this class was during a too-many-credits-in-one-semester haze so I’d love to work through it again.

The Hawking book was a random purchase and while I’ve skimmed it I can’t say I’ll ever read it cover to cover.

And then there’s Perl. It’s not in the reference category because i just don’t do perl anymore though it was the first programming language I fell in love with. I can’t get rid of this book2 because I spent so much time in this book.

The Work Shelf

Books at Work

I used to have almost all my books at work at my last company and almost never used them. This is the subset I decided to take in or work bought for me. I think they pretty much match up with the categories I already setup.


I think the goal is still achievable, especially if you consider not reading the reference stack though the Project books would be a bit intense to work through in a single year.

Also, I think Fogus’ Reading for the Rushed also applies to all of these books. If I don’t find Black Swan interesting I should probably just donate it instead of suffering through it, for example.

  1. I bought the AOCP in college for way too much money relative to how much I had in my bank acccount. I didn’t get to use it until my master’s level algorithms course but it did come in handy (finally).

  2. Much like the TI-99/A programmer’s manual and my COBOL book.