Hey everyone. We at StackVM just finished recording the 2nd demo video. The 2nd video shows all the cool new features we have recently built - user login system, chatting and sharing of virtual machines by just dragging and dropping. Also this time James Halliday joins me from Fairbanks, Alaska!

Here is the video #2,

StackVM brings virtual machines to the web. Join #stackvm on FreeNode to discuss!

If you haven't seen the first video, see my StackVM startup announcement post!

During the past few weeks we have also written two new node.js libraries for use at StackVM:

We did not demo gifcasts in this video but I am going to do a separate video in the next week or two showing just that. They're pretty awesome!

In a few weeks we'll also post the 3rd demo video. In that video we have planned to show virtual network editor that allows to network virtual machines by just dragging and dropping! Be sure to subscribe to catonmat's rss feed and follow me on twitter to know when the video is out!

See you!

Ps. Join #stackvm on FreeNode to discuss StackVM with me and James! We're there 24/7!

Hey everyone,

I have exceptional news - I am doing a startup together with James Halliday!

I met James on FreeNode several years ago and it turned out that we had very similar ideas about doing great hacking. So we teamed up as equal co-founders to do a startup. We're on different continents but we use IRC, GitHub and WeDoist to get stuff done!

Check out an early demo of our software:

StackVM brings virtual machines to the web. Join #stackvm on FreeNode to discuss!

The startup we're doing is called StackVM. StackVM makes virtual machines much more accessible over the web, makes them easier to use, and makes them embeddable in webpages (like putting a virtual machine in a blog post). This is just the first step that we're starting with. Next we're making networking between them very easy, just drag and drop to create any virtual network topology you wish, with firewalls, switches, etc. (fun for hacking competitions and learning networking). Then we're making what we call "vmcasts" - much like a screencasts, except the computation is recorded, meaning that at any point you can break into the playing vmcast and change the course of computation (and return back to it later).

Our plan is to host the virtual machines and our awesome software for you, so that you don't have to worry about anything. We'll make sure it all works! At the moment we're actually already at our third major iteration of the software.

Here are a few use cases:

  • Suppose you're selling software and you want your users to try it before they buy it. Perfect use of StackVM - put your software in the virtual machine and embed it on your products page. The potential customers can try your software before they buy it right from your website!
  • Suppose you're an application developer and have written a program that should work cross-platform. You can easily rent 10 virtual machines with Linux, Windows, MacOS, and other operating systems and test your software. Just drag and drop it into the virtual machines, and you can test your software!
  • Suppose you want to teach someone how to work in Perl in a series of blog posts (like I do), you can embed the terminal with a vmcast in your blog post, and everyone can follow your tutorial, and also try out the examples interactively, in a real shell!
  • You can build a virtual honeypot network and have hackers break into it, then analyse how they did breakins. Or, you can build a huge network and learn routing and networking concepts!
  • Suppose you want to share your work with a group of people. You can easily do it in stackvm! Just send the other people link to your VM and they can connect to it with any web browser. They'll be able to see what you're doing, comment on your work, and if you allow fix your bugs (think pair programming!)

Hosting virtual machines requires a lot of infrastructure, so we plan to start collecting revenue as soon as possible with affordable paid user accounts. We're not going to do the common nonsense among startups of first building up the project for years and only then trying to figure out how to make it profitable. We're going to offer virtual machines together with an awesome interface and features to them as a monthly paid service from the day we launch. We're also going to have an open API to our software, so that you can build on top of it or customize it (for example script virtual machines to do something specific).

We're also testing out the idea of complete openness with this startup. It's going to be 100% open-source and 100% idea-open, meaning that anyone can read what we're up to, and run our code if they want to run stackvm on their own. So far we have shared all the code on github (my stackvm repo, James's stackvm repo) and documented most of the ideas and experiments on stackvm github wiki.

We're applying for YC funding later this year so that we can focus on hacking and not paperwork.

