blob: 9a6f44cd45304ec669c6395a2ff1bbeb2a93ecba [file] [log] [blame]
Artem Senicheve8837d52020-06-07 11:59:04 +03001// SPDX-License-Identifier: Apache-2.0
2// Copyright (C) 2020 YADRO
3
4#include "config.hpp"
5
Nan Zhou042b5ba2021-06-18 09:32:45 -07006#include <sys/un.h>
7
Artem Senicheve8837d52020-06-07 11:59:04 +03008#include <algorithm>
9#include <climits>
10#include <cstring>
11#include <stdexcept>
12#include <string>
13
Nan Zhou042b5ba2021-06-18 09:32:45 -070014namespace
15{
16constexpr char bufferModeStr[] = "buffer";
17constexpr char streamModeStr[] = "stream";
18} // namespace
19
Artem Senicheve8837d52020-06-07 11:59:04 +030020/**
21 * @brief Set boolean value from environment variable.
22 *
23 * @param[in] name name of environment variable
24 * @param[out] value value to set
25 *
26 * @throw std::invalid_argument in case of errors
27 */
28static void safeSet(const char* name, bool& value)
29{
30 const char* envVal = std::getenv(name);
31 if (envVal)
32 {
33 if (strcmp(envVal, "true") == 0)
34 {
35 value = true;
36 }
37 else if (strcmp(envVal, "false") == 0)
38 {
39 value = false;
40 }
41 else
42 {
43 std::string err = "Invalid value of environment variable ";
44 err += name;
45 err += ": '";
46 err += envVal;
47 err += "', expected 'true' or 'false'";
48 throw std::invalid_argument(err);
49 }
50 }
51}
52
53/**
54 * @brief Set unsigned numeric value from environment variable.
55 *
56 * @param[in] name name of environment variable
57 * @param[out] value value to set
58 *
59 * @throw std::invalid_argument in case of errors
60 */
61static void safeSet(const char* name, size_t& value)
62{
63 const char* envVal = std::getenv(name);
64 if (envVal)
65 {
66 const size_t num = strtoul(envVal, nullptr, 0);
67 if (std::all_of(envVal, envVal + strlen(envVal), isdigit) &&
68 num != ULONG_MAX)
69 {
70 value = num;
71 }
72 else
73 {
74 std::string err = "Invalid argument: ";
75 err += envVal;
76 err += ", expected unsigned numeric value";
77 throw std::invalid_argument(err);
78 }
79 }
80}
81
82/**
83 * @brief Set string value from environment variable.
84 *
85 * @param[in] name name of environment variable
86 * @param[out] value value to set
87 */
88static void safeSet(const char* name, const char*& value)
89{
90 const char* envVal = std::getenv(name);
91 if (envVal)
92 {
93 value = envVal;
94 }
95}
96
97Config::Config()
98{
99 safeSet("SOCKET_ID", socketId);
Nan Zhou042b5ba2021-06-18 09:32:45 -0700100 const char* mode_str = bufferModeStr;
101 safeSet("MODE", mode_str);
102 if (strcmp(mode_str, bufferModeStr) == 0)
103 {
104 mode = Mode::bufferMode;
105 }
106 else if (strcmp(mode_str, streamModeStr) == 0)
107 {
108 mode = Mode::streamMode;
109 }
110 else
Artem Senicheve8837d52020-06-07 11:59:04 +0300111 {
112 throw std::invalid_argument(
Nan Zhou042b5ba2021-06-18 09:32:45 -0700113 "Invalid value for mode; expect either 'stream' or 'buffer'");
114 }
115
116 if (mode == Mode::bufferMode)
117 {
118 safeSet("BUF_MAXSIZE", bufMaxSize);
119 safeSet("BUF_MAXTIME", bufMaxTime);
120 safeSet("FLUSH_FULL", bufFlushFull);
121 safeSet("HOST_STATE", hostState);
122 safeSet("OUT_DIR", outDir);
123 safeSet("MAX_FILES", maxFiles);
124 // Validate parameters
125 if (bufFlushFull && !bufMaxSize && !bufMaxTime)
126 {
127 throw std::invalid_argument("Flush policy is set to save the "
128 "buffer as it fills, but buffer's "
129 "limits are not defined");
130 }
131 }
132 else
133 {
134 // mode == Mode::streamMode
135 safeSet("STREAM_DST", streamDestination);
136 // We need an extra +1 for null terminator.
137 if (strlen(streamDestination) + 1 > sizeof(sockaddr_un::sun_path))
138 {
139 throw std::invalid_argument("Invalid STREAM_DST: too long");
140 }
Artem Senicheve8837d52020-06-07 11:59:04 +0300141 }
142}