Add 's' command to the CAPI test application 61/139161/3
authorPiotr Sawicki <p.sawicki2@partner.samsung.com>
Mon, 17 Jul 2017 09:36:36 +0000 (11:36 +0200)
committerZofia Abramowska <z.abramowska@samsung.com>
Tue, 18 Jul 2017 14:02:13 +0000 (14:02 +0000)
From now on, the application has the 's' command which sends a pop-up
request, in the same way as 'r' command does, but after receiving
'deny forever' response it stops the application. Also, the source
code has been reorganised to achieve better readability.

Change-Id: If2bb7fcee45489ac8246bdbf6703ab0f88fdf87c

src/capi/test/privacy_privilege_manager_test.cpp

index 689b99b..e448c39 100644 (file)
@@ -21,7 +21,6 @@
  * @brief       This file contains test of CAPI for Privacy Privilege Manager
  */
 
-#include <iostream>
 #include <map>
 #include <set>
 #include <stdio.h>
@@ -63,6 +62,8 @@ typedef std::set<ServerPrivilegeRequest> PrivilegeRequestSet;
 struct ClientRequest {
     RequestId m_id;
     Privilege m_privilege;
+    GMainLoop *m_mainLoop;
+    bool m_stopAppAfterDeny;
 };
 
 struct Connection
@@ -82,8 +83,8 @@ const GIOCondition GIO_ERROR_CONDITION = static_cast<GIOCondition>(G_IO_ERR | G_
 
 GIOCondition maskToGIOCondition(int mask)
 {
-    int ret = (mask & FdMask::READ ? G_IO_IN : 0) |
-              (mask & FdMask::WRITE ? G_IO_OUT : 0);
+    int ret = ((mask & FdMask::READ) ? G_IO_IN : 0) |
+              ((mask & FdMask::WRITE) ? G_IO_OUT : 0);
     return static_cast<GIOCondition>(ret);
 }
 
@@ -97,7 +98,7 @@ bool isErrorCondition(GIOCondition condition)
     return !!(GIO_ERROR_CONDITION & condition);
 }
 
