/* ** Zabbix ** Copyright (C) 2001-2023 Zabbix SIA ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** 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 General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ #include "rtc.h" #include "zbxnum.h" #include "zbxprof.h" static int rtc_parse_scope(const char *str, int *scope) { if (NULL == scope) return FAIL; if (0 == strcmp(str, "rwlock")) *scope = ZBX_PROF_RWLOCK; else if (0 == strcmp(str, "mutex")) *scope = ZBX_PROF_MUTEX; else if (0 == strcmp(str, "processing")) *scope = ZBX_PROF_PROCESSING; else return FAIL; return SUCCEED; } /****************************************************************************** * * * Purpose: parse runtime control option * * * * Parameters: opt - [IN] runtime control option * * len - [IN] runtime control option length without * * parameter * * pid - [OUT] target pid (if specified) * * proc_type - [OUT] target process type (if specified) * * proc_num - [OUT] target process num (if specified) * * scope - [OUT] scope (if specified) * * error - [OUT] error message * * * * Return value: SUCCEED - runtime control option was processed * * FAIL - otherwise * * * ******************************************************************************/ int zbx_rtc_parse_option(const char *opt, size_t len, pid_t *pid, int *proc_type, int *proc_num, int *scope, char **error) { const char *rtc_options; rtc_options = opt + len; if ('\0' == *rtc_options) return SUCCEED; if ('=' != *rtc_options) { *error = zbx_dsprintf(NULL, "invalid runtime control option \"%s\"", opt); return FAIL; } else if (0 != isdigit(*(++rtc_options))) { char *scope_ptr; if (NULL != (scope_ptr = strchr(rtc_options, ','))) *scope_ptr++ = '\0'; /* convert PID */ if (FAIL == zbx_is_uint32(rtc_options, pid) || 0 == *pid) { *error = zbx_dsprintf(NULL, "invalid control target - invalid or unsupported process" " identifier"); return FAIL; } if (NULL != scope_ptr) { if (FAIL == rtc_parse_scope(scope_ptr, scope)) { *error = zbx_dsprintf(NULL, "invalid control target -" " invalid or unsupported scope \"%s\"", scope_ptr); return FAIL; } } } else if (FAIL == rtc_parse_scope(rtc_options, scope)) { char proc_name[MAX_STRING_LEN], *proc_num_ptr; if ('\0' == *rtc_options) { *error = zbx_dsprintf(NULL, "invalid control target - unspecified process identifier or type"); return FAIL; } zbx_strlcpy(proc_name, rtc_options, sizeof(proc_name)); if (NULL != (proc_num_ptr = strchr(proc_name, ','))) *proc_num_ptr++ = '\0'; if ('\0' == *proc_name) { *error = zbx_dsprintf(NULL, "invalid control target - unspecified process type"); return FAIL; } if (ZBX_PROCESS_TYPE_UNKNOWN == (*proc_type = get_process_type_by_name(proc_name))) { *error = zbx_dsprintf(NULL, "invalid control target - unknown process type \"%s\"", proc_name); return FAIL; } if (NULL != proc_num_ptr) { if ('\0' == *proc_num_ptr) { *error = zbx_dsprintf(NULL, "invalid control target - unspecified process number"); return FAIL; } if (FAIL == rtc_parse_scope(proc_num_ptr, scope)) { char *scope_ptr; if (NULL != (scope_ptr = strchr(proc_num_ptr, ','))) *scope_ptr++ = '\0'; if (FAIL == zbx_is_uint32(proc_num_ptr, proc_num) || 0 == *proc_num) { /* convert Zabbix process number (e.g. "2" in "poller,2") */ *error = zbx_dsprintf(NULL, "invalid control target -" " invalid or unsupported process number \"%s\"", proc_num_ptr); return FAIL; } if (NULL != scope_ptr) { if (FAIL == rtc_parse_scope(scope_ptr, scope)) { *error = zbx_dsprintf(NULL, "invalid control target" " invalid or unsupported scope \"%s\"", scope_ptr); return FAIL; } } } } } return SUCCEED; }