summaryrefslogtreecommitdiffstats
path: root/fluent-bit/src/flb_env.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-03-09 13:19:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-03-09 13:20:02 +0000
commit58daab21cd043e1dc37024a7f99b396788372918 (patch)
tree96771e43bb69f7c1c2b0b4f7374cb74d7866d0cb /fluent-bit/src/flb_env.c
parentReleasing debian version 1.43.2-1. (diff)
downloadnetdata-58daab21cd043e1dc37024a7f99b396788372918.tar.xz
netdata-58daab21cd043e1dc37024a7f99b396788372918.zip
Merging upstream version 1.44.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'fluent-bit/src/flb_env.c')
-rw-r--r--fluent-bit/src/flb_env.c273
1 files changed, 273 insertions, 0 deletions
diff --git a/fluent-bit/src/flb_env.c b/fluent-bit/src/flb_env.c
new file mode 100644
index 000000000..3b9158095
--- /dev/null
+++ b/fluent-bit/src/flb_env.c
@@ -0,0 +1,273 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* Fluent Bit
+ * ==========
+ * Copyright (C) 2015-2022 The Fluent Bit Authors
+ *
+ * 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.
+ */
+
+#include <fluent-bit/flb_info.h>
+#include <fluent-bit/flb_hash_table.h>
+#include <fluent-bit/flb_mem.h>
+#include <fluent-bit/flb_log.h>
+#include <fluent-bit/flb_str.h>
+#include <fluent-bit/flb_env.h>
+
+#include <stdlib.h>
+
+static inline flb_sds_t buf_append(flb_sds_t buf, const char *str, int len)
+{
+ flb_sds_t tmp;
+
+ tmp = flb_sds_cat(buf, str, len);
+ if (!tmp) {
+ return NULL;
+ }
+
+ return tmp;
+}
+
+/* Preset some useful variables */
+static int env_preset(struct flb_env *env)
+{
+ int ret;
+ char *buf;
+ char tmp[512];
+
+ /*
+ * ${HOSTNAME} this variable is very useful to identify records,
+ * despite this variable is recognized by the Shell, that does not
+ * means that is exposed as a real environment variable, e.g:
+ *
+ * 1. $ echo $HOSTNAME
+ * monotop
+ * 2. $ env | grep HOSTNAME
+ * (nothing)
+ */
+ buf = getenv("HOSTNAME");
+ if (!buf) {
+ ret = gethostname(tmp, sizeof(tmp) - 1);
+ if (ret == 0) {
+ flb_env_set(env, "HOSTNAME", tmp);
+ }
+ }
+
+ return 0;
+}
+
+struct flb_env *flb_env_create()
+{
+ struct flb_env *env;
+ struct flb_hash_table *ht;
+
+ env = flb_malloc(sizeof(struct flb_env));
+ if (!env) {
+ flb_errno();
+ return NULL;
+ }
+
+ /* Create the hash-table */
+ ht = flb_hash_table_create(FLB_HASH_TABLE_EVICT_NONE, FLB_ENV_SIZE, -1);
+ if (!ht) {
+ flb_free(env);
+ return NULL;
+ }
+
+ env->warn_unused = FLB_TRUE;
+ env->ht = ht;
+ env_preset(env);
+
+ return env;
+}
+
+void flb_env_destroy(struct flb_env *env)
+{
+ flb_hash_table_destroy(env->ht);
+ flb_free(env);
+}
+
+int flb_env_set(struct flb_env *env, const char *key, const char *val)
+{
+ int id;
+ int klen;
+ int vlen;
+ void *out_buf;
+ size_t out_size;
+
+ /* Get lengths */
+ klen = strlen(key);
+ vlen = strlen(val);
+
+ /* Check if the key is already set */
+ id = flb_hash_table_get(env->ht, key, klen, &out_buf, &out_size);
+ if (id >= 0) {
+ /* Remove the old entry */
+ flb_hash_table_del(env->ht, key);
+ }
+
+ /* Register the new key */
+ id = flb_hash_table_add(env->ht, key, klen, (void *) val, vlen);
+ return id;
+}
+
+const char *flb_env_get(struct flb_env *env, const char *key)
+{
+ int len;
+ int ret;
+ void *out_buf;
+ size_t out_size;
+
+ if (!key) {
+ return NULL;
+ }
+
+ len = strlen(key);
+
+ /* Try to get the value from the hash table */
+ ret = flb_hash_table_get(env->ht, key, len, &out_buf, &out_size);
+ if (ret >= 0) {
+ return (char *) out_buf;
+ }
+
+ /* If it was not found, try to get it from the real environment */
+ out_buf = getenv(key);
+ if (!out_buf) {
+ return NULL;
+ }
+
+ if (strlen(out_buf) == 0) {
+ return NULL;
+ }
+
+ return (char *) out_buf;
+}
+
+/*
+ * Given a 'value', lookup for variables, if found, return a new composed
+ * sds string.
+ */
+flb_sds_t flb_env_var_translate(struct flb_env *env, const char *value)
+{
+ int i;
+ int len;
+ int v_len;
+ int e_len;
+ int pre_var;
+ int have_var = FLB_FALSE;
+ const char *env_var = NULL;
+ char *v_start = NULL;
+ char *v_end = NULL;
+ char tmp[4096];
+ flb_sds_t buf;
+ flb_sds_t s;
+
+ if (!value) {
+ return NULL;
+ }
+
+ len = strlen(value);
+ buf = flb_sds_create_size(len);
+ if (!buf) {
+ return NULL;
+ }
+
+ for (i = 0; i < len; i++) {
+ v_start = strstr(value + i, "${");
+ if (!v_start) {
+ break;
+ }
+
+ v_end = strstr(value + i, "}");
+ if (!v_end) {
+ break;
+ }
+
+ v_start += 2;
+ v_len = v_end - v_start;
+ if (v_len <= 0 || v_len >= sizeof(tmp)) {
+ break;
+ }
+
+ /* variable */
+ strncpy(tmp, v_start, v_len);
+ tmp[v_len] = '\0';
+ have_var = FLB_TRUE;
+
+ /* Append pre-variable content */
+ pre_var = (v_start - 2) - (value + i);
+ if (pre_var > 0) {
+ s = buf_append(buf, value + i, (v_start - 2) - (value + i));
+ if (!s) {
+ flb_sds_destroy(buf);
+ return NULL;
+ }
+ if (s != buf) {
+ buf = s;
+ }
+ }
+
+ /* Lookup the variable in our env-hash */
+ env_var = flb_env_get(env, tmp);
+ if (env_var) {
+ e_len = strlen(env_var);
+ s = buf_append(buf, env_var, e_len);
+ if (!s) {
+ flb_sds_destroy(buf);
+ return NULL;
+ }
+ if (s != buf) {
+ buf = s;
+ }
+ }
+ else if (env->warn_unused == FLB_TRUE) {
+ flb_warn("[env] variable ${%s} is used but not set", tmp);
+ }
+ i += (v_start - (value + i)) + v_len;
+ }
+
+ /* Copy the remaining value into our buffer */
+ if (v_end) {
+ if (have_var == FLB_TRUE && (value + len) - (v_end + 1) > 0) {
+ s = buf_append(buf, v_end + 1, (value + len) - (v_end + 1));
+ if (!s) {
+ flb_sds_destroy(buf);
+ return NULL;
+ }
+ if (s != buf) {
+ buf = s;
+ }
+ }
+ }
+
+ if (flb_sds_len(buf) == 0) {
+ /*
+ * If the output length buffer is zero, it could mean:
+ *
+ * - just one variable was given and it don't have any value
+ * - no variables given (keep original value)
+ *
+ * In order to avoid problems in the caller, if a variable is null
+ * and is the only one content available, return a new empty memory
+ * string.
+ */
+ if (have_var == FLB_TRUE) {
+ return flb_sds_copy(buf, "", 0);
+ }
+ else {
+ return flb_sds_copy(buf, value, len);
+ }
+ }
+
+ return buf;
+}