diff --git a/Makefile b/Makefile
index f22ab4b507975406a2df32250dc3d184bd96951a..b1377c97f7c1094cb232391b7e51c6e3a11e1af0 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 TARGETS=cryptops-api
 CFLAGS=-O0 -g -Wall -D_GNU_SOURCE -Iincludes
-LDLIBS=-L/test/libraries -lcryptsetup -lc -lulfius -lyder -lorcania -ljansson
+LDLIBS=-L./libraries -lcryptsetup -lc -lulfius -lyder -lorcania -ljansson
 CC=gcc
 
 all: $(TARGETS)
diff --git a/cryptops-api.c b/cryptops-api.c
index 65339714361194a2e47cb413bf66959f3c61acd6..ad46f98e2d7c500ffe7bcf18fab5a82ed15fcf19 100644
--- a/cryptops-api.c
+++ b/cryptops-api.c
@@ -1,7 +1,6 @@
 #include <string.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 
 #define U_DISABLE_CURL
 #define U_DISABLE_WEBSOCKET
@@ -9,55 +8,92 @@
 #include <jansson.h>
 #include <libcryptsetup.h>
 
-#define PORT 8000
+#define PORT 8537
 #define PREFIX "/cryptops/v0"
 #define CONTAINER_DEVICE "/dev/xvda1"
-#define MAPPED_DEVICE_NAME "rootdisk"
+#define MAPPED_DEVICE_NAME "xvda1_crypt"
+
+#define FIFO_PATH "/tmp/cryptops-api-stop"
 
 /**
  * helper functions declaration
  */
 char * read_file(const char * filename);
+void stop_server();
+int send_simple_response
+(
+    struct _u_response * response,
+    int http_status,
+    const char *field,
+    const char *value
+);
 
 /**
  * callback functions declaration
  */
-int callback_encryption_unlock (const struct _u_request * request, struct _u_response * response, void * user_data);
-
-int callback_default (const struct _u_request * request, struct _u_response * response, void * user_data);
-
-static int encryption_unlock(const char *path, const char *device_name, const char *password);
+int callback_encryption_unlock
+(
+    const struct _u_request * request,
+    struct _u_response * response,
+    void * user_data
+);
+int callback_default
+(
+    const struct _u_request * request,
+    struct _u_response * response,
+    void * user_data
+);
+static int encryption_unlock
+(
+    const char *path,
+    const char *device_name,
+    const char *password
+);
 