Now a little bit about the tech we use at StackVM. I won't go into much details right now because many of the future posts will detail the tech at StackVM.

At the moment StackVM is in its 3rd major iteration already and is almost entirely built on node.js. Since we're doing everything open-source, we've written a bunch of reusable node.js modules:

  • dnode - Simple asynchronous remote method invocation for node.js.
  • node-bufferlist - Abstraction of node.js's buffers and monadic binary parsing.
  • node-rfb - Implements the client-side of the RFB protocol that VNC uses.
  • node-png - Produces PNG images from RGB or RGBA values.
  • node-jpeg - Produces JPEG images from RGB or RGBA values.
  • node-video - Records Theora/Ogg videos from RGB values.
  • node-base64 - Encodes binary data to base64 to send across websockets and ajax.
  • node-jsmin - Minify JavaScript on the server side, before sending it to the browser.
  • node-bufferdiff - A module to compare two buffers quickly.

I'll keep everyone updated on the progress and technical insight into our development. If you're not yet subscribed to my posts, please do it - catonmat rss feed. Going to make this happen!

And if you wish to talk about our software, come join #stackvm on FreeNode!

A Year of BloggingHey everyone! Another year has passed and it's now 3 years since I've been blogging here on catonmat! In this post I wish to summarize this year's statistics.

See the one year of blogging and two years of blogging for previous year statistics.

First of all traffic statistics,


Traffic statistics for the period 2009-07-01 - 2010-07-01 from Google Analytics.

Alright, so catonmat has received 1.43 million visitors and 2.11 million page views during this year. That's 120k visits and 175k page views per month. Or 4,000 visitors per day and 5,800 page views per day. Good numbers.

Let's look at the whole traffic picture from the day one of blogging,


Traffic statistics for the period 2007-07-01 - 2010-07-01 from Google Analytics.

Looks pretty random but seems to have a hidden linear trend upwards.

Now the FeedBurner subscriber stats,


Feedburner statistics for the period 2009-07-01 - 2010-07-01.

Last year I left off with 7000 subscribers, and now I have around 12,000. That's 5000 new subscribers, or 13 new subscribers per day on average.

And the whole picture of subscriber dynamics since the beginning of blogging,


Feedburner statistics for the period 2007-07-01 - 2010-07-01.

Also a nice positive trend, if it keeps going the same way, I expect to have around 17,000 subscribers the next year.

Now to articles. During this year I have written 43 articles. Here are ten most popular ones:

Here are my personal favorites that didn't make it into top ten:

It's now time for delicious cake:

Let's meet for cake the next year again! See you!

When people talk about polymorphism in C++ they usually mean the thing of using a derived class through the base class pointer or reference, which is called subtype polymorphism. But they often forget that there are all kinds of other polymorphisms in C++, such as parametric polymorphism, ad-hoc polymorphism and coercion polymorphism.

These polymorphisms also go by different names in C++,

  • Subtype polymorphism is also known as runtime polymorphism.
  • Parametric polymorphism is also known as compile-time polymorphism.
  • Ad-hoc polymorphism is also known as overloading.
  • Coercion is also known as (implicit or explicit) casting.

In this article I'll illustrate all the polymorphisms through examples in C++ language and also give insight on why they have various other names.

Subtype Polymorphism (Runtime Polymorphism)

Subtype polymorphism is what everyone understands when they say "polymorphism" in C++. It's the ability to use derived classes through base class pointers and references.

Here is an example. Suppose you have various cats like these felines,

Polymorphic Cats
Polymorphic cats on a mat by James Halliday.

Since they are all of Felidae biological family, and they all should be able to meow, they can be represented as classes inheriting from Felid base class and overriding the meow pure virtual function,

// file cats.h

class Felid {
public:
 virtual void meow() = 0;
};

class Cat : public Felid {
public:
 void meow() { std::cout << "Meowing like a regular cat! meow!\n"; }
};

class Tiger : public Felid {
public:
 void meow() { std::cout << "Meowing like a tiger! MREOWWW!\n"; }
};

