Updates to Getting Started.

This set of revisions separates the C from the asciidoc, and breaks
each pattern into separate documents.  A number of errors were fixed,
and the example code was hardened a bit to make it more robust and
correct for newbies who might be expecting it to Just Work.

This also sets the stage for us to make versions of this for NNG, mangos,
and other languages.
diff --git a/_adoc/build.sh b/_adoc/build.sh
index d029d3e..9e1e7ee 100755
--- a/_adoc/build.sh
+++ b/_adoc/build.sh
@@ -6,8 +6,14 @@
 # properly.
 
 cd $(dirname $0)
-for f in $(find . -name '*.adoc'); do
-
+if [ -n "$1" ]
+then
+	files=$*
+else
+	files=$(find . -name '*.adoc')
+fi
+for f in $files
+do
 	input=${f#./}
 	indir=$(dirname $f)
 	indir=${indir#./}
@@ -15,6 +21,11 @@
         outdir=../${indir}
 
 	when=$(git log -n1 --format='%ad' '--date=format-local:%s' $f)
+	if [[ -z "${when}" ]]
+	then
+		when=$(date +%s)
+	fi
+	
 	echo "Processing $input -> $output"
 	infrontmatter=0
 	manpage=0
diff --git a/_adoc/gettingstarted/banner.adoc b/_adoc/gettingstarted/banner.adoc
new file mode 100644
index 0000000..6e612f4
--- /dev/null
+++ b/_adoc/gettingstarted/banner.adoc
@@ -0,0 +1,6 @@
+= <<index#,Getting Started with 'nanomsg'>>
+
+NOTE: This document is derived from an original post by Tim Dysinger.
+That post is no longer available, but we have modified and restructured it,
+as well as making enhancments and corrections. 
+Tim's original code is on https://github.com/dysinger/nanomsg-examples[github], but we recommend using the examples here as they have a number of corrections.
diff --git a/_adoc/gettingstarted/bus.adoc b/_adoc/gettingstarted/bus.adoc
new file mode 100644
index 0000000..0ab43d8
--- /dev/null
+++ b/_adoc/gettingstarted/bus.adoc
@@ -0,0 +1,59 @@
+---
+layout: default
+---
+:source-highlighter: coderay
+:icons: font
+
+include::banner.adoc[]
+
+== Bus (Routing)
+
+image::bus.png[A Simple Bus]
+
+The bus protocol is useful for routing applications, or for building
+fully interconnected mesh networks.  In this pattern, messages are
+sent to every directly connected peer.
+
+.bus.c
+[source,c]
+----
+include::src/bus.c[]
+----
+<1> Blithely assumes message is ASCIIZ string. Real code should check it.
+
+.Compilation
+[source,bash]
+----
+gcc bus.c -lnanomsg.a -o bus
+----
+
+.Execution
+[source,bash]
+----
+./bus node0 ipc:///tmp/node0.ipc ipc:///tmp/node1.ipc ipc:///tmp/node2.ipc & node0=$!
+./bus node1 ipc:///tmp/node1.ipc ipc:///tmp/node2.ipc ipc:///tmp/node3.ipc & node1=$!
+./bus node2 ipc:///tmp/node2.ipc ipc:///tmp/node3.ipc & node2=$!
+./bus node3 ipc:///tmp/node3.ipc ipc:///tmp/node0.ipc & node3=$!
+sleep 5
+kill $node0 $node1 $node2 $node3
+----
+
+.Output
+----
+node0: SENDING 'node0' ONTO BUS
+node1: SENDING 'node1' ONTO BUS
+node2: SENDING 'node2' ONTO BUS
+node3: SENDING 'node3' ONTO BUS
+node0: RECEIVED 'node1' FROM BUS
+node0: RECEIVED 'node2' FROM BUS
+node0: RECEIVED 'node3' FROM BUS
+node1: RECEIVED 'node0' FROM BUS
+node1: RECEIVED 'node2' FROM BUS
+node1: RECEIVED 'node3' FROM BUS
+node2: RECEIVED 'node0' FROM BUS
+node2: RECEIVED 'node1' FROM BUS
+node2: RECEIVED 'node3' FROM BUS
+node3: RECEIVED 'node0' FROM BUS
+node3: RECEIVED 'node1' FROM BUS
+node3: RECEIVED 'node2' FROM BUS
+----
diff --git a/_adoc/gettingstarted/index.adoc b/_adoc/gettingstarted/index.adoc
index 30d6e6a..d31f624 100644
--- a/_adoc/gettingstarted/index.adoc
+++ b/_adoc/gettingstarted/index.adoc
@@ -4,561 +4,19 @@
 :source-highlighter: coderay
 :icons: font
 
-= Getting Started with 'nanomsg'
+include::banner.adoc[]
 
-NOTE: This document is taken from an original post by Tim Dysinger.
-That post is no longer available, but we have modified it from HTML
-and posted it here for your enjoyment.
+== Messaging Patterns
 
-Posted on September 16, 2013 by [Tim Dysinger](https://github.com/dysinger/nanomsg-examples)
+http://nanomsg.org[Nanomsg] is a messaging framework that attempts to
+help solve common messaging problems with one of a few patterns ('protocols'
+in nanomsg parlance.)
 
-I played around with http://nanomsg.org/[nanomsg]. It’s natural to describe it as a mini-zeromq in C. The following are my examples of each pattern type in C. Error handling and such has been left out for brevity.
+Following are examples of each pattern type in C.
 
-The code is on https://github.com/dysinger/nanomsg-examples[github as well], but may be more out of date.
-
-== Pipeline (A One-Way Pipe)
-
-image::pipeline.png[A One-Way Pipe]
-
-[source,C]
-----------
-#include <assert.h>
-#include <libc.h>
-#include <stdio.h>
-#include <nanomsg/nn.h>
-#include <nanomsg/pipeline.h>
-
-#define NODE0 "node0"
-#define NODE1 "node1"
-
-int node0 (const char *url)
-{
-  int sock = nn_socket (AF_SP, NN_PULL);
-  assert (sock >= 0);
-  assert (nn_bind (sock, url) >= 0);
-  while (1)
-    {
-      char *buf = NULL;
-      int bytes = nn_recv (sock, &buf, NN_MSG, 0);
-      assert (bytes >= 0);
-      printf ("NODE0: RECEIVED \"%s\"\n", buf);
-      nn_freemsg (buf);
-    }
-}
-
-int node1 (const char *url, const char *msg)
-{
-  int sz_msg = strlen (msg) + 1; // '\0' too
-  int sock = nn_socket (AF_SP, NN_PUSH);
-  assert (sock >= 0);
-  assert (nn_connect (sock, url) >= 0);
-  printf ("NODE1: SENDING \"%s\"\n", msg);
-  int bytes = nn_send (sock, msg, sz_msg, 0);
-  assert (bytes == sz_msg);
-  sleep(1); // wait for messages to flush before shutting down
-  return nn_shutdown (sock, 0);
-}
-
-int main (const int argc, const char **argv)
-{
-  if (strncmp (NODE0, argv[1], strlen (NODE0)) == 0 && argc > 1)
-    return node0 (argv[2]);
-  else if (strncmp (NODE1, argv[1], strlen (NODE1)) == 0 && argc > 2)
-    return node1 (argv[2], argv[3]);
-  else
-    {
-      fprintf (stderr, "Usage: pipeline %s|%s <URL> <ARG> ...'\n",
-               NODE0, NODE1);
-      return 1;
-    }
-}
-----------
-
-[source,bash]
--------------
-gcc pipeline.c /usr/local/lib/libnanomsg.a -o pipeline
-./pipeline node0 ipc:///tmp/pipeline.ipc & node0=$! && sleep 1
-./pipeline node1 ipc:///tmp/pipeline.ipc "Hello, World!"
-./pipeline node1 ipc:///tmp/pipeline.ipc "Goodbye."
-kill $node0
--------------
-
--------------
-NODE1: SENDING "Hello, World!"
-NODE0: RECEIVED "Hello, World!"
-NODE1: SENDING "Goodbye."
-NODE0: RECEIVED "Goodbye."
--------------
-
-== Request/Reply (I ask, you answer)
-
-image::reqrep.png[I ask, you answer]
-
-[source,c]
-----------
-#include <assert.h>
-#include <libc.h>
-#include <stdio.h>
-#include <nanomsg/nn.h>
-#include <nanomsg/pipeline.h>
-
-#define NODE0 "node0"
-#define NODE1 "node1"
-
-int node0 (const char *url)
-{
-  int sock = nn_socket (AF_SP, NN_PULL);
-  assert (sock >= 0);
-  assert (nn_bind (sock, url) >= 0);
-  while (1)
-    {
-      char *buf = NULL;
-      int bytes = nn_recv (sock, &buf, NN_MSG, 0);
-      assert (bytes >= 0);
-      printf ("NODE0: RECEIVED \"%s\"\n", buf);
-      nn_freemsg (buf);
-    }
-}
-
-int node1 (const char *url, const char *msg)
-{
-  int sz_msg = strlen (msg) + 1; // '\0' too
-  int sock = nn_socket (AF_SP, NN_PUSH);
-  assert (sock >= 0);
-  assert (nn_connect (sock, url) >= 0);
-  printf ("NODE1: SENDING \"%s\"\n", msg);
-  int bytes = nn_send (sock, msg, sz_msg, 0);
-  assert (bytes == sz_msg);
-  sleep(1); // wait for messages to flush before shutting down
-  return nn_shutdown (sock, 0);
-}
-
-int main (const int argc, const char **argv)
-{
-  if (strncmp (NODE0, argv[1], strlen (NODE0)) == 0 && argc > 1)
-    return node0 (argv[2]);
-  else if (strncmp (NODE1, argv[1], strlen (NODE1)) == 0 && argc > 2)
-    return node1 (argv[2], argv[3]);
-  else
-    {
-      fprintf (stderr, "Usage: pipeline %s|%s <URL> <ARG> ...'\n",
-               NODE0, NODE1);
-      return 1;
-    }
-}
-----------
-
-[source,bash]
--------------
-gcc reqrep.c /usr/local/lib/libnanomsg.a -o reqrep
-./reqrep node0 ipc:///tmp/reqrep.ipc & node0=$! && sleep 1
-./reqrep node1 ipc:///tmp/reqrep.ipc
-kill $node0
--------------
-
--------------
-NODE1: SENDING DATE REQUEST DATE
-NODE0: RECEIVED DATE REQUEST
-NODE0: SENDING DATE Sat Sep  7 17:39:01 2013
-NODE1: RECEIVED DATE Sat Sep  7 17:39:01 2013
--------------
-
-== Pair (Two Way Radio)
-
-image::pair.png[Two Way Radio]
-
-[source,c]
-----------
-#include <assert.h>
-#include <libc.h>
-#include <nanomsg/nn.h>
-#include <nanomsg/pair.h>
-#include <stdio.h>
-
-#define NODE0 "node0"
-#define NODE1 "node1"
-
-int send_name(int sock, const char *name)
-{
-  printf ("%s: SENDING \"%s\"\n", name, name);
-  int sz_n = strlen (name) + 1; // '\0' too
-  return nn_send (sock, name, sz_n, 0);
-}
-
-int recv_name(int sock, const char *name)
-{
-  char *buf = NULL;
-  int result = nn_recv (sock, &buf, NN_MSG, 0);
-  if (result > 0)
-    {
-      printf ("%s: RECEIVED \"%s\"\n", name, buf);
-      nn_freemsg (buf);
-    }
-  return result;
-}
-
-int send_recv(int sock, const char *name)
-{
-  int to = 100;
-  assert (nn_setsockopt (sock, NN_SOL_SOCKET, NN_RCVTIMEO, &to, sizeof (to)) >= 0);
-  while(1)
-    {
-      recv_name(sock, name);
-      sleep(1);
-      send_name(sock, name);
-    }
-}
-
-int node0 (const char *url)
-{
-  int sock = nn_socket (AF_SP, NN_PAIR);
-  assert (sock >= 0);
-  assert (nn_bind (sock, url) >= 0);
-  send_recv(sock, NODE0);
-  return nn_shutdown (sock, 0);
-}
-
-int node1 (const char *url)
-{
-  int sock = nn_socket (AF_SP, NN_PAIR);
-  assert (sock >= 0);
-  assert (nn_connect (sock, url) >= 0);
-  send_recv(sock, NODE1);
-  sleep(1); // wait for messages to flush before shutting down
-  return nn_shutdown (sock, 0);
-}
-
-int main (const int argc, const char **argv)
-{
-  if (strncmp (NODE0, argv[1], strlen (NODE0)) == 0 && argc > 1)
-    return node0 (argv[2]);
-  else if (strncmp (NODE1, argv[1], strlen (NODE1)) == 0 && argc > 1)
-    return node1 (argv[2]);
-  else
-    {
-      fprintf (stderr, "Usage: pair %s|%s <URL> <ARG> ...\n",
-               NODE0, NODE1);
-      return 1;
-    }
-}
-----------
-
-[source,bash]
--------------
-gcc pair.c /usr/local/lib/libnanomsg.a -o pair
-./pair node0 ipc:///tmp/pair.ipc & node0=$!
-./pair node1 ipc:///tmp/pair.ipc & node1=$!
-sleep 3
-kill $node0 $node1
--------------
-
--------------
-NODE1: SENDING DATE REQUEST DATE
-NODE0: RECEIVED DATE REQUEST
-NODE0: SENDING DATE Sat Sep  7 17:39:01 2013
-NODE1: RECEIVED DATE Sat Sep  7 17:39:01 2013
--------------
-
-== Pub/Sub (Topics & Broadcast)
-
-image::pubsub.png[Topics & Broadcast]
-
-[source,c]
-----------
-#include <assert.h>
-#include <libc.h>
-#include <stdio.h>
-#include <nanomsg/nn.h>
-#include <nanomsg/pubsub.h>
-
-#define SERVER "server"
-#define CLIENT "client"
-
-char *date ()
-{
-  time_t raw = time (&raw);
-  struct tm *info = localtime (&raw);
-  char *text = asctime (info);
-  text[strlen(text)-1] = '\0'; // remove '\n'
-  return text;
-}
-
-int server (const char *url)
-{
-  int sock = nn_socket (AF_SP, NN_PUB);
-  assert (sock >= 0);
-  assert (nn_bind (sock, url) >= 0);
-  while (1)
-    {
-      char *d = date();
-      int sz_d = strlen(d) + 1; // '\0' too
-      printf ("SERVER: PUBLISHING DATE %s\n", d);
-      int bytes = nn_send (sock, d, sz_d, 0);
-      assert (bytes == sz_d);
-      sleep(1);
-    }
-  return nn_shutdown (sock, 0);
-}
-
-int client (const char *url, const char *name)
-{
-  int sock = nn_socket (AF_SP, NN_SUB);
-  assert (sock >= 0);
-  // TODO learn more about publishing/subscribe keys
-  assert (nn_setsockopt (sock, NN_SUB, NN_SUB_SUBSCRIBE, "", 0) >= 0);
-  assert (nn_connect (sock, url) >= 0);
-  while (1)
-    {
-      char *buf = NULL;
-      int bytes = nn_recv (sock, &buf, NN_MSG, 0);
-      assert (bytes >= 0);
-      printf ("CLIENT (%s): RECEIVED %s\n", name, buf);
-      nn_freemsg (buf);
-    }
-  return nn_shutdown (sock, 0);
-}
-
-int main (const int argc, const char **argv)
-{
-  if (strncmp (SERVER, argv[1], strlen (SERVER)) == 0 && argc >= 2)
-    return server (argv[2]);
-  else if (strncmp (CLIENT, argv[1], strlen (CLIENT)) == 0 && argc >= 3)
-    return client (argv[2], argv[3]);
-  else
-    {
-      fprintf (stderr, "Usage: pubsub %s|%s <URL> <ARG> ...\n",
-               SERVER, CLIENT);
-      return 1;
-    }
-}
-----------
-
-[source,bash]
--------------
-gcc pubsub.c /usr/local/lib/libnanomsg.a -o pubsub
-./pubsub server ipc:///tmp/pubsub.ipc & server=$! && sleep 1
-./pubsub client ipc:///tmp/pubsub.ipc client0 & client0=$!
-./pubsub client ipc:///tmp/pubsub.ipc client1 & client1=$!
-./pubsub client ipc:///tmp/pubsub.ipc client2 & client2=$!
-sleep 5
-kill $server $client0 $client1 $client2
--------------
-
--------------
-SERVER: PUBLISHING DATE Sat Sep  7 17:40:11 2013
-SERVER: PUBLISHING DATE Sat Sep  7 17:40:12 2013
-SERVER: PUBLISHING DATE Sat Sep  7 17:40:13 2013
-CLIENT (client2): RECEIVED Sat Sep  7 17:40:13 2013
-CLIENT (client0): RECEIVED Sat Sep  7 17:40:13 2013
-CLIENT (client1): RECEIVED Sat Sep  7 17:40:13 2013
-SERVER: PUBLISHING DATE Sat Sep  7 17:40:14 2013
-CLIENT (client2): RECEIVED Sat Sep  7 17:40:14 2013
-CLIENT (client1): RECEIVED Sat Sep  7 17:40:14 2013
-CLIENT (client0): RECEIVED Sat Sep  7 17:40:14 2013
-SERVER: PUBLISHING DATE Sat Sep  7 17:40:15 2013
-CLIENT (client1): RECEIVED Sat Sep  7 17:40:15 2013
-CLIENT (client2): RECEIVED Sat Sep  7 17:40:15 2013
-CLIENT (client0): RECEIVED Sat Sep  7 17:40:15 2013
-SERVER: PUBLISHING DATE Sat Sep  7 17:40:16 2013
-CLIENT (client1): RECEIVED Sat Sep  7 17:40:16 2013
-CLIENT (client2): RECEIVED Sat Sep  7 17:40:16 2013
-CLIENT (client0): RECEIVED Sat Sep  7 17:40:16 2013
--------------
-
-== Survey (Everybody Votes)
-
-image::survey.png[Everybody Votes]
-
-[source,c]
-----------
-#include <assert.h>
-#include <libc.h>
-#include <stdio.h>
-#include <nanomsg/nn.h>
-#include <nanomsg/survey.h>
-
-#define SERVER "server"
-#define CLIENT "client"
-#define DATE   "DATE"
-
-char *date ()
-{
-  time_t raw = time (&raw);
-  struct tm *info = localtime (&raw);
-  char *text = asctime (info);
-  text[strlen(text)-1] = '\0'; // remove '\n'
-  return text;
-}
-
-int server (const char *url)
-{
-  int sock = nn_socket (AF_SP, NN_SURVEYOR);
-  assert (sock >= 0);
-  assert (nn_bind (sock, url) >= 0);
-  sleep(1); // wait for connections
-  int sz_d = strlen(DATE) + 1; // '\0' too
-  printf ("SERVER: SENDING DATE SURVEY REQUEST\n");
-  int bytes = nn_send (sock, DATE, sz_d, 0);
-  assert (bytes == sz_d);
-  while (1)
-    {
-      char *buf = NULL;
-      int bytes = nn_recv (sock, &buf, NN_MSG, 0);
-      if (bytes == ETIMEDOUT) break;
-      if (bytes >= 0)
-      {
-        printf ("SERVER: RECEIVED \"%s\" SURVEY RESPONSE\n", buf);
-        nn_freemsg (buf);
-      }
-    }
-  return nn_shutdown (sock, 0);
-}
-
-int client (const char *url, const char *name)
-{
-  int sock = nn_socket (AF_SP, NN_RESPONDENT);
-  assert (sock >= 0);
-  assert (nn_connect (sock, url) >= 0);
-  while (1)
-    {
-      char *buf = NULL;
-      int bytes = nn_recv (sock, &buf, NN_MSG, 0);
-      if (bytes >= 0)
-        {
-          printf ("CLIENT (%s): RECEIVED \"%s\" SURVEY REQUEST\n", name, buf);
-          nn_freemsg (buf);
-          char *d = date();
-          int sz_d = strlen(d) + 1; // '\0' too
-          printf ("CLIENT (%s): SENDING DATE SURVEY RESPONSE\n", name);
-          int bytes = nn_send (sock, d, sz_d, 0);
-          assert (bytes == sz_d);
-        }
-    }
-  return nn_shutdown (sock, 0);
-}
-
-int main (const int argc, const char **argv)
-{
-  if (strncmp (SERVER, argv[1], strlen (SERVER)) == 0 && argc >= 2)
-    return server (argv[2]);
-  else if (strncmp (CLIENT, argv[1], strlen (CLIENT)) == 0 && argc >= 3)
-    return client (argv[2], argv[3]);
-  else
-    {
-      fprintf (stderr, "Usage: survey %s|%s <URL> <ARG> ...\n",
-               SERVER, CLIENT);
-      return 1;
-    }
-}
-----------
-
-[source,bash]
--------------
-gcc survey.c /usr/local/lib/libnanomsg.a -o survey
-./survey server ipc:///tmp/survey.ipc & server=$!
-./survey client ipc:///tmp/survey.ipc client0 & client0=$!
-./survey client ipc:///tmp/survey.ipc client1 & client1=$!
-./survey client ipc:///tmp/survey.ipc client2 & client2=$!
-sleep 3
-kill $server $client0 $client1 $client2
--------------
-
--------------
-SERVER: SENDING DATE SURVEY REQUEST
-CLIENT (client1): RECEIVED "DATE" SURVEY REQUEST
-CLIENT (client2): RECEIVED "DATE" SURVEY REQUEST
-CLIENT (client0): RECEIVED "DATE" SURVEY REQUEST
-CLIENT (client0): SENDING DATE SURVEY RESPONSE
-CLIENT (client1): SENDING DATE SURVEY RESPONSE
-CLIENT (client2): SENDING DATE SURVEY RESPONSE
-SERVER: RECEIVED "Sun Sep 15 13:39:46 2013" SURVEY RESPONSE
-SERVER: RECEIVED "Sun Sep 15 13:39:46 2013" SURVEY RESPONSE
-SERVER: RECEIVED "Sun Sep 15 13:39:46 2013" SURVEY RESPONSE
--------------
-
-== Bus (Routing)
-
-image::bus.png[A Simple Bus]
-
-[source,c]
-----------
-#include <assert.h>
-#include <libc.h>
-#include <stdio.h>
-#include <nanomsg/nn.h>
-#include <nanomsg/bus.h>
-
-int node (const int argc, const char **argv)
-{
-  int sock = nn_socket (AF_SP, NN_BUS);
-  assert (sock >= 0);
-  assert (nn_bind (sock, argv[2]) >= 0);
-  sleep (1); // wait for connections
-  if (argc >= 3)
-    {
-      int x=3;
-      for(x; x<argc; x++)
-        assert (nn_connect (sock, argv[x]) >= 0);
-    }
-  sleep (1); // wait for connections
-  int to = 100;
-  assert (nn_setsockopt (sock, NN_SOL_SOCKET, NN_RCVTIMEO, &to, sizeof (to)) >= 0);
-  // SEND
-  int sz_n = strlen(argv[1]) + 1; // '\0' too
-  printf ("%s: SENDING '%s' ONTO BUS\n", argv[1], argv[1]);
-  int send = nn_send (sock, argv[1], sz_n, 0);
-  assert (send == sz_n);
-  while (1)
-    {
-      // RECV
-      char *buf = NULL;
-      int recv = nn_recv (sock, &buf, NN_MSG, 0);
-      if (recv >= 0)
-        {
-          printf ("%s: RECEIVED '%s' FROM BUS\n", argv[1], buf);
-          nn_freemsg (buf);
-        }
-    }
-  return nn_shutdown (sock, 0);
-}
-
-int main (const int argc, const char **argv)
-{
-  if (argc >= 3) node (argc, argv);
-  else
-    {
-      fprintf (stderr, "Usage: bus <NODE_NAME> <URL> <URL> ...\n");
-      return 1;
-    }
-}
-----------
-
-[source,bash]
--------------
-gcc bus.c /usr/local/lib/libnanomsg.a -o bus
-./bus node0 ipc:///tmp/node0.ipc ipc:///tmp/node1.ipc ipc:///tmp/node2.ipc & node0=$!
-./bus node1 ipc:///tmp/node1.ipc ipc:///tmp/node2.ipc ipc:///tmp/node3.ipc & node1=$!
-./bus node2 ipc:///tmp/node2.ipc ipc:///tmp/node3.ipc & node2=$!
-./bus node3 ipc:///tmp/node3.ipc ipc:///tmp/node0.ipc & node3=$!
-sleep 5
-kill $node0 $node1 $node2 $node3
--------------
-
--------------
-node0: SENDING 'node0' ONTO BUS
-node1: SENDING 'node1' ONTO BUS
-node2: SENDING 'node2' ONTO BUS
-node3: SENDING 'node3' ONTO BUS
-node0: RECEIVED 'node1' FROM BUS
-node0: RECEIVED 'node2' FROM BUS
-node0: RECEIVED 'node3' FROM BUS
-node1: RECEIVED 'node0' FROM BUS
-node1: RECEIVED 'node2' FROM BUS
-node1: RECEIVED 'node3' FROM BUS
-node2: RECEIVED 'node0' FROM BUS
-node2: RECEIVED 'node1' FROM BUS
-node2: RECEIVED 'node3' FROM BUS
-node3: RECEIVED 'node0' FROM BUS
-node3: RECEIVED 'node1' FROM BUS
-node3: RECEIVED 'node2' FROM BUS
--------------
+* <<pipeline#,Pipeline (A One-Way Pipe)>>
+* <<reqrep#,Request/Reply (I ask, you answer)>> 
+* <<pair#,Pair (Two Way Radio)>>
+* <<pubsub#,Pub/Sub (Topics & Broadcast)>>
+* <<survey#,Survey (Everybody Votes)>>
+* <<bus#,Bus (Routing)>>
diff --git a/_adoc/gettingstarted/pair.adoc b/_adoc/gettingstarted/pair.adoc
new file mode 100644
index 0000000..b96a5db
--- /dev/null
+++ b/_adoc/gettingstarted/pair.adoc
@@ -0,0 +1,45 @@
+---
+layout: default
+---
+:source-highlighter: coderay
+:icons: font
+
+include::banner.adoc[]
+
+== Pair (Two Way Radio)
+
+image::pair.png[Two Way Radio]
+
+The pair pattern is used when there a one-to-one peer relationship.
+Only one peer may be connected to another peer at a time, but both
+may speak freely.
+
+.pair.c
+[source,c]
+----
+include::src/pair.c[]
+----
+<1> Blithely assumes message is ASCIIZ string. Real code should check it.
+
+.Compilation
+[source,bash]
+----
+gcc pair.c -lnanomsg -o pair
+----
+
+.Execution
+[source,bash]
+----
+./pair node0 ipc:///tmp/pair.ipc & node0=$!
+./pair node1 ipc:///tmp/pair.ipc & node1=$!
+sleep 3
+kill $node0 $node1
+----
+
+.Output
+----
+NODE1: SENDING DATE REQUEST DATE
+NODE0: RECEIVED DATE REQUEST
+NODE0: SENDING DATE Sat Sep  7 17:39:01 2013
+NODE1: RECEIVED DATE Sat Sep  7 17:39:01 2013
+----
diff --git a/_adoc/gettingstarted/pipeline.adoc b/_adoc/gettingstarted/pipeline.adoc
new file mode 100644
index 0000000..31d225b
--- /dev/null
+++ b/_adoc/gettingstarted/pipeline.adoc
@@ -0,0 +1,45 @@
+---
+layout: default
+---
+:source-highlighter: coderay
+:icons: font
+
+include::banner.adoc[]
+
+== Pipeline (A One-Way Pipe)
+
+image::pipeline.png[A One-Way Pipe]
+
+This pattern is useful for solving producer/consumer problems, including
+load-balancing.  Messages flow from the push side to the pull side.  If
+multiple peers are connected, the pattern attempts to distribute fairly.
+
+.pipeline.c
+[source,C]
+----
+include::src/pipeline.c[]
+----
+<1> Blithely assumes message is ASCIIZ string. Real code should check it.
+
+.Compilation
+[source,bash]
+----
+gcc pipeline.c -lnanomsg -o pipeline
+----
+
+.Execution
+[source,bash]
+----
+./pipeline node0 ipc:///tmp/pipeline.ipc & node0=$! && sleep 1
+./pipeline node1 ipc:///tmp/pipeline.ipc "Hello, World!"
+./pipeline node1 ipc:///tmp/pipeline.ipc "Goodbye."
+kill $node0
+----
+
+.Output
+----
+NODE1: SENDING "Hello, World!"
+NODE0: RECEIVED "Hello, World!"
+NODE1: SENDING "Goodbye."
+NODE0: RECEIVED "Goodbye."
+----
diff --git a/_adoc/gettingstarted/pubsub.adoc b/_adoc/gettingstarted/pubsub.adoc
new file mode 100644
index 0000000..f92f3be
--- /dev/null
+++ b/_adoc/gettingstarted/pubsub.adoc
@@ -0,0 +1,60 @@
+---
+layout: default
+---
+:source-highlighter: coderay
+:icons: font
+
+include::banner.adoc[]
+
+== Pub/Sub (Topics & Broadcast)
+
+image::pubsub.png[Topics & Broadcast]
+
+This pattern is used to allow a single broadcaster to publish messages
+to many subscribers, which may choose to limit which messages they receive.
+
+.pubsub.c
+[source,c]
+----
+include::src/pubsub.c[]
+----
+<1> Blithely assumes message is ASCIIZ string. Real code should check it.
+
+.Compilation
+[source,bash]
+----
+gcc pubsub.c /usr/local/lib/libnanomsg.a -o pubsub
+----
+
+.Execution
+[source,bash]
+----
+./pubsub server ipc:///tmp/pubsub.ipc & server=$! && sleep 1
+./pubsub client ipc:///tmp/pubsub.ipc client0 & client0=$!
+./pubsub client ipc:///tmp/pubsub.ipc client1 & client1=$!
+./pubsub client ipc:///tmp/pubsub.ipc client2 & client2=$!
+sleep 5
+kill $server $client0 $client1 $client2
+----
+
+.Output
+----
+SERVER: PUBLISHING DATE Sat Sep  7 17:40:11 2013
+SERVER: PUBLISHING DATE Sat Sep  7 17:40:12 2013
+SERVER: PUBLISHING DATE Sat Sep  7 17:40:13 2013
+CLIENT (client2): RECEIVED Sat Sep  7 17:40:13 2013
+CLIENT (client0): RECEIVED Sat Sep  7 17:40:13 2013
+CLIENT (client1): RECEIVED Sat Sep  7 17:40:13 2013
+SERVER: PUBLISHING DATE Sat Sep  7 17:40:14 2013
+CLIENT (client2): RECEIVED Sat Sep  7 17:40:14 2013
+CLIENT (client1): RECEIVED Sat Sep  7 17:40:14 2013
+CLIENT (client0): RECEIVED Sat Sep  7 17:40:14 2013
+SERVER: PUBLISHING DATE Sat Sep  7 17:40:15 2013
+CLIENT (client1): RECEIVED Sat Sep  7 17:40:15 2013
+CLIENT (client2): RECEIVED Sat Sep  7 17:40:15 2013
+CLIENT (client0): RECEIVED Sat Sep  7 17:40:15 2013
+SERVER: PUBLISHING DATE Sat Sep  7 17:40:16 2013
+CLIENT (client1): RECEIVED Sat Sep  7 17:40:16 2013
+CLIENT (client2): RECEIVED Sat Sep  7 17:40:16 2013
+CLIENT (client0): RECEIVED Sat Sep  7 17:40:16 2013
+----
diff --git a/_adoc/gettingstarted/reqrep.adoc b/_adoc/gettingstarted/reqrep.adoc
new file mode 100644
index 0000000..ab0c439
--- /dev/null
+++ b/_adoc/gettingstarted/reqrep.adoc
@@ -0,0 +1,46 @@
+---
+layout: default
+---
+:source-highlighter: coderay
+:icons: font
+
+include::banner.adoc[]
+
+== Request/Reply (I ask, you answer)
+
+image::reqrep.png[I ask, you answer]
+
+Request/Reply is used for synchronous communications where each question
+is responded with a single answer, for example remote procedure calls (RPCs).
+Like <<pipeline#,Pipeline>>, it also can perform load-balancing.  This
+is the only reliaable messaging pattern in the suite, as it automatically
+will retry if a request is not matched with a response.
+
+.reqprep.c
+[source,c]
+----
+include::src/reqrep.c[]
+----
+<1> Blithely assumes message is ASCIIZ string. Real code should check it.
+
+.Compilation
+[source,bash]
+----
+gcc reqrep.c -lnanomsg -o reqrep
+----
+
+.Execution
+[source,bash]
+----
+./reqrep node0 ipc:///tmp/reqrep.ipc & node0=$! && sleep 1
+./reqrep node1 ipc:///tmp/reqrep.ipc
+kill $node0
+----
+
+.Output
+----
+NODE1: SENDING DATE REQUEST DATE
+NODE0: RECEIVED DATE REQUEST
+NODE0: SENDING DATE Sat Sep  7 17:39:01 2013
+NODE1: RECEIVED DATE Sat Sep  7 17:39:01 2013
+----
diff --git a/_adoc/gettingstarted/src/bus.c b/_adoc/gettingstarted/src/bus.c
new file mode 100644
index 0000000..514c26a
--- /dev/null
+++ b/_adoc/gettingstarted/src/bus.c
@@ -0,0 +1,70 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <nanomsg/nn.h>
+#include <nanomsg/bus.h>
+
+void
+fatal(const char *func)
+{
+        fprintf(stderr, "%s: %s\n", func, nn_strerror(nn_errno()));
+        exit(1);
+}
+
+int
+node(const int argc, const char **argv)
+{
+        int sock;
+
+        if ((sock = nn_socket (AF_SP, NN_BUS)) < 0) {
+                fatal("nn_socket");
+        }
+          if (nn_bind(sock, argv[2]) < 0) {
+                fatal("nn_bind");
+        }
+
+        sleep(1); // wait for peers to bind
+        if (argc >= 3) {
+                for (int x = 3; x < argc; x++) {
+                        if (nn_connect(sock, argv[x]) < 0) {
+                                fatal("nn_connect");
+                        }
+                }
+        }
+        sleep(1); // wait for connections
+        int to = 100;
+        if (nn_setsockopt(sock, NN_SOL_SOCKET, NN_RCVTIMEO, &to,
+            sizeof (to)) < 0) {
+                fatal("nn_setsockopt");
+        }
+
+        // SEND
+        int sz_n = strlen(argv[1]) + 1; // '\0' too
+        printf("%s: SENDING '%s' ONTO BUS\n", argv[1], argv[1]);
+        if (nn_send(sock, argv[1], sz_n, 0) < 0) {
+                fatal("nn_send");
+        }
+
+        // RECV
+        for (;;) {
+                char *buf = NULL;
+                int recv = nn_recv(sock, &buf, NN_MSG, 0);
+                if (recv >= 0) {
+                        printf("%s: RECEIVED '%s' FROM BUS\n", argv[1], buf); // <1>
+                        nn_freemsg(buf);
+                }
+        }
+        return (nn_shutdown(sock, 0));
+}
+
+int
+main(int argc, const char **argv)
+{
+        if (argc >= 3) {
+                return (node(argc, argv));
+        }
+        fprintf(stderr, "Usage: bus <NODE_NAME> <URL> <URL> ...\n");
+        return 1;
+}
diff --git a/_adoc/gettingstarted/src/pair.c b/_adoc/gettingstarted/src/pair.c
new file mode 100644
index 0000000..bf9ba4b
--- /dev/null
+++ b/_adoc/gettingstarted/src/pair.c
@@ -0,0 +1,92 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <nanomsg/nn.h>
+#include <nanomsg/pair.h>
+
+#define NODE0 "node0"
+#define NODE1 "node1"
+
+void
+fatal(const char *func)
+{
+        fprintf(stderr, "%s: %s\n", func, nn_strerror(nn_errno()));
+        exit(1);
+}
+
+int
+send_name(int sock, const char *name)
+{
+        printf("%s: SENDING \"%s\"\n", name, name);
+        int sz_n = strlen(name) + 1; // '\0' too
+        return (nn_send(sock, name, sz_n, 0));
+}
+
+int
+recv_name(int sock, const char *name)
+{
+        char *buf = NULL;
+        int result = nn_recv(sock, &buf, NN_MSG, 0);
+        if (result > 0) {
+                printf("%s: RECEIVED \"%s\"\n", name, buf); // <1>
+                nn_freemsg(buf);
+        }
+        return (result);
+}
+
+int
+send_recv(int sock, const char *name)
+{
+        int to = 100;
+        if (nn_setsockopt(sock, NN_SOL_SOCKET, NN_RCVTIMEO, &to,
+            sizeof (to)) < 0) {
+                fatal("nn_setsockopt");
+        }
+
+        for (;;) {
+                recv_name(sock, name);
+                sleep(1);
+                send_name(sock, name);
+        }
+}
+
+int
+node0(const char *url)
+{
+        int sock;
+        if ((sock = nn_socket(AF_SP, NN_PAIR)) < 0) {
+                fatal("nn_socket");
+        }
+         if (nn_bind(sock, url) < 0) {
+                fatal("nn_bind");
+        }
+        return (send_recv(sock, NODE0));
+}
+
+int
+node1(const char *url)
+{
+        int sock;
+        if ((sock = nn_socket(AF_SP, NN_PAIR)) < 0) {
+                fatal("nn_socket");
+        }
+        if (nn_connect(sock, url) < 0) {
+                fatal("nn_connect");
+        }
+        return (send_recv(sock, NODE1));
+}
+
+int
+main(const int argc, const char **argv)
+{
+        if ((argc > 1) && (strcmp(NODE0, argv[1]) == 0))
+                return (node0(argv[2]));
+
+        if ((argc > 1) && (strcmp(NODE1, argv[1]) == 0))
+                return (node1(argv[2]));
+
+        fprintf(stderr, "Usage: pair %s|%s <URL> <ARG> ...\n", NODE0, NODE1);
+        return 1;
+}
diff --git a/_adoc/gettingstarted/src/pipeline.c b/_adoc/gettingstarted/src/pipeline.c
new file mode 100644
index 0000000..5eca4c6
--- /dev/null
+++ b/_adoc/gettingstarted/src/pipeline.c
@@ -0,0 +1,75 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <nanomsg/nn.h>
+#include <nanomsg/pipeline.h>
+
+#define NODE0 "node0"
+#define NODE1 "node1"
+
+void
+fatal(const char *func)
+{
+        fprintf(stderr, "%s: %s\n", func, nn_strerror(nn_errno()));
+        exit(1);
+}
+
+int
+node0(const char *url)
+{
+        int sock;
+        int rv;
+
+        if ((sock = nn_socket(AF_SP, NN_PULL)) < 0) {
+                fatal("nn_socket");
+        }
+        if ((rv = nn_bind(sock, url)) < 0) {
+                fatal("nn_bind");
+        }
+        for (;;) {
+                char *buf = NULL;
+                int bytes;
+                if ((bytes = nn_recv(sock, &buf, NN_MSG, 0)) < 0) {
+                        fatal("nn_recv");
+                }
+                printf("NODE0: RECEIVED \"%s\"\n", buf); // <1>
+                nn_freemsg(buf);
+        }
+}
+
+int
+node1(const char *url, const char *msg)
+{
+        int sz_msg = strlen(msg) + 1; // '\0' too
+        int sock;
+        int rv;
+        int bytes;
+
+        if ((sock = nn_socket(AF_SP, NN_PUSH)) < 0) {
+                fatal("nn_socket");
+        }
+        if ((rv = nn_connect(sock, url)) < 0) {
+                fatal("nn_connect");
+        }
+        printf("NODE1: SENDING \"%s\"\n", msg);
+        if ((bytes = nn_send(sock, msg, sz_msg, 0)) < 0) {
+                fatal("nn_send");
+        }
+        sleep(1); // wait for messages to flush before shutting down
+        return (nn_shutdown(sock, 0));
+}
+
+int
+main(const int argc, const char **argv)
+{
+        if ((argc > 1) && (strcmp(NODE0, argv[1]) == 0))
+                return (node0(argv[2]));
+
+        if ((argc > 2) && (strcmp(NODE1, argv[1]) == 0))
+                return (node1(argv[2], argv[3]));
+
+        fprintf(stderr, "Usage: pipeline %s|%s <URL> <ARG> ...'\n",
+                NODE0, NODE1);
+        return (1);
+}
diff --git a/_adoc/gettingstarted/src/pubsub.c b/_adoc/gettingstarted/src/pubsub.c
new file mode 100644
index 0000000..ae2ce2e
--- /dev/null
+++ b/_adoc/gettingstarted/src/pubsub.c
@@ -0,0 +1,91 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <nanomsg/nn.h>
+#include <nanomsg/pubsub.h>
+
+#define SERVER "server"
+#define CLIENT "client"
+
+void
+fatal(const char *func)
+{
+        fprintf(stderr, "%s: %s\n", func, nn_strerror(nn_errno()));
+}
+
+char *
+date(void)
+{
+        time_t now = time(&now);
+        struct tm *info = localtime(&now);
+        char *text = asctime(info);
+        text[strlen(text)-1] = '\0'; // remove '\n'
+        return (text);
+}
+
+int
+server(const char *url)
+{
+        int sock;
+
+        if ((sock = nn_socket(AF_SP, NN_PUB)) < 0) {
+                fatal("nn_socket");
+        }
+          if (nn_bind(sock, url) < 0) {
+                fatal("nn_bind");
+        }
+        for (;;) {
+                char *d = date();
+                int sz_d = strlen(d) + 1; // '\0' too
+                printf("SERVER: PUBLISHING DATE %s\n", d);
+                int bytes = nn_send(sock, d, sz_d, 0);
+                if (bytes < 0) {
+                        fatal("nn_send");
+                }
+                sleep(1);
+        }
+}
+
+int
+client(const char *url, const char *name)
+{
+        int sock;
+
+        if ((sock = nn_socket(AF_SP, NN_SUB)) < 0) {
+                fatal("nn_socket");
+        }
+
+        // subscribe to everything ("" means all topics)
+        if (nn_setsockopt(sock, NN_SUB, NN_SUB_SUBSCRIBE, "", 0) < 0) {
+                fatal("nn_setsockopt");
+        }
+        if (nn_connect(sock, url) < 0) {
+                fatal("nn_connet");
+        }
+        for (;;) {
+                char *buf = NULL;
+                int bytes = nn_recv(sock, &buf, NN_MSG, 0);
+                if (bytes < 0) {
+                        fatal("nn_recv");
+                }
+                printf("CLIENT (%s): RECEIVED %s\n", name, buf); // <1>
+                nn_freemsg(buf);
+        }
+}
+
+int
+main(const int argc, const char **argv)
+{
+        if ((argc >= 2) && (strcmp(SERVER, argv[1]) == 0))
+                return (server(argv[2]));
+
+          if ((argc >= 3) && (strcmp(CLIENT, argv[1]) == 0))
+                return (client (argv[2], argv[3]));
+
+        fprintf(stderr, "Usage: pubsub %s|%s <URL> <ARG> ...\n",
+            SERVER, CLIENT);
+        return 1;
+}
diff --git a/_adoc/gettingstarted/src/reqrep.c b/_adoc/gettingstarted/src/reqrep.c
new file mode 100644
index 0000000..d27d94f
--- /dev/null
+++ b/_adoc/gettingstarted/src/reqrep.c
@@ -0,0 +1,100 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <nanomsg/nn.h>
+#include <nanomsg/reqrep.h>
+
+#define NODE0 "node0"
+#define NODE1 "node1"
+#define DATE "DATE"
+
+void
+fatal(const char *func)
+{
+        fprintf(stderr, "%s: %s\n", func, nn_strerror(nn_errno()));
+        exit(1);
+}
+
+char *
+date(void)
+{
+        time_t now = time(&now);
+        struct tm *info = localtime(&now);
+        char *text = asctime(info);
+        text[strlen(text)-1] = '\0'; // remove '\n'
+        return (text);
+}
+
+int
+node0(const char *url)
+{
+        int sz_date = strlen(DATE) + 1; // '\0' too
+        int sock;
+        int rv;
+
+        if ((sock = nn_socket(AF_SP, NN_REP)) < 0) {
+                fatal("nn_socket");
+        }
+          if ((rv = nn_bind(sock, url)) < 0) {
+                fatal("nn_bind");
+        }
+        for (;;) {
+                char *buf = NULL;
+                int bytes;
+                if ((bytes = nn_recv(sock, &buf, NN_MSG, 0)) < 0) {
+                        fatal("nn_recv");
+                }
+                if ((bytes == (strlen(DATE) + 1)) && (strcmp(DATE, buf) == 0)) {
+                        printf("NODE0: RECEIVED DATE REQUEST\n");
+                        char *d = date();
+                        int sz_d = strlen(d) + 1; // '\0' too
+                        printf("NODE0: SENDING DATE %s\n", d);
+                        if ((bytes = nn_send(sock, d, sz_d, 0)) < 0) {
+                                fatal("nn_send");
+                        }
+                }
+                nn_freemsg(buf);
+        }
+}
+
+int
+node1(const char *url)
+{
+        int sz_date = strlen(DATE) + 1; // '\0' too
+        char *buf = NULL;
+        int bytes = -1;
+        int sock;
+        int rv;
+
+        if ((sock = nn_socket(AF_SP, NN_REQ)) < 0) {
+                fatal("nn_socket");
+        }
+        if ((rv = nn_connect (sock, url)) < 0) {
+                fatal("nn_connect");
+        }
+        printf("NODE1: SENDING DATE REQUEST %s\n", DATE);
+        if ((bytes = nn_send(sock, DATE, sz_date, 0)) < 0) {
+                fatal("nn_send");
+        }
+        if ((bytes = nn_recv(sock, &buf, NN_MSG, 0)) < 0) {
+                fatal("nn_recv");
+        }
+        printf("NODE1: RECEIVED DATE %s\n", buf);  // <1>
+        nn_freemsg(buf);
+        return (nn_shutdown(sock, 0));
+}
+
+int
+main(const int argc, const char **argv)
+{
+        if ((argc > 1) && (strcmp(NODE0, argv[1]) == 0))
+                return (node0(argv[2]));
+
+        if ((argc > 1) && (strcmp(NODE1, argv[1]) == 0))
+                return (node1(argv[2]));
+
+      fprintf(stderr, "Usage: reqrep %s|%s <URL> ...\n", NODE0, NODE1);
+      return (1);
+}
+
diff --git a/_adoc/gettingstarted/src/survey.c b/_adoc/gettingstarted/src/survey.c
new file mode 100644
index 0000000..8c3ed0d
--- /dev/null
+++ b/_adoc/gettingstarted/src/survey.c
@@ -0,0 +1,109 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <nanomsg/nn.h>
+#include <nanomsg/survey.h>
+
+#define SERVER "server"
+#define CLIENT "client"
+#define DATE   "DATE"
+
+void
+fatal(const char *func)
+{
+        fprintf(stderr, "%s: %s\n", func, nn_strerror(nn_errno()));
+        exit(1);
+}
+
+char *
+date(void)
+{
+        time_t now = time(&now);
+        struct tm *info = localtime(&now);
+        char *text = asctime(info);
+        text[strlen(text)-1] = '\0'; // remove '\n'
+        return (text);
+}
+
+int
+server(const char *url)
+{
+        int sock;
+
+        if ((sock = nn_socket (AF_SP, NN_SURVEYOR)) < 0) {
+                fatal("nn_socket");
+        }
+        if (nn_bind(sock, url)  < 0) {
+                fatal("nn_bind");
+        }
+        for (;;) {
+                printf("SERVER: SENDING DATE SURVEY REQUEST\n");
+                int bytes = nn_send(sock, DATE, strlen(DATE) + 1, 0);
+                if (bytes < 0) {
+                        fatal("nn_send");
+                }
+
+                for (;;) {
+                        char *buf = NULL;
+                        int bytes = nn_recv(sock, &buf, NN_MSG, 0);
+                        if (bytes < 0) {
+                                if (nn_errno() == ETIMEDOUT) {
+                                        break;
+                                }
+                                fatal("nn_recv");
+                        }
+                        printf("SERVER: RECEIVED \"%s\" SURVEY RESPONSE\n",
+                            buf); // <1>
+                        nn_freemsg(buf);
+                }
+
+                printf("SERVER: SURVEY COMPLETE\n");
+                sleep(1); // Start another survey in a second
+        }
+}
+
+int
+client(const char *url, const char *name)
+{
+        int sock;
+
+        if ((sock = nn_socket(AF_SP, NN_RESPONDENT)) < 0) {
+                fatal("nn_socket");
+        }
+        if (nn_connect (sock, url) < 0) {
+                fatal("nn_connect");
+        }
+            for (;;) {
+                char *buf = NULL;
+                int bytes = nn_recv(sock, &buf, NN_MSG, 0);
+                if (bytes >= 0) {
+                        printf("CLIENT (%s): RECEIVED \"%s\" SURVEY REQUEST\n",
+                            name, buf); // <1>
+                        nn_freemsg(buf);
+                        char *d = date();
+                        int sz_d = strlen(d) + 1; // '\0' too
+                        printf("CLIENT (%s): SENDING DATE SURVEY RESPONSE\n",
+                           name);
+                        if (nn_send(sock, d, sz_d, 0) < 0) {
+                                fatal("nn_send");
+                        }
+                }
+        }
+}
+
+int
+main(const int argc, const char **argv)
+{
+        if ((argc >= 2) && (strcmp(SERVER, argv[1]) == 0))
+                return (server(argv[2]));
+
+        if ((argc >= 3) && (strcmp(CLIENT, argv[1]) == 0))
+                return (client(argv[2], argv[3]));
+
+        fprintf(stderr, "Usage: survey %s|%s <URL> <ARG> ...\n",
+            SERVER, CLIENT);
+        return 1;
+}
diff --git a/_adoc/gettingstarted/survey.adoc b/_adoc/gettingstarted/survey.adoc
new file mode 100644
index 0000000..e871b58
--- /dev/null
+++ b/_adoc/gettingstarted/survey.adoc
@@ -0,0 +1,57 @@
+---
+layout: default
+---
+:source-highlighter: coderay
+:icons: font
+
+include::banner.adoc[]
+
+== Survey (Everybody Votes)
+
+image::survey.png[Everybody Votes]
+
+The surveyor pattern is used to send a timed survey out, responses
+are individually returned until the survey has expired.  This pattern
+is useful for service discovery and voting algorithms.
+
+.survey.c
+[source,c]
+----
+include::src/survey.c[]
+----
+<1> Blithely assumes message is ASCIIZ string. Real code should check it.
+
+.Compilation
+[source,bash]
+----
+gcc survey.c -lnanmosg -o survey
+----
+
+.Execution
+[source,bash]
+----
+./survey server ipc:///tmp/survey.ipc & server=$!
+./survey client ipc:///tmp/survey.ipc client0 & client0=$!
+./survey client ipc:///tmp/survey.ipc client1 & client1=$!
+./survey client ipc:///tmp/survey.ipc client2 & client2=$!
+sleep 4 <1>
+kill $server $client0 $client1 $client2
+----
+<1> The first survey times out with no responders because the clients aren’t started yet.
+
+.Output
+----
+SERVER: SENDING DATE SURVEY REQUEST
+SERVER: SURVEY COMPLETE
+SERVER: SENDING DATE SURVEY REQUEST
+CLIENT (client2): RECEIVED "DATE" SURVEY REQUEST
+CLIENT (client1): RECEIVED "DATE" SURVEY REQUEST
+CLIENT (client0): RECEIVED "DATE" SURVEY REQUEST
+CLIENT (client1): SENDING DATE SURVEY RESPONSE
+CLIENT (client0): SENDING DATE SURVEY RESPONSE
+CLIENT (client2): SENDING DATE SURVEY RESPONSE
+SERVER: RECEIVED "Mon Jan  8 13:10:43 2018" SURVEY RESPONSE
+SERVER: RECEIVED "Mon Jan  8 13:10:43 2018" SURVEY RESPONSE
+SERVER: RECEIVED "Mon Jan  8 13:10:43 2018" SURVEY RESPONSE
+SERVER: SURVEY COMPLETE
+----