-void print_prompt(Mode mode)
+void printPrompt(Mode mode)
 {
     switch (mode) {
         case Mode::CLIENT:
@@ -115,25 +116,118 @@ void print_prompt(Mode mode)
     fflush(stdout);
 }
 
+const char *popupResultToString(ppm_popup_result_e result)
+{
+    switch (result) {
+        case PRIVACY_PRIVILEGE_MANAGER_POPUP_RESULT_ALLOW_FOREVER:
+            return "ALLOW_FOREVER";
+        case PRIVACY_PRIVILEGE_MANAGER_POPUP_RESULT_DENY_FOREVER:
+            return "DENY_FOREVER";
+        case PRIVACY_PRIVILEGE_MANAGER_POPUP_RESULT_DENY_ONCE:
+            return "DENY_ONCE";
+    }
+
+    return "UNKNOWN";
+}
+
+void printClientHelp()
+{
+    printf("c <privilege>   check privilege status\n");
+    printf("r <privilege>   send popup request\n");
+    printf("s <privilege>   send popup request, additionally after receiving DENY it finishes this app\n");
+    printf("h               print help\n");
+    printf("q               quit\n");
+    printPrompt(Mode::CLIENT);
+}
+
+void printClientError(ppm_error_e error)
+{
+    switch (error) {
+        case PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE:
+            break;
+        case PRIVACY_PRIVILEGE_MANAGER_ERROR_IO_ERROR:
+            printf("I/O error\n");
+            break;
+        case  PRIVACY_PRIVILEGE_MANAGER_ERROR_INVALID_PARAMETER:
+            printf("Invalid parameters\n");
+            break;
+        case PRIVACY_PRIVILEGE_MANAGER_ERROR_OUT_OF_MEMORY:
+            printf("Out of memory\n");
+            break;
+        case PRIVACY_PRIVILEGE_MANAGER_ERROR_UNKNOWN:
+            printf("Unknown error\n");
+            break;
+    }
+}
+
+void printClientCheckResult(ppm_check_result_e result)
+{
+    printf("res: ");
+
+    switch (result) {
+        case  PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ALLOW:
+            printf("ALLOW\n");
+            break;
+        case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_DENY:
+            printf("DENY\n");
+            break;
+        case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ASK:
+            printf("ASK\n");
+            break;
+    }
+
+    printPrompt(Mode::CLIENT);
+}
+
+void printAppHelp(const char *programName)
+{
+    printf("Usage: %s [OPTIONS]\n", programName);
+    printf("Allows to test CAPI for Privacy Privilege Manager.\n");
+    printf("This program can run in two modes: as a client and as a server.\n");
+    printf("You can use it in two scenarios:\n");
+    printf("1. Run as a client (%s -c) to trigger popups in the askuser-notification daemon.\n", programName);
+    printf("2. Run one part as a client (%s -c) and other one as a server (%s -s).\n",
+           programName, programName);
+    printf("If you want to run this program as a root you need to create /var/run/user_ext/0 folder.\n");
+    printf("To run this program in context of some Tizen's application, type in the console:\n");
+    printf("#echo <SMACK label of the application> > /proc/self/attr/current\n");
+    printf("#su - <user name>\n\n");
+    printf("Options:\n");
+    printf("-s  run as a server\n");
+    printf("-c  run as a client (uses CAPI)\n");
+    printf("-h  display this help end exit\n");
+}
+
+void printServerHelp()
+{
+    printf("l                       list all connections\n");
+    printf("s                       list all requests\n");
+    printf("ra <fd> <request id>    send ALLOW FOREVER response\n");
+    printf("rd <fd> <request id>    send DENY FOREVER response\n");
+    printf("ro <fd> <request id>    send DENY ONCE response\n");
+    printf("c  <fd>                 close connection\n");
+    printf("h                       print help\n");
+    printf("q                       quit\n");
+    printPrompt(Mode::SERVER);
+}
+
 struct ServerSimulator : public IServerCallbacks {
 
     ServerSimulator()
     : m_channel(nullptr)
-    {
-    }
+    {}
 
     virtual void newConnection(ConnectionFd fd, const Credentials &creds) {
         printf("\nnew connection fd: %d credentials = { label: \"%s\" uid: %s }",
                fd, creds.label.c_str(), creds.uid.c_str());
     }
 
-    static gboolean server_gio_cb(GIOChannel *src, GIOCondition cond, gpointer data)
-    {
+    static gboolean serverGIOCallback(GIOChannel *src, GIOCondition cond, gpointer data) {
         ServerSimulator *handle = static_cast<ServerSimulator *>(data);
 
         int fd = g_io_channel_unix_get_fd(src);
-        int events = (cond & G_IO_IN ? FdMask::READ : 0) |
-                     (cond & G_IO_OUT ? FdMask::WRITE : 0);
+        int events = ((cond & G_IO_IN) ? FdMask::READ : 0) |
+                     ((cond & G_IO_OUT) ? FdMask::WRITE : 0);
 
         handle->m_channel->process(fd, isErrorCondition(cond) ? 0 : events);
 
@@ -163,7 +257,7 @@ struct ServerSimulator : public IServerCallbacks {
             m_requests.erase(fd);
 
             printf("Connection for fd: %d has been closed\n", fd);
-            print_prompt(Mode::SERVER);
+            printPrompt(Mode::SERVER);
             return;
         }
 
@@ -175,7 +269,7 @@ struct ServerSimulator : public IServerCallbacks {
 
             guint watch_id = g_io_add_watch(gio_channel,
                                       makeCondition(gio_condition),
-                                      server_gio_cb,
+                                      serverGIOCallback,
                                       this);
 
             m_connections.insert({ fd, Connection{gio_channel, gio_condition, watch_id }});
@@ -190,7 +284,7 @@ struct ServerSimulator : public IServerCallbacks {
             g_source_remove(connection.watch_id);
             connection.watch_id = g_io_add_watch(connection.gio_channel,
                                                  makeCondition(connection.condition),
-                                                 server_gio_cb,
+                                                 serverGIOCallback,
                                                  this);
         }
     }
@@ -198,15 +292,10 @@ struct ServerSimulator : public IServerCallbacks {
     virtual void popup(ConnectionFd fd, RequestId id, Privilege &&privilege) {
         printf("\npopup request fd: %d requestId: %d privilege: \"%s\"\n", fd, id, privilege.c_str());
         addRequest(fd, id, privilege);
-        print_prompt(Mode::SERVER);
+        printPrompt(Mode::SERVER);
     }
 
     void addRequest(ConnectionFd fd, RequestId id, const Privilege &privilege) {
-        auto fdIt = m_requests.find(fd);
-        if (fdIt == m_requests.end()) {
-            m_requests.insert({ fd, PrivilegeRequestSet() });
-        }
-
         auto &s = m_requests[fd];
 
         auto reqIt = s.find(id);
@@ -257,7 +346,7 @@ struct ServerSimulator : public IServerCallbacks {
         auto it = m_connections.find(fd);
         if (it == m_connections.end()) {
             printf("ERROR: Connection fd: %d not found\n", fd);
-            print_prompt(Mode::SERVER);
+            printPrompt(Mode::SERVER);
             return;
         }
 
@@ -282,307 +371,247 @@ private:
     std::map<ConnectionFd,  PrivilegeRequestSet> m_requests;
 };
 
-struct AppContext {
+class AppContext {
+public:
     AppContext()
-    : m_serverSimulator(nullptr)
+    : m_mainloop(g_main_loop_new(nullptr, FALSE))
+    , m_serverSimulator(nullptr)
     , m_channel(nullptr)
     , m_mode(Mode::UNKNOWN)
     {}
 
     ~AppContext() {
+        g_main_loop_unref(m_mainloop);
+
         if (m_channel != nullptr) {
             delete m_channel;
         }
     }
 
-    void initialize() {
-        if (m_mode == Mode::SERVER) {
-            m_serverSimulator = new ServerSimulator();
-            m_channel = new ServerChannel(ServerCallbacksPtr(m_serverSimulator));
-            m_serverSimulator->setServerChannel(m_channel);
+    void initialize(int argc, char **argv) {
+        if (argc < 1) {
+            throw std::logic_error("AppContext::initialize called with argc < 1");
         }
-    }
-
-    ServerSimulator *m_serverSimulator;
-    ServerChannel *m_channel;
-    Mode m_mode;
-};
-
-const char *popup_result_to_str(ppm_popup_result_e result)
-{
-    switch (result) {
-        case PRIVACY_PRIVILEGE_MANAGER_POPUP_RESULT_ALLOW_FOREVER:
-            return "ALLOW_FOREVER";
-        case PRIVACY_PRIVILEGE_MANAGER_POPUP_RESULT_DENY_FOREVER:
-            return "DENY_FOREVER";
-        case PRIVACY_PRIVILEGE_MANAGER_POPUP_RESULT_DENY_ONCE:
-            return "DENY_ONCE";
-    }
 
-    return "UNKNOWN";
-}
-
-void popup_response_cb(ppm_call_cause_e cause, ppm_popup_result_e result, void *user_data)
-{
-    ClientRequest *request = static_cast<ClientRequest *>(user_data);
-    if (request == nullptr) {
-        printf("ERROR: User data is nullptr\n");
-        return;
-    }
+        int c;
+        opterr = 0;
+        while ((c = getopt (argc, argv, "sch")) != -1) {
+            switch (c) {
+                case 's':
+                    m_mode = Mode::SERVER;
+                    break;
+                case 'c':
+                    m_mode = Mode::CLIENT;
+                    break;
+                case 'h':
+                default:
+                    break;
+            }
+        }
 
-    printf("localId: %d privilege: \"%s\" ", request->m_id, request->m_privilege.c_str());
+        switch (m_mode) {
+            case Mode::SERVER:
+                m_serverSimulator = new ServerSimulator();
+                m_channel = new ServerChannel(ServerCallbacksPtr(m_serverSimulator));
+                m_serverSimulator->setServerChannel(m_channel);
+                printServerHelp();
+                break;
+            case Mode::CLIENT:
+                printClientHelp();
+                break;
+            case Mode::UNKNOWN:
+            default:
+                printAppHelp(argv[0]);
+                exit(EXIT_SUCCESS);
+        }
 
-    switch (cause) {
-        case PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ANSWER:
-            printf("popup response ANSWER: %s\n", popup_result_to_str(result));
-            break;
-        case PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ERROR:
-            printf("popup response ERROR cause: PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ERROR\n");
-            break;
+        GIOChannel *gio_channel = g_io_channel_unix_new(0);
+        g_io_add_watch(gio_channel, static_cast<GIOCondition>(G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL),
+                       &AppContext::mainLoopCallback, this);
     }
 
-    delete request;
-
-    print_prompt(Mode::CLIENT);
-}
-
-void print_client_help()
-{
-    printf("c <privilege>   check privilege status\n");
-    printf("r <privilege>   send popup request\n");
-    printf("h               print help\n");
-    printf("q               quit\n");
-    print_prompt(Mode::CLIENT);
-}
+    void run() {
+        if (m_mode == Mode::UNKNOWN) {
+            throw std::logic_error("AppContext is not initialized");
+        }
 
-void print_client_error(ppm_error_e error)
-{
-    switch (error) {
-        case PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE:
-            break;
-        case PRIVACY_PRIVILEGE_MANAGER_ERROR_IO_ERROR:
-            printf("I/O error\n");
-            break;
-        case  PRIVACY_PRIVILEGE_MANAGER_ERROR_INVALID_PARAMETER:
-            printf("Invalid parameters\n");
-            break;
-        case PRIVACY_PRIVILEGE_MANAGER_ERROR_OUT_OF_MEMORY:
-            printf("Out of memory\n");
-            break;
-        case PRIVACY_PRIVILEGE_MANAGER_ERROR_UNKNOWN:
-            printf("Unknown error\n");
-            break;
+        g_main_loop_run(m_mainloop);
     }
-}
 
-static void print_client_check_result(ppm_check_result_e result)
-{
-    printf("res: ");
+private:
 
-    switch (result) {
-        case  PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ALLOW:
-            printf("ALLOW\n");
-            break;
-        case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_DENY:
-            printf("DENY\n");
-            break;
-        case PRIVACY_PRIVILEGE_MANAGER_CHECK_RESULT_ASK:
-            printf("ASK\n");
-            break;
-    }
+    static void popupResponseCallback(ppm_call_cause_e cause, ppm_popup_result_e result, void *user_data) {
+        ClientRequest *request = static_cast<ClientRequest *>(user_data);
+        if (request == nullptr) {
+            printf("ERROR: User data is nullptr\n");
+            return;
+        }
 
-    print_prompt(Mode::CLIENT);
-}
+        printf("localId: %d privilege: \"%s\" ", request->m_id, request->m_privilege.c_str());
 
-void handle_client(char *buffer)
-{
-    ppm_check_result_e result;
-    ppm_error_e err = PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE;
-    ClientRequest *request = nullptr;
-    char *privilege = nullptr;
-    static RequestId clientRequestId;
-
-    switch (buffer[0]) {
-        case 'c':
-            if (strlen(buffer) < 3) {
-                print_client_help();
+        switch (cause) {
+            case PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ANSWER:
+                printf("popup response ANSWER: %s\n", popupResultToString(result));
                 break;
-            }
-            err = static_cast<ppm_error_e>(ppm_check_privilege(&buffer[2], &result));
-            if (err == PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) {
-                print_client_check_result(result);
-            }
-            break;
-        case 'r':
-            if (strlen(buffer) < 3) {
-                print_client_help();
+            case PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ERROR:
+                printf("popup response ERROR cause: PRIVACY_PRIVILEGE_MANAGER_CALL_CAUSE_ERROR\n");
                 break;
-            }
-
-            buffer[strlen(buffer)] = '\0'; // erase new line
-            privilege = &buffer[2];
+        }
 
-            printf("sending localId: %d privilege: \"%s\"\n", clientRequestId, privilege);
+        if (result == PRIVACY_PRIVILEGE_MANAGER_POPUP_RESULT_DENY_FOREVER && request->m_stopAppAfterDeny) {
+            g_main_loop_quit(request->m_mainLoop);
+        }
 
-            request = new ClientRequest{ clientRequestId++, privilege };
-            err = static_cast<ppm_error_e>(ppm_popup_request(privilege, popup_response_cb, request));
-            if (err != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) {
-                delete request;
-            }
+        delete request;
 
-            break;
-        case 'q':
-            exit(EXIT_SUCCESS);
-        case 'h':
-        default:
-            print_client_help();
-            return;
+        printPrompt(Mode::CLIENT);
     }
 
-    print_client_error(err);
-    print_prompt(Mode::CLIENT);
-}
+    void handleClient(char *buffer) {
+        ppm_check_result_e result;
+        ppm_error_e err = PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE;
+        ClientRequest *request = nullptr;
+        char *privilege = nullptr;
+        static RequestId clientRequestId;
+        bool stopAppAfterDeny = false;
 
-void print_server_help()
-{
-    printf("l                       list all connections\n");
-    printf("s                       list all requests\n");
-    printf("ra <fd> <request id>    send ALLOW FOREVER response\n");
-    printf("rd <fd> <request id>    send DENY FOREVER response\n");
-    printf("ro <fd> <request id>    send DENY ONCE response\n");
-    printf("c  <fd>                 close connection\n");
-    printf("h                       print help\n");
-    printf("q                       quit\n");
-    print_prompt(Mode::SERVER);
-}
+        switch (buffer[0]) {
+            case 'c':
+                if (strlen(buffer) < 3) {
+                    printClientHelp();
+                    break;
+                }
+                err = static_cast<ppm_error_e>(ppm_check_privilege(&buffer[2], &result));
+                if (err == PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) {
+                    printClientCheckResult(result);
+                }
+                break;
+            case 's':
+                stopAppAfterDeny = true;
+            case 'r':
+                if (strlen(buffer) < 3) {
+                    printClientHelp();
+                    break;
+                }
 
-void handle_server(const char *buffer, ServerSimulator *serverSimulator)
-{
-    int res;
-    ConnectionFd fd;
-    RequestId requestId;
+                buffer[strlen(buffer)] = '\0'; // erase new line
+                privilege = &buffer[2];
 
-    switch (buffer[0]) {
-        case 'l':
-            serverSimulator->showConnections();
-            break;
-        case 's':
-            serverSimulator->showPrivilegeRequests();
-            break;
-        case 'r':
-            res = sscanf(&buffer[2], "%d %d", &fd, &requestId);
-            if (res != 2) {
-                print_server_help();
+                printf("sending localId: %d privilege: \"%s\"\n", clientRequestId, privilege);
+
+                request = new ClientRequest{ clientRequestId++, privilege, m_mainloop, stopAppAfterDeny };
+                err = static_cast<ppm_error_e>(ppm_popup_request(privilege, &AppContext::popupResponseCallback, request));
+                if (err != PRIVACY_PRIVILEGE_MANAGER_ERROR_NONE) {
+                    delete request;
+                }
+
+                break;
+            case 'q':
+                g_main_loop_quit(m_mainloop);
                 return;
-            }
-            switch (buffer[1]) {
-                case 'a':
-                    serverSimulator->sendResponse(fd, requestId, ASKUSER_ALLOW_FOREVER);
-                    break;
-                case 'd':
-                    serverSimulator->sendResponse(fd, requestId, ASKUSER_DENY_FOREVER);
-                    break;
-                case 'o':
-                    serverSimulator->sendResponse(fd, requestId, ASKUSER_DENY_ONCE);
-                    break;
-                default:
-                    print_server_help();
-                    return;
-            }
-            break;
-        case 'c':
-            res = sscanf(&buffer[1], "%d", &fd);
-            if (res != 1) {
-                print_server_help();
+            case 'h':
+            default:
+                printClientHelp();
                 return;
-            }
-            serverSimulator->closeConnection(fd);
-            return;
-        case 'h':
-            print_server_help();
-            return;
-        case 'q':
-            exit(EXIT_SUCCESS);
+        }
+
+        printClientError(err);
+        printPrompt(Mode::CLIENT);
     }
 
-    print_prompt(Mode::SERVER);
-}
+    void handleServer(const char *buffer) {
+        int res;
+        ConnectionFd fd;
+        RequestId requestId;
 
-gboolean main_loop_cb(UNUSED GIOChannel *channel, UNUSED GIOCondition cond, gpointer user_data)
-{
-    char buffer[4096];
+        switch (buffer[0]) {
+            case 'l':
+                m_serverSimulator->showConnections();
+                break;
+            case 's':
+                m_serverSimulator->showPrivilegeRequests();
+                break;
+            case 'r':
+                res = sscanf(&buffer[2], "%d %d", &fd, &requestId);
+                if (res != 2) {
+                    printServerHelp();
+                    return;
+                }
+                switch (buffer[1]) {
+                    case 'a':
+                        m_serverSimulator->sendResponse(fd, requestId, ASKUSER_ALLOW_FOREVER);
+                        break;
+                    case 'd':
+                        m_serverSimulator->sendResponse(fd, requestId, ASKUSER_DENY_FOREVER);
+                        break;
+                    case 'o':
+                        m_serverSimulator->sendResponse(fd, requestId, ASKUSER_DENY_ONCE);
+                        break;
+                    default:
+                        printServerHelp();
+                        return;
+                }
+                break;
+            case 'c':
+                res = sscanf(&buffer[1], "%d", &fd);
+                if (res != 1) {
+                    printServerHelp();
+                    return;
+                }
+                m_serverSimulator->closeConnection(fd);
+                return;
+            case 'h':
+                printServerHelp();
+                return;
+            case 'q':
+                g_main_loop_quit(m_mainloop);
+                return;
+        }
 
-    int ret = read(0, buffer, sizeof(buffer));
-    if (ret <= 0) {
-        printf("read from stdin failed\n");
-        exit(EXIT_FAILURE);
+        printPrompt(Mode::SERVER);
     }
 
-    buffer[ret - 1] = '\0';
+    static gboolean mainLoopCallback(UNUSED GIOChannel *channel, UNUSED GIOCondition cond, gpointer user_data) {
+        char buffer[4096];
 
-    AppContext *ctx = static_cast<AppContext *>(user_data);
-    switch (ctx->m_mode) {
-        case Mode::CLIENT:
-            handle_client(buffer);
-            break;
-        case Mode::SERVER:
-            handle_server(buffer, ctx->m_serverSimulator);
-            break;
-        case Mode::UNKNOWN:
-        default:
-            printf("Mode not set, exiting.\n");
+        int ret = read(0, buffer, sizeof(buffer));
+        if (ret <= 0) {
+            printf("read from stdin failed\n");
             exit(EXIT_FAILURE);
-    }
-
-    return TRUE;
-}
-
-void print_help(const char *programName)
-{
-    printf("Usage: %s [OPTIONS]\n", programName);
-    printf("Allows to test CAPI for Privacy Privilege Manager.\n");
-    printf("This program can run in two modes: as a client and as a server.\n");
-    printf("You can use it in two scenarios:\n");
-    printf("1. Run as a client (%s -c) to trigger popups in the askuser-notification daemon.\n", programName);
-    printf("2. Run one part as a client (%s -c) and other one as a server (%s -s).\n",
-           programName, programName);
-    printf("If you want to run this program as a root you need to create /var/run/user_ext/0 folder.\n");
-    printf("To run this program in context of some Tizen's application, type in the console:\n");
-    printf("#echo <SMACK label of the application> > /proc/self/attr/current\n");
-    printf("#su - <user name>\n\n");
-    printf("Options:\n");
-    printf("-s  run as a server\n");
-    printf("-c  run as a client (uses CAPI)\n");
-    printf("-h  display this help end exit\n");
-}
+        }
 
-int main(int argc, char **argv)
-{
-    AppContext ctx;
-    int c;
+        buffer[ret - 1] = '\0';
 
-    opterr = 0;
-    while ((c = getopt (argc, argv, "sch")) != -1) {
-        switch (c) {
-            case 's':
-                ctx.m_mode = Mode::SERVER;
+        AppContext *ctx = static_cast<AppContext *>(user_data);
+        switch (ctx->m_mode) {
+            case Mode::CLIENT:
+                ctx->handleClient(buffer);
                 break;
-            case 'c':
-                ctx.m_mode = Mode::CLIENT;
+            case Mode::SERVER:
+                ctx->handleServer(buffer);
                 break;
-            case 'h':
+            case Mode::UNKNOWN:
             default:
-                break;
+                printf("Mode not set, exiting.\n");
+                exit(EXIT_FAILURE);
         }
-    }
 
-    if (ctx.m_mode == Mode::UNKNOWN) {
-        print_help(argv[0]);
-        exit(EXIT_SUCCESS);
+        return TRUE;
     }
 
+    GMainLoop *m_mainloop;
+    ServerSimulator *m_serverSimulator;
+    ServerChannel *m_channel;
+    Mode m_mode;
+};
+
+int main(int argc, char **argv)
+{
+    AppContext appCtx;
+
     try {
-        ctx.initialize();
+        appCtx.initialize(argc, argv);
+        appCtx.run();
     }
     catch (const ConnectionException &e) {
         printf("Connection exception occured during initialization: %s, exiting.\n", e.what());
@@ -598,26 +627,5 @@ int main(int argc, char **argv)
         exit(EXIT_FAILURE);
     }
 
-    switch (ctx.m_mode) {
-        case Mode::SERVER:
-            print_server_help();
-            break;
-        case Mode::CLIENT:
-            print_client_help();
-            break;
-        case Mode::UNKNOWN:
-        default:
-            printf("Unknown mode\n");
-            exit(EXIT_FAILURE);
-    }
-
-    GMainLoop *mainloop = g_main_loop_new(nullptr, FALSE);
-
-    GIOChannel *gio_channel = g_io_channel_unix_new(0);
-    g_io_add_watch(gio_channel, static_cast<GIOCondition>(G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL),
-                   main_loop_cb, &ctx);
-
-    g_main_loop_run(mainloop);
-
     return 0;
 }