-int main (int argc, char **argv)
+int main(int argc, char **argv)
 {
-    int ret;
-    
-    // Set the framework port number
+    y_init_logs
+    (
+        "cryptops-api",
+        Y_LOG_MODE_CONSOLE,
+        Y_LOG_LEVEL_DEBUG,
+        NULL,
+        "Starting cryptops-api"
+    );
+
     struct _u_instance instance;
-    
-    y_init_logs("cryptops-api", Y_LOG_MODE_CONSOLE, Y_LOG_LEVEL_DEBUG, NULL, "Starting cryptops-api");
-    
     if (ulfius_init_instance(&instance, PORT, NULL, NULL) != U_OK)
     {
         y_log_message(Y_LOG_LEVEL_ERROR, "Error ulfius_init_instance, abort");
         return(1);
     }
-    
+
     u_map_put(instance.default_headers, "Access-Control-Allow-Origin", "*");
-    
-    // Maximum body size sent by the client is 1 Kb
+
+    // Maximum body size sent by the client is 1 Kb.
     instance.max_post_body_size = 1024;
-    
-    // Endpoint list declaration
-    ulfius_add_endpoint_by_val(&instance, "POST", PREFIX, "/encryption/unlock", 0, &callback_encryption_unlock, NULL);
-    
-    // default_endpoint declaration
+
+    // Add api endpoints.
+    ulfius_add_endpoint_by_val
+    (
+        &instance,
+        "POST",
+        PREFIX,
+        "/encryption/unlock",
+        0,
+        &callback_encryption_unlock,
+        NULL
+    );
+
+    // Add default endpoint.
     ulfius_set_default_endpoint(&instance, &callback_default, NULL);
-    
-    // Start the framework
+
+    // Start the framework.
+    int ret;
     if (argc == 4 && strcmp("-secure", argv[1]) == 0)
     {
-        // If command-line options are -secure <key_file> <cert_file>, then open an https connection
+        // If command-line options are -secure <key_file> <cert_file>,
+        // then listen for https connections.
         char * key_pem = read_file(argv[2]), * cert_pem = read_file(argv[3]);
         ret = ulfius_start_secure_framework(&instance, key_pem, cert_pem);
         o_free(key_pem);
@@ -65,16 +101,36 @@ int main (int argc, char **argv)
     }
     else
     {
-        // Open an http connection
+        // Listen for http connections.
         ret = ulfius_start_framework(&instance);
     }
-    
+
     if (ret == U_OK)
     {
-        y_log_message(Y_LOG_LEVEL_DEBUG, "Start %sframework on port %d", ((argc == 4 && strcmp("-secure", argv[1]) == 0)?"secure ":""), instance.port);
+        y_log_message
+        (
+            Y_LOG_LEVEL_DEBUG,
+            "Start %sframework on port %d",
+            ((argc == 4 && strcmp("-secure", argv[1]) == 0)?"secure ":""),
+            instance.port
+        );
         
-        // Wait for the user to press <enter> on the console to quit the application
-        getchar();
+        // Wait for signal from fifo to quit.
+        y_init_logs
+        (
+            "cryptops-api",
+            Y_LOG_MODE_CONSOLE,
+            Y_LOG_LEVEL_DEBUG,
+            NULL,
+            "Waiting for fifo signal to quit"
+        );
+        int fifo = 0;
+        char buf[4];
+        char fifo_path[] = FIFO_PATH;
+        mkfifo(fifo_path, 0600);
+        fifo = open(fifo_path, O_RDONLY);
+        // This will block until the fifo is written to.
+        read(fifo, &buf, 4);
     }
     else
     {
@@ -91,67 +147,86 @@ int main (int argc, char **argv)
 }
 
 /**
- * Callback function that uses the given password to open the luks volume.
+ * Callback function that uses the password passed in the request to open the
+ * luks volume.
  */
-int callback_encryption_unlock(const struct _u_request * request, struct _u_response * response, void * user_data)
+int callback_encryption_unlock
+(
+    const struct _u_request * request,
+    struct _u_response * response,
+    void * user_data
+)
 {
     json_t * json_input = ulfius_get_json_body_request(request, NULL);
-    // json_t * password = json_object_get(json_input, "password");
-    const char * password = json_string_value(json_object_get(json_input, "password"));
+    const char * password;
+    password = json_string_value(json_object_get(json_input, "password"));
   
     if (password == NULL)
     {
-        json_t * json_body = NULL;
-        json_body = json_object();
-        json_object_set_new(json_body, "error", json_string("missing password"));
-        ulfius_set_json_body_response(response, 400, json_body);
-        json_decref(json_body);
-        return U_CALLBACK_CONTINUE; 
+        return send_simple_response(response, 400, "error", "missing password");
     }
   
-    int unlock_status = encryption_unlock(CONTAINER_DEVICE, MAPPED_DEVICE_NAME, password);
+    int unlock_status = encryption_unlock
+    (
+        CONTAINER_DEVICE,
+        MAPPED_DEVICE_NAME,
+        password
+    );
   
     if (unlock_status == -1)
     {
         // Experience learns that -1 is returned when the password is wrong.
-        json_t * json_body = NULL;
-        json_body = json_object();
-        json_object_set_new(json_body, "error", json_string("incorrect password"));
-        ulfius_set_json_body_response(response, 403, json_body);
-        json_decref(json_body);
-        return U_CALLBACK_CONTINUE; 
+        return send_simple_response
+        (
+           response,
+           403,
+           "error",
+           "incorrect password"
+        );
     }
   
     if (unlock_status != 0)
     {
         // Something else went wrong with unlocking.
         printf("encryption_unlock failed with status %d\n", unlock_status);
-        json_t * json_body = NULL;
-        json_body = json_object();
-        json_object_set_new(json_body, "error", json_string("error during unlocking"));
-        ulfius_set_json_body_response(response, 500, json_body);
-        json_decref(json_body);
-        return U_CALLBACK_CONTINUE; 
+        return send_simple_response(response, 500, "error", "error during unlocking");
     }
   
     // If we reach this point, apparently everything went well.
-    json_t * json_body = NULL;
-    json_body = json_object();
-    json_object_set_new(json_body, "status", json_string("ok"));
-    ulfius_set_json_body_response(response, 200, json_body);
-    json_decref(json_body);
-    return U_CALLBACK_CONTINUE; 
+    stop_server();
+    return send_simple_response(response, 200, "status", "ok");
 }
 
 /**
- * Default callback function called if no endpoint has a match
+ * Default callback function called if no other endpoint matches.
  */
-int callback_default(const struct _u_request * request, struct _u_response * response, void * user_data)
+int callback_default
+(
+    const struct _u_request * request,
+    struct _u_response * response,
+    void * user_data
+)
 {
     ulfius_set_string_body_response(response, 404, "Unknown endpoint");
     return U_CALLBACK_CONTINUE;
 }
 
+/**
+ * Use a fifo to signal that we want to stop the api server.
+ */
+void stop_server()
+{
+    printf("Stopping cryptops-api server...\n");
+    int fifo;
+    char fifo_path[] = FIFO_PATH;
+    fifo = open(fifo_path, O_WRONLY);
+    char * msg = "stop";
+    write(fifo, msg, strlen(msg) + 1);
+}
+
+/**
+ * Read a file completely into a string.
+ */
 char * read_file(const char * filename)
 {
     char * buffer = NULL;
@@ -180,17 +255,39 @@ char * read_file(const char * filename)
     }
 }
 
