mirror of
https://github.com/rsyslog/rsyslog.git
synced 2025-12-16 02:50:40 +01:00
This commit applies the new canonical formatting style using `clang-format` with custom settings (notably 4-space indentation), as part of our shift toward automated formatting normalization. ⚠️ No functional changes are included — only whitespace and layout modifications as produced by `clang-format`. This change is part of the formatting modernization strategy discussed in: https://github.com/rsyslog/rsyslog/issues/5747 Key context: - Formatting is now treated as a disposable view, normalized via tooling. - The `.clang-format` file defines the canonical style. - A fixup script (`devtools/format-code.sh`) handles remaining edge cases. - Formatting commits are added to `.git-blame-ignore-revs` to reduce noise. - Developers remain free to format code however they prefer locally.
177 lines
6.0 KiB
C
177 lines
6.0 KiB
C
/* timezones.c
|
|
* Support for timezones in RainerScript.
|
|
*
|
|
* Copyright 2022 Attila Lakatos and Adiscon GmbH.
|
|
*
|
|
* This file is part of the rsyslog runtime library.
|
|
*
|
|
* 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
|
|
* -or-
|
|
* see COPYING.ASL20 in the source distribution
|
|
*
|
|
* 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 "config.h"
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <ctype.h>
|
|
#include <stdint.h>
|
|
#include <errno.h>
|
|
|
|
#include "rsyslog.h"
|
|
#include "unicode-helper.h"
|
|
#include "errmsg.h"
|
|
#include "parserif.h"
|
|
#include "rainerscript.h"
|
|
#include "srUtils.h"
|
|
#include "rsconf.h"
|
|
|
|
|
|
static struct cnfparamdescr timezonecnfparamdescr[] = {{"id", eCmdHdlrString, CNFPARAM_REQUIRED},
|
|
{"offset", eCmdHdlrGetWord, CNFPARAM_REQUIRED}};
|
|
static struct cnfparamblk timezonepblk = {
|
|
CNFPARAMBLK_VERSION, sizeof(timezonecnfparamdescr) / sizeof(struct cnfparamdescr), timezonecnfparamdescr};
|
|
|
|
/* Note: this function is NOT thread-safe!
|
|
* This is currently not needed as used only during
|
|
* initialization.
|
|
*/
|
|
static rsRetVal addTimezoneInfo(rsconf_t *cnf, uchar *tzid, char offsMode, int8_t offsHour, int8_t offsMin) {
|
|
DEFiRet;
|
|
tzinfo_t *newti;
|
|
CHKmalloc(newti = realloc(cnf->timezones.tzinfos, (cnf->timezones.ntzinfos + 1) * sizeof(tzinfo_t)));
|
|
if ((newti[cnf->timezones.ntzinfos].id = strdup((char *)tzid)) == NULL) {
|
|
free(newti);
|
|
DBGPRINTF("addTimezoneInfo: strdup failed with OOM\n");
|
|
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
|
|
}
|
|
newti[cnf->timezones.ntzinfos].offsMode = offsMode;
|
|
newti[cnf->timezones.ntzinfos].offsHour = offsHour;
|
|
newti[cnf->timezones.ntzinfos].offsMin = offsMin;
|
|
++cnf->timezones.ntzinfos, cnf->timezones.tzinfos = newti;
|
|
finalize_it:
|
|
RETiRet;
|
|
}
|
|
|
|
void glblProcessTimezone(struct cnfobj *o) {
|
|
struct cnfparamvals *pvals;
|
|
uchar *id = NULL;
|
|
uchar *offset = NULL;
|
|
char offsMode;
|
|
int8_t offsHour;
|
|
int8_t offsMin;
|
|
int i;
|
|
|
|
pvals = nvlstGetParams(o->nvlst, &timezonepblk, NULL);
|
|
if (pvals == NULL) {
|
|
LogError(0, RS_RET_MISSING_CNFPARAMS,
|
|
"error processing timezone "
|
|
"config parameters");
|
|
goto done;
|
|
}
|
|
if (Debug) {
|
|
dbgprintf("timezone param blk after glblProcessTimezone:\n");
|
|
cnfparamsPrint(&timezonepblk, pvals);
|
|
}
|
|
|
|
for (i = 0; i < timezonepblk.nParams; ++i) {
|
|
if (!pvals[i].bUsed) continue;
|
|
if (!strcmp(timezonepblk.descr[i].name, "id")) {
|
|
id = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
} else if (!strcmp(timezonepblk.descr[i].name, "offset")) {
|
|
offset = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
|
|
} else {
|
|
dbgprintf(
|
|
"glblProcessTimezone: program error, non-handled "
|
|
"param '%s'\n",
|
|
timezonepblk.descr[i].name);
|
|
}
|
|
}
|
|
|
|
/* note: the following two checks for NULL are not strictly necessary
|
|
* as these are required parameters for the config block. But we keep
|
|
* them to make the clang static analyzer happy, which also helps
|
|
* guard against logic errors.
|
|
*/
|
|
if (offset == NULL) {
|
|
parser_errmsg("offset parameter missing (logic error?), timezone config ignored");
|
|
goto done;
|
|
}
|
|
if (id == NULL) {
|
|
parser_errmsg("id parameter missing (logic error?), timezone config ignored");
|
|
goto done;
|
|
}
|
|
|
|
if (strlen((char *)offset) != 6 || !(offset[0] == '-' || offset[0] == '+') ||
|
|
!(isdigit(offset[1]) && isdigit(offset[2])) || offset[3] != ':' ||
|
|
!(isdigit(offset[4]) && isdigit(offset[5]))) {
|
|
parser_errmsg("timezone offset has invalid format. Must be +/-hh:mm, e.g. \"-07:00\".");
|
|
goto done;
|
|
}
|
|
|
|
offsHour = (offset[1] - '0') * 10 + offset[2] - '0';
|
|
offsMin = (offset[4] - '0') * 10 + offset[5] - '0';
|
|
offsMode = offset[0];
|
|
|
|
if (offsHour > 12 || offsMin > 59) {
|
|
parser_errmsg("timezone offset outside of supported range (hours 0..12, minutes 0..59)");
|
|
goto done;
|
|
}
|
|
|
|
addTimezoneInfo(loadConf, id, offsMode, offsHour, offsMin);
|
|
|
|
done:
|
|
cnfparamvalsDestruct(pvals, &timezonepblk);
|
|
free(id);
|
|
free(offset);
|
|
}
|
|
|
|
/* comparison function for qsort() and string array compare
|
|
* this is for the string lookup table type
|
|
*/
|
|
static int qs_arrcmp_tzinfo(const void *s1, const void *s2) {
|
|
return strcmp(((tzinfo_t *)s1)->id, ((tzinfo_t *)s2)->id);
|
|
}
|
|
|
|
void sortTimezones(rsconf_t *cnf) {
|
|
if (cnf->timezones.ntzinfos > 0) {
|
|
qsort(cnf->timezones.tzinfos, cnf->timezones.ntzinfos, sizeof(tzinfo_t), qs_arrcmp_tzinfo);
|
|
}
|
|
}
|
|
|
|
void displayTimezones(rsconf_t *cnf) {
|
|
if (!Debug) return;
|
|
for (int i = 0; i < cnf->timezones.ntzinfos; ++i)
|
|
dbgprintf("tzinfo: '%s':%c%2.2d:%2.2d\n", cnf->timezones.tzinfos[i].id, cnf->timezones.tzinfos[i].offsMode,
|
|
cnf->timezones.tzinfos[i].offsHour, cnf->timezones.tzinfos[i].offsMin);
|
|
}
|
|
|
|
static int bs_arrcmp_tzinfo(const void *s1, const void *s2) {
|
|
return strcmp((char *)s1, (char *)((tzinfo_t *)s2)->id);
|
|
}
|
|
|
|
/* returns matching timezone info or NULL if no entry exists */
|
|
tzinfo_t *glblFindTimezone(rsconf_t *cnf, char *id) {
|
|
return (tzinfo_t *)bsearch(id, cnf->timezones.tzinfos, cnf->timezones.ntzinfos, sizeof(tzinfo_t), bs_arrcmp_tzinfo);
|
|
}
|
|
|
|
static void freeTimezone(tzinfo_t *tzinfo) {
|
|
free(tzinfo->id);
|
|
}
|
|
|
|
void freeTimezones(rsconf_t *cnf) {
|
|
for (int i = 0; i < cnf->timezones.ntzinfos; ++i) freeTimezone(&cnf->timezones.tzinfos[i]);
|
|
if (cnf->timezones.ntzinfos > 0) free(cnf->timezones.tzinfos);
|
|
cnf->timezones.tzinfos = NULL;
|
|
}
|