1 /*
2 ** Zabbix
3 ** Copyright (C) 2001-2021 Zabbix SIA
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 **/
19 
20 #include "control.h"
21 
parse_log_level_options(const char * opt,size_t len,unsigned int * scope,unsigned int * data)22 static int	parse_log_level_options(const char *opt, size_t len, unsigned int *scope, unsigned int *data)
23 {
24 	unsigned short	num = 0;
25 	const char	*rtc_options;
26 
27 	rtc_options = opt + len;
28 
29 	if ('\0' == *rtc_options)
30 	{
31 		*scope = ZBX_RTC_LOG_SCOPE_FLAG | ZBX_RTC_LOG_SCOPE_PID;
32 		*data = 0;
33 	}
34 	else if ('=' != *rtc_options)
35 	{
36 		zbx_error("invalid runtime control option: %s", opt);
37 		return FAIL;
38 	}
39 	else if (0 != isdigit(*(++rtc_options)))
40 	{
41 		/* convert PID */
42 		if (FAIL == is_ushort(rtc_options, &num) || 0 == num)
43 		{
44 			zbx_error("invalid log level control target: invalid or unsupported process identifier");
45 			return FAIL;
46 		}
47 
48 		*scope = ZBX_RTC_LOG_SCOPE_FLAG | ZBX_RTC_LOG_SCOPE_PID;
49 		*data = num;
50 	}
51 	else
52 	{
53 		char	*proc_name = NULL, *proc_num;
54 		int	proc_type;
55 
56 		if ('\0' == *rtc_options)
57 		{
58 			zbx_error("invalid log level control target: unspecified process identifier or type");
59 			return FAIL;
60 		}
61 
62 		proc_name = zbx_strdup(proc_name, rtc_options);
63 
64 		if (NULL != (proc_num = strchr(proc_name, ',')))
65 			*proc_num++ = '\0';
66 
67 		if ('\0' == *proc_name)
68 		{
69 			zbx_error("invalid log level control target: unspecified process type");
70 			zbx_free(proc_name);
71 			return FAIL;
72 		}
73 
74 		if (ZBX_PROCESS_TYPE_UNKNOWN == (proc_type = get_process_type_by_name(proc_name)))
75 		{
76 			zbx_error("invalid log level control target: unknown process type \"%s\"", proc_name);
77 			zbx_free(proc_name);
78 			return FAIL;
79 		}
80 
81 		if (NULL != proc_num)
82 		{
83 			if ('\0' == *proc_num)
84 			{
85 				zbx_error("invalid log level control target: unspecified process number");
86 				zbx_free(proc_name);
87 				return FAIL;
88 			}
89 
90 			/* convert Zabbix process number (e.g. "2" in "poller,2") */
91 			if (FAIL == is_ushort(proc_num, &num) || 0 == num)
92 			{
93 				zbx_error("invalid log level control target: invalid or unsupported process number"
94 						" \"%s\"", proc_num);
95 				zbx_free(proc_name);
96 				return FAIL;
97 			}
98 		}
99 
100 		zbx_free(proc_name);
101 
102 		*scope = ZBX_RTC_LOG_SCOPE_PROC | (unsigned int)proc_type;
103 		*data = num;
104 	}
105 
106 	return SUCCEED;
107 }
108 
109 /******************************************************************************
110  *                                                                            *
111  * Function: parse_rtc_options                                                *
112  *                                                                            *
113  * Purpose: parse runtime control options and create a runtime control        *
114  *          message                                                           *
115  *                                                                            *
116  * Parameters: opt          - [IN] the command line argument                  *
117  *             program_type - [IN] the program type                           *
118  *             message      - [OUT] the message containing options for log    *
119  *                                  level change or cache reload              *
120  *                                                                            *
121  * Return value: SUCCEED - the message was created successfully               *
122  *               FAIL    - an error occurred                                  *
123  *                                                                            *
124  ******************************************************************************/
parse_rtc_options(const char * opt,unsigned char program_type,int * message)125 int	parse_rtc_options(const char *opt, unsigned char program_type, int *message)
126 {
127 	unsigned int	scope, data, command;
128 
129 	if (0 == strncmp(opt, ZBX_LOG_LEVEL_INCREASE, ZBX_CONST_STRLEN(ZBX_LOG_LEVEL_INCREASE)))
130 	{
131 		command = ZBX_RTC_LOG_LEVEL_INCREASE;
132 
133 		if (SUCCEED != parse_log_level_options(opt, ZBX_CONST_STRLEN(ZBX_LOG_LEVEL_INCREASE), &scope, &data))
134 			return FAIL;
135 	}
136 	else if (0 == strncmp(opt, ZBX_LOG_LEVEL_DECREASE, ZBX_CONST_STRLEN(ZBX_LOG_LEVEL_DECREASE)))
137 	{
138 		command = ZBX_RTC_LOG_LEVEL_DECREASE;
139 
140 		if (SUCCEED != parse_log_level_options(opt, ZBX_CONST_STRLEN(ZBX_LOG_LEVEL_DECREASE), &scope, &data))
141 			return FAIL;
142 	}
143 	else if (0 != (program_type & (ZBX_PROGRAM_TYPE_SERVER | ZBX_PROGRAM_TYPE_PROXY)) &&
144 			0 == strcmp(opt, ZBX_CONFIG_CACHE_RELOAD))
145 	{
146 		command = ZBX_RTC_CONFIG_CACHE_RELOAD;
147 		scope = 0;
148 		data = 0;
149 	}
150 	else if (0 != (program_type & (ZBX_PROGRAM_TYPE_SERVER | ZBX_PROGRAM_TYPE_PROXY)) &&
151 			0 == strcmp(opt, ZBX_HOUSEKEEPER_EXECUTE))
152 	{
153 		command = ZBX_RTC_HOUSEKEEPER_EXECUTE;
154 		scope = 0;
155 		data = 0;
156 	}
157 	else
158 	{
159 		zbx_error("invalid runtime control option: %s", opt);
160 		return FAIL;
161 	}
162 
163 	*message = (int)ZBX_RTC_MAKE_MESSAGE(command, scope, data);
164 
165 	return SUCCEED;
166 }
167