/* ** Copyright (C) 2001-2025 Zabbix SIA ** ** This program is free software: you can redistribute it and/or modify it under the terms of ** the GNU Affero General Public License as published by the Free Software Foundation, version 3. ** ** This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; ** without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU Affero General Public License for more details. ** ** You should have received a copy of the GNU Affero General Public License along with this program. ** If not, see <https://www.gnu.org/licenses/>. **/ #include "control.h" #include "zbxnix.h" #include "zbxnum.h" #include "zbx_rtc_constants.h" static int parse_log_level_options(const char *opt, size_t len, unsigned int *scope, unsigned int *data) { unsigned short num = 0; const char *rtc_options; rtc_options = opt + len; if ('\0' == *rtc_options) { *scope = ZBX_RTC_LOG_SCOPE_FLAG | ZBX_RTC_LOG_SCOPE_PID; *data = 0; } else if ('=' != *rtc_options) { zbx_error("invalid runtime control option: %s", opt); return FAIL; } else if (0 != isdigit(*(++rtc_options))) { /* convert PID */ if (FAIL == zbx_is_ushort(rtc_options, &num) || 0 == num) { zbx_error("invalid log level control target: invalid or unsupported process identifier"); return FAIL; } *scope = ZBX_RTC_LOG_SCOPE_FLAG | ZBX_RTC_LOG_SCOPE_PID; *data = num; } else { char *proc_name = NULL, *proc_num; int proc_type; if ('\0' == *rtc_options) { zbx_error("invalid log level control target: unspecified process identifier or type"); return FAIL; } proc_name = zbx_strdup(proc_name, rtc_options); if (NULL != (proc_num = strchr(proc_name, ','))) *proc_num++ = '\0'; if ('\0' == *proc_name) { zbx_error("invalid log level control target: unspecified process type"); zbx_free(proc_name); return FAIL; } if (ZBX_PROCESS_TYPE_UNKNOWN == (proc_type = get_process_type_by_name(proc_name))) { zbx_error("invalid log level control target: unknown process type \"%s\"", proc_name); zbx_free(proc_name); return FAIL; } if (NULL != proc_num) { if ('\0' == *proc_num) { zbx_error("invalid log level control target: unspecified process number"); zbx_free(proc_name); return FAIL; } /* convert Zabbix process number (e.g. "2" in "poller,2") */ if (FAIL == zbx_is_ushort(proc_num, &num) || 0 == num) { zbx_error("invalid log level control target: invalid or unsupported process number" " \"%s\"", proc_num); zbx_free(proc_name); return FAIL; } } zbx_free(proc_name); *scope = ZBX_RTC_LOG_SCOPE_PROC | (unsigned int)proc_type; *data = num; } return SUCCEED; } /****************************************************************************** * * * Purpose: parse runtime control options and create a runtime control * * message * * * * Parameters: opt - [IN] the command line argument * * message - [OUT] the message containing options for log * * level change or cache reload * * * * Return value: SUCCEED - the message was created successfully * * FAIL - an error occurred * * * ******************************************************************************/ int zbx_parse_rtc_options(const char *opt, int *message) { unsigned int scope, data, command; if (0 == strncmp(opt, ZBX_LOG_LEVEL_INCREASE, ZBX_CONST_STRLEN(ZBX_LOG_LEVEL_INCREASE))) { command = ZBX_RTC_LOG_LEVEL_INCREASE; if (SUCCEED != parse_log_level_options(opt, ZBX_CONST_STRLEN(ZBX_LOG_LEVEL_INCREASE), &scope, &data)) return FAIL; } else if (0 == strncmp(opt, ZBX_LOG_LEVEL_DECREASE, ZBX_CONST_STRLEN(ZBX_LOG_LEVEL_DECREASE))) { command = ZBX_RTC_LOG_LEVEL_DECREASE; if (SUCCEED != parse_log_level_options(opt, ZBX_CONST_STRLEN(ZBX_LOG_LEVEL_DECREASE), &scope, &data)) return FAIL; } else if (0 == strcmp(opt, ZBX_USER_PARAMETERS_RELOAD)) { command = ZBX_RTC_USER_PARAMETERS_RELOAD; scope = 0; data = 0; } else { zbx_error("invalid runtime control option: %s", opt); return FAIL; } *message = (int)ZBX_RTC_MAKE_MESSAGE(command, scope, data); return SUCCEED; }