Add multi-host support

This refactoring includes:
- added multi-host mode support;
- added support for graceful shutdown of the service;
- added support to flush the log buffer as it fills;
- D-Bus service xyz.openbmc_project.HostLogger replaced with SIGUSR1
  signal handler;
- self diagnostic messages now registered via phosphor-logging;
- added unit tests;
- build system migrated from autotools to meson;
- source code aligned with OpenBMC conventions.

Change-Id: If6c1dfde278af685d8563450543a6587a282c7e4
Signed-off-by: Artem Senichev <a.senichev@yadro.com>
diff --git a/src/main.cpp b/src/main.cpp
index 89b4f58..cb8d2bc 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,201 +1,77 @@
-/**
- * @brief Host logger service entry point.
- *
- * This file is part of HostLogger project.
- *
- * Copyright (c) 2018 YADRO
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// SPDX-License-Identifier: Apache-2.0
+// Copyright (C) 2020 YADRO
 
 #include "config.hpp"
-#include "dbus_server.hpp"
-#include "dbus_watch.hpp"
-#include "log_manager.hpp"
+#include "service.hpp"
+#include "version.hpp"
 
 #include <getopt.h>
 
-#include <climits>
-#include <cstdio>
-#include <cstdlib>
-
-// Global logger configuration instance
-Config loggerConfig = {.path = LOG_OUTPUT_PATH,
-                       .storageSizeLimit = LOG_STORAGE_SIZE_LIMIT,
-                       .storageTimeLimit = LOG_STORAGE_TIME_LIMIT,
-                       .flushPeriod = LOG_FLUSH_PERIOD,
-                       .rotationLimit = LOG_ROTATION_LIMIT};
-
-/** @brief Print title with version info. */
-static void printTitle()
+/** @brief Print version info. */
+static void printVersion()
 {
-    printf("Host logger service " PACKAGE_VERSION ".\n");
+    puts("Host logger service rev." HOSTLOGGER_VERSION ".");
 }
 