class Ocelot : public Felid {
public:
 void meow() { std::cout << "Meowing like an ocelot! mews!\n"; }
};

Now the main program can use Cat, Tiger and Ocelot interchangeably through Felid (base class) pointer,

#include <iostream>
#include "cats.h"

void do_meowing(Felid *cat) {
 cat->meow();
}

int main() {
 Cat cat;
 Tiger tiger;
 Ocelot ocelot;

 do_meowing(&cat);
 do_meowing(&tiger);
 do_meowing(&ocelot);
}

Here the main program passes pointers to cat, tiger and ocelot to do_meowing function that expects a pointer to Felid. Since they are all Felids, the program calls the right meow function for each felid and the output is:

Meowing like a regular cat! meow!
Meowing like a tiger! MREOWWW!
Meowing like an ocelot! mews!

Subtype polymorphism is also called runtime polymorphism for a good reason. The resolution of polymorphic function calls happens at runtime through an indirection via the virtual table. Another way of explaining this is that compiler does not locate the address of the function to be called at compile-time, instead when the program is run, the function is called by dereferencing the right pointer in the virtual table.

In type theory it's also known as inclusion polymorphism.

Parametric Polymorphism (Compile-Time Polymorphism)

Parametric polymorphism provides a means to execute the same code for any type. In C++ parametric polymorphism is implemented via templates.

One of the simplest examples is a generic max function that finds maximum of two of its arguments,

#include <iostream>
#include <string>

template <class T>
T max(T a, T b) {
 return a > b ? a : b;
}

int main() {
 std::cout << ::max(9, 5) << std::endl;     // 9

 std::string foo("foo"), bar("bar");
 std::cout << ::max(foo, bar) << std::endl; // "foo"
}

Here the max function is polymorphic on type T. Note, however, that it doesn't work on pointer types because comparing pointers compares the memory locations and not the contents. To get it working for pointers you'd have to specialize the template for pointer types and that would no longer be parametric polymorphism but would be ad-hoc polymorphism.

Since parametric polymorphism happens at compile time, it's also called compile-time polymorphism.

Ad-hoc Polymorphism (Overloading)

Ad-hoc polymorphism allows functions with the same name act differently for each type. For example, given two ints and the + operator, it adds them together. Given two std::strings it concatenates them together. This is called overloading.

Here is a concrete example that implements function add for ints and strings,

#include <iostream>
#include <string>

int add(int a, int b) {
 return a + b;
}

std::string add(const char *a, const char *b) {
 std::string result(a);
 result += b;
 return result;
}

int main() {
 std::cout << add(5, 9) << std::endl;
 std::cout << add("hello ", "world") << std::endl;
}

Ad-hoc polymorphism also appears in C++ if you specialize templates. Returning to the previous example about max function, here is how you'd write a max for two char *,

template <>
const char *max(const char *a, const char *b) {
 return strcmp(a, b) > 0 ? a : b;
}

Now you can call ::max("foo", "bar") to find maximum of strings "foo" and "bar".

Coercion Polymorphism (Casting)

Coercion happens when an object or a primitive is cast into another object type or primitive type. For example,

float b = 6; // int gets promoted (cast) to float implicitly
int a = 9.99 // float gets demoted to int implicitly

Explicit casting happens when you use C's type-casting expressions, such as (unsigned int *) or (int) or C++'s static_cast, const_cast, reinterpret_cast, or dynamic_cast.

Coercion also happens if the constructor of a class isn't explicit, for example,

#include <iostream>

class A {
 int foo;
public:
 A(int ffoo) : foo(ffoo) {}
 void giggidy() { std::cout << foo << std::endl; }
};

void moo(A a) {
 a.giggidy();
}

int main() {
 moo(55);     // prints 55
}

If you made the constructor of A explicit, that would no longer be possible. It's always a good idea to make your constructors explicit to avoid accidental conversions.

Also if a class defines conversion operator for type T, then it can be used anywhere where type T is expected.

