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 "common.h"
21
22 #include "cfg.h"
23 #include "log.h"
24 #include "zbxgetopt.h"
25 #include "zbxembed.h"
26 #include "mutexs.h"
27
28 const char *progname;
29 const char title_message[] = "zabbix_js";
30 const char syslog_app_name[] = "zabbix_js";
31 const char *usage_message[] = {
32 "-s script-file", "-p input-param", "[-l log-level]", "[-t timeout]", NULL,
33 "-s script-file", "-i input-file", "[-l log-level]", "[-t timeout]", NULL,
34 "-h", NULL,
35 "-V", NULL,
36 NULL /* end of text */
37 };
38
39 unsigned char program_type;
40
41 const char *help_message[] = {
42 "Execute script using Zabbix embedded scripting engine.",
43 "",
44 "General options:",
45 " -s,--script script-file Specify the filename of script to execute. Specify - for",
46 " standard input.",
47 " -i,--input input-file Specify input parameter file name. Specify - for",
48 " standard input.",
49 " -p,--param input-param Specify input parameter",
50 " -l,--loglevel log-level Specify log level",
51 " -t,--timeout timeout Specify timeout in seconds",
52 " -h --help Display this help message",
53 " -V --version Display version number",
54 "",
55 "Example:",
56 " zabbix_js -s script-file.js -p example",
57 NULL /* end of text */
58 };
59
60
61 /* long options */
62 struct zbx_option longopts[] =
63 {
64 {"script", 1, NULL, 's'},
65 {"input", 1, NULL, 'i'},
66 {"param", 1, NULL, 'p'},
67 {"loglevel", 1, NULL, 'l'},
68 {"timeout", 1, NULL, 't'},
69 {"help", 0, NULL, 'h'},
70 {"version", 0, NULL, 'V'},
71 {NULL}
72 };
73
74 /* short options */
75 static char shortopts[] = "s:i:p:hVl:t";
76
77 /* end of COMMAND LINE OPTIONS */
78
79 unsigned int configured_tls_connect_mode;
80 unsigned int configured_tls_accept_modes; /* not used in zabbix_get, just for linking */
81 /* with tls.c */
82 char *CONFIG_TLS_CONNECT = NULL;
83 char *CONFIG_TLS_ACCEPT = NULL; /* not used in zabbix_js, just for linking with tls.c */
84 char *CONFIG_TLS_CA_FILE = NULL;
85 char *CONFIG_TLS_CRL_FILE = NULL;
86 char *CONFIG_TLS_SERVER_CERT_ISSUER = NULL;
87 char *CONFIG_TLS_SERVER_CERT_SUBJECT = NULL;
88 char *CONFIG_TLS_CERT_FILE = NULL;
89 char *CONFIG_TLS_KEY_FILE = NULL;
90 char *CONFIG_TLS_PSK_IDENTITY = NULL;
91 char *CONFIG_TLS_PSK_FILE = NULL;
92
93 /* CONFIG_TLS_CIPHER_* are not used in zabbix_js, defined for linking with tls.c */
94 char *CONFIG_TLS_CIPHER_CERT13 = NULL;
95 char *CONFIG_TLS_CIPHER_CERT = NULL;
96 char *CONFIG_TLS_CIPHER_PSK13 = NULL;
97 char *CONFIG_TLS_CIPHER_PSK = NULL;
98 char *CONFIG_TLS_CIPHER_ALL13 = NULL;
99 char *CONFIG_TLS_CIPHER_ALL = NULL;
100 char *CONFIG_TLS_CIPHER_CMD13 = NULL;
101 char *CONFIG_TLS_CIPHER_CMD = NULL;
102
103 int CONFIG_PASSIVE_FORKS = 0; /* not used in zabbix_js, just for linking with tls.c */
104 int CONFIG_ACTIVE_FORKS = 0; /* not used in zabbix_js, just for linking with tls.c */
105
106
107 char *CONFIG_SOURCE_IP = NULL;
108 char *CONFIG_SSL_CA_LOCATION = NULL;
109 char *CONFIG_SSL_CERT_LOCATION = NULL;
110 char *CONFIG_SSL_KEY_LOCATION = NULL;
111
read_file(const char * filename,char ** error)112 static char *read_file(const char *filename, char **error)
113 {
114 char buffer[4096];
115 int n, fd;
116 char *data = NULL;
117 size_t data_alloc = 0, data_offset = 0;
118
119 if (0 != strcmp(filename, "-"))
120 {
121 if (-1 == (fd = open(filename, O_RDONLY)))
122 {
123 *error = zbx_strdup(NULL, zbx_strerror(errno));
124 return NULL;
125 }
126 }
127 else
128 fd = STDIN_FILENO;
129
130 while (0 != (n = read(fd, buffer, sizeof(buffer))))
131 {
132 if (-1 == n)
133 {
134 if (fd != STDIN_FILENO)
135 close(fd);
136 zbx_free(data);
137 *error = zbx_strdup(NULL, zbx_strerror(errno));
138 return NULL;
139 }
140 zbx_strncpy_alloc(&data, &data_alloc, &data_offset, buffer, n);
141 }
142
143 if (fd != STDIN_FILENO)
144 close(fd);
145
146 return data;
147 }
148
main(int argc,char ** argv)149 int main(int argc, char **argv)
150 {
151 int ret = FAIL, loglevel = LOG_LEVEL_WARNING, timeout = 0;
152 char *script_file = NULL, *input_file = NULL, *param = NULL, ch, *script = NULL, *error = NULL,
153 *result = NULL, script_error[MAX_STRING_LEN];
154
155 progname = get_program_name(argv[0]);
156
157 /* parse the command-line */
158 while ((char)EOF != (ch = (char)zbx_getopt_long(argc, argv, shortopts, longopts, NULL)))
159 {
160 switch (ch)
161 {
162 case 's':
163 if (NULL == script_file)
164 script_file = zbx_strdup(NULL, zbx_optarg);
165 break;
166 case 'i':
167 if (NULL == input_file)
168 input_file = zbx_strdup(NULL, zbx_optarg);
169 break;
170 case 'p':
171 if (NULL == param)
172 param = zbx_strdup(NULL, zbx_optarg);
173 break;
174 case 'l':
175 loglevel = atoi(zbx_optarg);
176 break;
177 case 't':
178 timeout = atoi(zbx_optarg);
179 break;
180 case 'h':
181 help();
182 ret = SUCCEED;
183 goto clean;
184 case 'V':
185 version();
186 ret = SUCCEED;
187 goto clean;
188 default:
189 usage();
190 goto clean;
191 }
192 }
193
194 if (SUCCEED != zbx_locks_create(&error))
195 {
196 zbx_error("cannot create locks: %s", error);
197 goto clean;
198 }
199
200 if (SUCCEED != zabbix_open_log(LOG_TYPE_UNDEFINED, loglevel, NULL, &error))
201 {
202 zbx_error("cannot open log: %s", error);
203 goto clean;
204 }
205
206
207 if (NULL == script_file || (NULL == input_file && NULL == param))
208 {
209 usage();
210 goto close;
211 }
212
213 if (NULL != input_file && NULL != param)
214 {
215 zbx_error("input and script options are mutually exclusive");
216 goto close;
217 }
218
219 if (0 == strcmp(script_file, "-") && NULL != input_file && 0 == strcmp(input_file, "-"))
220 {
221 zbx_error("cannot read script and input parameters from standard input at the same time");
222 goto close;
223 }
224
225 if (NULL == (script = read_file(script_file, &error)))
226 {
227 if (NULL != error)
228 zbx_error("cannot read script file: %s", error);
229 else
230 zbx_error("cannot use empty script file");
231
232 goto close;
233 }
234
235 if (NULL != input_file)
236 {
237 if (NULL == (param = read_file(input_file, &error)))
238 {
239 if (NULL != error)
240 zbx_error("cannot read input file: %s", error);
241 else
242 zbx_error("cannot use empty input file");
243
244 goto close;
245 }
246 }
247
248 if (FAIL == zbx_es_execute_command(script, param, timeout, &result, script_error, sizeof(script_error), NULL))
249 {
250 zbx_error("error executing script:\n%s", script_error);
251 goto close;
252 }
253 ret = SUCCEED;
254 printf("\n%s\n", result);
255 close:
256 zabbix_close_log();
257 clean:
258 zbx_free(result);
259 zbx_free(error);
260 zbx_free(script);
261 zbx_free(script_file);
262 zbx_free(input_file);
263 zbx_free(param);
264
265 return SUCCEED == ret ? EXIT_SUCCESS : EXIT_FAILURE;
266 }
267