-static int encryption_unlock(const char *path, const char *device_name, const char *password)
+/**
+ * Respond to the request with a simple json structure '{$field: $value}'.
+ */
+int send_simple_response
+(
+    struct _u_response * response, /* response struct to use */
+    int http_status,               /* HTTP status code to return */
+    const char *field,             /* name of the json field to return */
+    const char *value              /* json value to return */
+)
+{
+    json_t * json_body = NULL;
+    json_body = json_object();
+    json_object_set_new(json_body, field, json_string(value));
+    ulfius_set_json_body_response(response, http_status, json_body);
+    json_decref(json_body);
+    return U_CALLBACK_CONTINUE;
+}
+
+/**
+ * Use cryptsetup to unlock the luks container.
+ * This will create `/dev/mapper/$device_name`.
+ */
+static int encryption_unlock
+(
+    const char *path,        /* path to the encrypted container */
+    const char *device_name, /* name of the mapping */
+    const char *password     /* encryption password of the container */
+)
 {
+    // Let LUKS initialise the encrypted device.
     struct crypt_device *cd;
-    int r;
-
-    /*
-     * LUKS device activation example.
-     * It's sequence of sub-steps: device initialization, LUKS header load
-     * and the device activation itself.
-     */
-    r = crypt_init(&cd, path);
+    int r = crypt_init(&cd, path);
     if (r < 0)
     {
         printf("crypt_init() failed for %s.\n", path);
@@ -198,27 +295,29 @@ static int encryption_unlock(const char *path, const char *device_name, const ch
         return r;
     }
 
-    /*
-     * crypt_load() is used to load the LUKS header from block device
-     * into crypt_device context.
-     */
-    r = crypt_load(
-        cd,          /* crypt context */
-        CRYPT_LUKS1, /* requested type */
+    // Load the LUKS header from the block device into the crypt device context.
+    r = crypt_load
+    (
+        cd,          /* crypt device context */
+        CRYPT_LUKS1, /* requested encryption type */
         NULL         /* additional parameters (not used) */
     );
 
     if (r < 0)
     {
-        printf("crypt_load() failed on device %s.\n", crypt_get_device_name(cd));
+        printf
+        (
+            "crypt_load() failed on device %s.\n",
+            crypt_get_device_name(cd)
+        );
         crypt_free(cd);
         return r;
     }
 
-    /*
-     * Device activation creates device-mapper devie mapping with name device_name.
-     */
-    r = crypt_activate_by_passphrase(
+    // Device activation creates device-mapper devie mapping with namei
+    // device_name.
+    r = crypt_activate_by_passphrase
+    (
         cd,                          /* crypt context */
         device_name,                 /* device name to activate */
         CRYPT_ANY_SLOT,              /* which slot use (ANY - try all) */