For example,

class CrazyInt {
 int v;
public:
 CrazyInt(int i) : v(i) {}
 operator int() const { return v; } // conversion from CrazyInt to int
};

The CrazyInt defines a conversion operator to type int. Now if we had a function, let's say, print_int that took int as an argument, we could also pass it an object of type CrazyInt,

#include <iostream>

void print_int(int a) {
 std::cout << a << std::endl;
}

int main() {
 CrazyInt b = 55;
 print_int(999);    // prints 999
 print_int(b);      // prints 55
}

Subtype polymorphism that I discussed earlier is actually also coercion polymorphism because the derived class gets converted into base class type.

Have Fun!

Have fun with all the new knowledge about polymorphism!

This article is part of the article series "CommandLineFu One-Liners Explained."
<- previous article next article ->

CommandLineFu ExplainedHey everyone, this is the fourth article in the series on the most popular commandlinefu one-liners explained.

Here are the first three parts:

And here are today's one-liners:

31. Quickly access ASCII table.

$ man 7 ascii

Ever forgot a keycode for some ASCII character or escape code? Look no further, man ascii contains the 7-bit ASCII table. Take a look at it online.

Linux man pages are full of gems like these. One day I actually went through all the man pages to find the most interesting ones. An article about them is upcoming but before I get it published, here are a few interesting ones:

And finally the section 7 man pages that are most packed with wild and cool info,

  • man 7 bootparam - a tutorial and reference of Linux kernel boot parameters.
  • man 7 charsets - a Linux programmer's view of character sets and internationalization.
  • man 7 glob - how pathname globbing works.
  • man 7 hier - description of the Linux file system hierarchy.
  • man 7 operator - C language operator precedence and associativity table.
  • man 7 regex - basic and extended regular expression overview.
  • man 7 suffixes - lists common Linux file suffixes and the associated file types.
  • man 7 time - overview of time and timers.
  • man 7 units - kilo, kibi, mega, mebi, giga, gibi, ... - decimal (SI) and binary system of units.
  • man 7 utf8 - description of UTF-8 encoding.
  • man 7 url - description of URIs, URLs and URNs.

There are a lot more interesting man pages but these stood out from the rest.

32. Simple timer.

$ time read

This one-liner can be used a simple timer. For example, if you wish to time something, you can execute it when the event starts and press the return key when the event ends. It will output the time the event took to finish.

Here is how this one-liner works. First the time command times any command that is supplied to it. In this case the command supplied to it is read that reads a line from the standard input. As soon as you press enter, read finishes and time reports how long it took.

If you get annoyed by having to press enter, you can specify that read should return after having read 1 character,

$ time read -N 1

Now you can press any key to stop the timer.

If you wish to run a timer for a specific number of seconds, you can add -t flag for timeout,

$ time read -t 60

This would stop the timer after 60 seconds.

33. Shutdown a Windows machine.

$ net rpc shutdown -I IP_ADDRESS -U username%password

Everyone knows the net command, right? We all used to net use \\ip\ipc$ *, right? :)

Anyway, the net command comes as part of Samba, which allows you, for example, to use Linux in a Windows workgroup.

This particular one-liner executes the shutdown command on a Windows computer located at IP_ADDRESS with as the user username with password password.

To reboot a machine use the -r switch to net rpc:

$ net rpc shutdown -r -I IP_ADDRESS -U username%password

If you're on an unsecured network, don't forget about the good old nmblookup and smbclient tools that come with Samba.

34. Execute a command independently from the current shell.

$ (cd /tmp && ls)

This one-liner illustrates subshells. Here the commands cd /tmp and ls are executed but they do not affect the current shell. If you had done just cd /tmp && ls, your current shell would have changed directory to /tmp but in this one-liner it happens in a subshell and your current shell is not affected.

Surely, this is only a toy example. If you wanted to know what's in /tmp, you'd do just ls /tmp.

