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 #include "zbxdiag.h"
22
parse_log_level_options(const char * opt,size_t len,unsigned int * scope,unsigned int * data)23 static int parse_log_level_options(const char *opt, size_t len, unsigned int *scope, unsigned int *data)
24 {
25 unsigned short num = 0;
26 const char *rtc_options;
27
28 rtc_options = opt + len;
29
30 if ('\0' == *rtc_options)
31 {
32 *scope = ZBX_RTC_LOG_SCOPE_FLAG | ZBX_RTC_LOG_SCOPE_PID;
33 *data = 0;
34 }
35 else if ('=' != *rtc_options)
36 {
37 zbx_error("invalid runtime control option: %s", opt);
38 return FAIL;
39 }
40 else if (0 != isdigit(*(++rtc_options)))
41 {
42 /* convert PID */
43 if (FAIL == is_ushort(rtc_options, &num) || 0 == num)
44 {
45 zbx_error("invalid log level control target: invalid or unsupported process identifier");
46 return FAIL;
47 }
48
49 *scope = ZBX_RTC_LOG_SCOPE_FLAG | ZBX_RTC_LOG_SCOPE_PID;
50 *data = num;
51 }
52 else
53 {
54 char *proc_name = NULL, *proc_num;
55 int proc_type;
56
57 if ('\0' == *rtc_options)
58 {
59 zbx_error("invalid log level control target: unspecified process identifier or type");
60 return FAIL;
61 }
62
63 proc_name = zbx_strdup(proc_name, rtc_options);
64
65 if (NULL != (proc_num = strchr(proc_name, ',')))
66 *proc_num++ = '\0';
67
68 if ('\0' == *proc_name)
69 {
70 zbx_error("invalid log level control target: unspecified process type");
71 zbx_free(proc_name);
72 return FAIL;
73 }
74
75 if (ZBX_PROCESS_TYPE_UNKNOWN == (proc_type = get_process_type_by_name(proc_name)))
76 {
77 zbx_error("invalid log level control target: unknown process type \"%s\"", proc_name);
78 zbx_free(proc_name);
79 return FAIL;
80 }
81
82 if (NULL != proc_num)
83 {
84 if ('\0' == *proc_num)
85 {
86 zbx_error("invalid log level control target: unspecified process number");
87 zbx_free(proc_name);
88 return FAIL;
89 }
90
91 /* convert Zabbix process number (e.g. "2" in "poller,2") */
92 if (FAIL == is_ushort(proc_num, &num) || 0 == num)
93 {
94 zbx_error("invalid log level control target: invalid or unsupported process number"
95 " \"%s\"", proc_num);
96 zbx_free(proc_name);
97 return FAIL;
98 }
99 }
100
101 zbx_free(proc_name);
102
103 *scope = ZBX_RTC_LOG_SCOPE_PROC | (unsigned int)proc_type;
104 *data = num;
105 }
106
107 return SUCCEED;
108 }
109
110 /******************************************************************************
111 * *
112 * Function: parse_rtc_options *
113 * *
114 * Purpose: parse runtime control options and create a runtime control *
115 * message *
116 * *
117 * Parameters: opt - [IN] the command line argument *
118 * program_type - [IN] the program type *
119 * message - [OUT] the message containing options for log *
120 * level change or cache reload *
121 * *
122 * Return value: SUCCEED - the message was created successfully *
123 * FAIL - an error occurred *
124 * *
125 ******************************************************************************/
parse_rtc_options(const char * opt,unsigned char program_type,int * message)126 int parse_rtc_options(const char *opt, unsigned char program_type, int *message)
127 {
128 unsigned int scope, data, command;
129
130 if (0 == strncmp(opt, ZBX_LOG_LEVEL_INCREASE, ZBX_CONST_STRLEN(ZBX_LOG_LEVEL_INCREASE)))
131 {
132 command = ZBX_RTC_LOG_LEVEL_INCREASE;
133
134 if (SUCCEED != parse_log_level_options(opt, ZBX_CONST_STRLEN(ZBX_LOG_LEVEL_INCREASE), &scope, &data))
135 return FAIL;
136 }
137 else if (0 == strncmp(opt, ZBX_LOG_LEVEL_DECREASE, ZBX_CONST_STRLEN(ZBX_LOG_LEVEL_DECREASE)))
138 {
139 command = ZBX_RTC_LOG_LEVEL_DECREASE;
140
141 if (SUCCEED != parse_log_level_options(opt, ZBX_CONST_STRLEN(ZBX_LOG_LEVEL_DECREASE), &scope, &data))
142 return FAIL;
143 }
144 else if (0 != (program_type & (ZBX_PROGRAM_TYPE_SERVER | ZBX_PROGRAM_TYPE_PROXY)) &&
145 0 == strcmp(opt, ZBX_CONFIG_CACHE_RELOAD))
146 {
147 command = ZBX_RTC_CONFIG_CACHE_RELOAD;
148 scope = 0;
149 data = 0;
150 }
151 else if (0 != (program_type & (ZBX_PROGRAM_TYPE_SERVER | ZBX_PROGRAM_TYPE_PROXY)) &&
152 0 == strcmp(opt, ZBX_HOUSEKEEPER_EXECUTE))
153 {
154 command = ZBX_RTC_HOUSEKEEPER_EXECUTE;
155 scope = 0;
156 data = 0;
157 }
158 else if (0 != (program_type & (ZBX_PROGRAM_TYPE_SERVER | ZBX_PROGRAM_TYPE_PROXY)) &&
159 0 == strcmp(opt, ZBX_SNMP_CACHE_RELOAD))
160 {
161 #ifdef HAVE_NETSNMP
162 command = ZBX_RTC_SNMP_CACHE_RELOAD;
163 /* Scope is ignored for SNMP. R/U pollers, trapper, discoverer and taskmanager always get targeted. */
164 scope = 0;
165 data = 0;
166 #else
167 zbx_error("invalid runtime control option: no SNMP support enabled");
168 return FAIL;
169 #endif
170 }
171 else if (0 != (program_type & (ZBX_PROGRAM_TYPE_SERVER | ZBX_PROGRAM_TYPE_PROXY)) &&
172 0 == strncmp(opt, ZBX_DIAGINFO, ZBX_CONST_STRLEN(ZBX_DIAGINFO)))
173 {
174 command = ZBX_RTC_DIAGINFO;
175 data = 0;
176 scope = ZBX_DIAGINFO_ALL;
177
178 if ('=' == opt[ZBX_CONST_STRLEN(ZBX_DIAGINFO)])
179 {
180 const char *section = opt + ZBX_CONST_STRLEN(ZBX_DIAGINFO) + 1;
181
182 if (0 == strcmp(section, ZBX_DIAG_HISTORYCACHE))
183 {
184 scope = ZBX_DIAGINFO_HISTORYCACHE;
185 }
186 else if (0 == strcmp(section, ZBX_DIAG_PREPROCESSING))
187 {
188 scope = ZBX_DIAGINFO_PREPROCESSING;
189 }
190 else if (0 == strcmp(section, ZBX_DIAG_LOCKS))
191 {
192 scope = ZBX_DIAGINFO_LOCKS;
193 }
194 else if (0 != (program_type & (ZBX_PROGRAM_TYPE_SERVER)))
195 {
196 if (0 == strcmp(section, ZBX_DIAG_VALUECACHE))
197 scope = ZBX_DIAGINFO_VALUECACHE;
198 else if (0 == strcmp(section, ZBX_DIAG_LLD))
199 scope = ZBX_DIAGINFO_LLD;
200 else if (0 == strcmp(section, ZBX_DIAG_ALERTING))
201 scope = ZBX_DIAGINFO_ALERTING;
202 }
203
204 if (0 == scope)
205 {
206 zbx_error("invalid diaginfo section: %s", section);
207 return FAIL;
208 }
209 }
210 else if ('\0' != opt[ZBX_CONST_STRLEN(ZBX_DIAGINFO)])
211 {
212 zbx_error("invalid runtime control option: %s", opt);
213 return FAIL;
214 }
215 }
216 else
217 {
218 zbx_error("invalid runtime control option: %s", opt);
219 return FAIL;
220 }
221
222 *message = (int)ZBX_RTC_MAKE_MESSAGE(command, scope, data);
223
224 return SUCCEED;
225 }
226