-/** @brief Print help usage info.
+/**
+ * @brief Print help usage info.
  *
- *  @param[in] app - application's file name
+ * @param[in] app application's file name
  */
 static void printHelp(const char* app)
 {
-    printTitle();
-    printf("Copyright (c) 2018 YADRO.\n");
-    printf("Usage: %s [options]\n", app);
-    printf(
-        "Options (defaults are specified in brackets):\n"
-        "  -p, --path=PATH   Path used to store logs [%s]\n"
-        "Intermediate storage buffer capacity setup:\n"
-        "  -s, --szlimit=N   Store up to N last messages [%i], 0=unlimited\n"
-        "  -t, --tmlimit=N   Store messages for last N hours [%i], "
-        "0=unlimited\n"
-        "Flush storage buffer policy:\n"
-        "  -f, --flush=N     Flush logs every N hours [%i]\n"
-        "                    If this option is set to 0 flush will be called "
-        "at\n"
-        "                    every host state change event from D-Bus.\n"
-        "Log files rotation policy:\n"
-        "  -r, --rotate=N    Store up to N files in the log directory [%i],\n"
-        "                    0=unlimited\n"
-        "Common options:\n"
-        "  -v, --version     Print version and exit\n"
-        "  -h, --help        Print this help and exit\n",
-        loggerConfig.path, loggerConfig.storageSizeLimit,
-        loggerConfig.storageTimeLimit, loggerConfig.flushPeriod,
-        loggerConfig.rotationLimit);
-}
-
-/** @brief Get numeric positive value from string argument.
- *
- *  @param[in] param - parameter name
- *  @param[in] arg - parameter text value
- *
- *  @return positive numeric value from string argument or -1 on errors
- */
-static int getNumericArg(const char* param, const char* arg)
-{
-    char* ep = nullptr;
-    const unsigned long val = strtoul(arg, &ep, 0);
-    if (val > INT_MAX || !ep || ep == arg || *ep != 0)
-    {
-        fprintf(stderr, "Invalid %s param: %s, expected 0<=N<=%i\n", param, arg,
-                INT_MAX);
-        return -1;
-    }
-    return static_cast<int>(val);
+    printVersion();
+    puts("Copyright (c) 2020 YADRO.");
+    printf("Usage: %s [OPTION...]\n", app);
+    puts("  -v, --version  Print version and exit");
+    puts("  -h, --help     Print this help and exit");
 }
 
 /** @brief Application entry point. */
 int main(int argc, char* argv[])
 {
-    int opt_val;
     // clang-format off
-    const struct option opts[] = {
-        { "path",    required_argument, 0, 'p' },
-        { "szlimit", required_argument, 0, 's' },
-        { "tmlimit", required_argument, 0, 't' },
-        { "flush",   required_argument, 0, 'f' },
-        { "rotate",  required_argument, 0, 'r' },
-        { "version", no_argument,       0, 'v' },
-        { "help",    no_argument,       0, 'h' },
-        { 0,         0,                 0,  0  }
+    const struct option longOpts[] = {
+        { "version", no_argument, nullptr, 'v' },
+        { "help",    no_argument, nullptr, 'h' },
+        { nullptr,   0,           nullptr,  0  }
     };
     // clang-format on
-
-    opterr = 0;
-    while ((opt_val = getopt_long(argc, argv, "p:s:t:f:r:vh", opts, NULL)) !=
-           -1)
+    const char* shortOpts = "vh";
+    opterr = 0; // prevent native error messages
+    int val;
+    while ((val = getopt_long(argc, argv, shortOpts, longOpts, nullptr)) != -1)
     {
-        switch (opt_val)
+        switch (val)
         {
-            case 'p':
-                loggerConfig.path = optarg;
-                if (*loggerConfig.path != '/')
-                {
-                    fprintf(stderr,
-                            "Invalid directory: %s, expected absolute path\n",
-                            loggerConfig.path);
-                    return EXIT_FAILURE;
-                }
-                break;
-            case 's':
-                loggerConfig.storageSizeLimit =
-                    getNumericArg(opts[optind - 1].name, optarg);
-                if (loggerConfig.storageSizeLimit < 0)
-                    return EXIT_FAILURE;
-                break;
-            case 't':
-                loggerConfig.storageTimeLimit =
-                    getNumericArg(opts[optind - 1].name, optarg);
-                if (loggerConfig.storageTimeLimit < 0)
-                    return EXIT_FAILURE;
-                break;
-            case 'f':
-                loggerConfig.flushPeriod =
-                    getNumericArg(opts[optind - 1].name, optarg);
-                if (loggerConfig.flushPeriod < 0)
-                    return EXIT_FAILURE;
-                break;
-            case 'r':
-                loggerConfig.rotationLimit =
-                    getNumericArg(opts[optind - 1].name, optarg);
-                if (loggerConfig.rotationLimit < 0)
-                    return EXIT_FAILURE;
-                break;
             case 'v':
-                printTitle();
+                printVersion();
                 return EXIT_SUCCESS;
             case 'h':
                 printHelp(argv[0]);
                 return EXIT_SUCCESS;
             default:
-                fprintf(stderr, "Invalid option: %s\n", argv[optind - 1]);
+                fprintf(stderr, "Invalid argument: %s\n", argv[optind - 1]);
                 return EXIT_FAILURE;
         }
     }
-
-    int rc;
-
-    // Initialize log manager
-    LogManager logManager;
-    rc = logManager.openHostLog();
-    if (rc != 0)
-        return rc;
-
-    // Initialize D-Bus server
-    sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
-    sd_event* event = nullptr;
-    rc = sd_event_default(&event);
-    if (rc < 0)
+    if (optind < argc)
     {
-        fprintf(stderr, "Error occurred during the sd_event_default: %i\n", rc);
+        fprintf(stderr, "Unexpected argument: %s\n", argv[optind - 1]);
         return EXIT_FAILURE;
     }
-    EventPtr eventPtr(event);
-    bus.attach_event(eventPtr.get(), SD_EVENT_PRIORITY_NORMAL);
 
-    DbusServer dbusMgr(logManager, bus);
-    bus.request_name(HOSTLOGGER_DBUS_IFACE);
-
-    // Initialize D-Bus watcher
-    DbusWatcher dbusWatch(logManager, bus);
-    rc = dbusWatch.initialize();
-    if (rc < 0)
+    try
+    {
+        Config cfg;
+        Service svc(cfg);
+        svc.run();
+    }
+    catch (const std::exception& ex)
+    {
+        fprintf(stderr, "%s\n", ex.what());
         return EXIT_FAILURE;
+    }
 
-    // D-Bus event processing
-    rc = sd_event_loop(eventPtr.get());
-    if (rc != 0)
-        fprintf(stderr, "Error occurred during the sd_event_loop: %i\n", rc);
-
-    return rc ? rc : -1; // Allways retrun an error code
+    return EXIT_SUCCESS;
 }