Actually, talking about cd, be aware of pushd and popd commands. They allow you to maintain a stack of directories you want to return to later. For example,

/long/path/is/long$ pushd .
/long/path/is/long$ cd /usr
/usr$ popd 
/long/path/is/long$

Or even shorter, passing the directory you're gonna cd to directly to pushd,

/long/path/is/long$ pushd /usr
/usr$ popd 
/long/path/is/long$

Another cool trick is to use cd - to return to the previous directory. Here is an example,

/home/pkrumins$ cd /tmp
/tmp$ cd -
/home/pkrumins$

35. Tunnel your SSH connection via intermediate host.

$ ssh -t reachable_host ssh unreachable_host

This one-liner creates an ssh connection to unreachable_host via reachable_host. It does it by executing the ssh unreachable_host on reachable_host. The -t forces ssh to allocate a pseudo-tty, which is necessary for working interactively in the second ssh to unreachable_host.

This one-liner can be generalized. You can tunnel through arbitrary number of ssh servers:

$ ssh -t host1 ssh -t host2 ssh -t host3 ssh -t host4 ...

Now catch me if you can. ;)

36. Clear the terminal screen.

$ CTRL+l

Pressing CTRL+l (that's small L) clears the screen leaving the current line at the top of the screen.

If you wish to clear just some line, you can use argumented version of CTRL+l - first press ESC, then the line you want to clear, let's say 21 (21st line), and then press the same CTRL+l. That will clear the 21st line on the screen without erasing the whole screen.

$ ESC 21 CTRL+l

This command outputs a special "clear-screen" sequence to the terminal. The same can be achieved by tput command,

$ tput clear

Another way to clear the terminal (usually when the screen gets garbled) is to use the reset command,

$ reset

37. Hear when the machine comes back online.

$ ping -a IP

Ever had a situation when you need to know when the system comes up after a reboot? Up until now you probably launched ping and either followed the timeouts until the system came back, or left it running and occasionally checked its output to see if the host is up. But that is unnecessary, you can make ping -a audible! As soon as the host at IP is back, ping will beep!

38. List 10 most often used commands.

$ history | awk '{a[$2]++}END{for(i in a){print a[i] " " i}}' | sort -rn | head

The person who wrote it has the Unix mindset right. He's combining several shell commands to get the result he/she wants.

First, history outputs all the commands the person has executed. Next, awk counts how many times the second column $2 appears in the output. Once history has output all the commands and awk has counted them, awk loops over all the commands and outputs the count a[i] separated by space, followed by the command itself. Then sort takes this input and sorts numerically -n and reverses the output -r, so that most frequent commands were on top. Finally head outputs the first 10 most frequent history commands.

If you want to see more than 10 commands (or less), change head to head -20 for 20 commands or head -5 for 5 commands.

39. Check gmail for new mail.

$ curl -u you@gmail.com --silent "https://mail.google.com/mail/feed/atom" |
  perl -ne \
  '
    print "Subject: $1 " if /<title>(.+?)<\/title>/ && $title++;
    print "(from $1)\n" if /<email>(.+?)<\/email>/;
  '

Gmail is cool because they offer an Atom feed for the new mail. This one-liner instructs curl to retrieve the feed and authenticate as you@gmail.com. You'll be prompted a password after you execute the command. Next it feeds the output to perl. Perl extracts the title (subject) of each email and the sender's email. These two items are printed to stdout.

Here is a the output when I run the command,

Subject: i heard you liked windows! (from gates@microsoft.com)
Subject: got root? (from bofh@underground.org)

40. Watch Star-Wars via telnet.

$ telnet towel.blinkenlights.nl

Needs no explaining. Just telnet to the host to watch ASCII Star-Wars.

And here is another one,

$ telnet towel.blinkenlights.nl 666

Connecting on port 666 will spit out BOFH excuses.

That's it for today.

I hope you enjoyed the 4th part of the article. Tune in next time for the 5th part.

Oh, and I'd love if you followed me on Twitter!