File: | src/switch_console.c |
Location: | line 539, column 4 |
Description: | Potential leak of memory pointed to by '__retval' |
1 | /* | |||||||||
2 | * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application | |||||||||
3 | * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org> | |||||||||
4 | * | |||||||||
5 | * Version: MPL 1.1 | |||||||||
6 | * | |||||||||
7 | * The contents of this file are subject to the Mozilla Public License Version | |||||||||
8 | * 1.1 (the "License"); you may not use this file except in compliance with | |||||||||
9 | * the License. You may obtain a copy of the License at | |||||||||
10 | * http://www.mozilla.org/MPL/ | |||||||||
11 | * | |||||||||
12 | * Software distributed under the License is distributed on an "AS IS" basis, | |||||||||
13 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |||||||||
14 | * for the specific language governing rights and limitations under the | |||||||||
15 | * License. | |||||||||
16 | * | |||||||||
17 | * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application | |||||||||
18 | * | |||||||||
19 | * The Initial Developer of the Original Code is | |||||||||
20 | * Anthony Minessale II <anthm@freeswitch.org> | |||||||||
21 | * Portions created by the Initial Developer are Copyright (C) | |||||||||
22 | * the Initial Developer. All Rights Reserved. | |||||||||
23 | * | |||||||||
24 | * Contributor(s): | |||||||||
25 | * | |||||||||
26 | * Anthony Minessale II <anthm@freeswitch.org> | |||||||||
27 | * | |||||||||
28 | * | |||||||||
29 | * switch_console.c -- Simple Console | |||||||||
30 | * | |||||||||
31 | */ | |||||||||
32 | ||||||||||
33 | #include <switch.h> | |||||||||
34 | #include <switch_console.h> | |||||||||
35 | #ifndef _MSC_VER | |||||||||
36 | #include <switch_private.h> | |||||||||
37 | #endif | |||||||||
38 | #define CMD_BUFLEN1024 1024 | |||||||||
39 | ||||||||||
40 | #ifdef HAVE_LIBEDIT1 | |||||||||
41 | #include <histedit.h> | |||||||||
42 | ||||||||||
43 | static EditLine *el; | |||||||||
44 | static History *myhistory; | |||||||||
45 | static HistEvent ev; | |||||||||
46 | static char *hfile = NULL((void*)0); | |||||||||
47 | ||||||||||
48 | #else | |||||||||
49 | ||||||||||
50 | #define CC_NORM0 0 | |||||||||
51 | #define CC_NEWLINE1 1 | |||||||||
52 | #define CC_EOF2 2 | |||||||||
53 | #define CC_ARGHACK3 3 | |||||||||
54 | #define CC_REFRESH4 4 | |||||||||
55 | #define CC_CURSOR5 5 | |||||||||
56 | #define CC_ERROR6 6 | |||||||||
57 | #define CC_FATAL7 7 | |||||||||
58 | #define CC_REDISPLAY8 8 | |||||||||
59 | #define CC_REFRESH_BEEP9 9 | |||||||||
60 | ||||||||||
61 | #ifdef _MSC_VER | |||||||||
62 | #define HISTLEN 10 | |||||||||
63 | #define KEY_UP 1 | |||||||||
64 | #define KEY_DOWN 2 | |||||||||
65 | #define KEY_TAB 3 | |||||||||
66 | #define CLEAR_OP 4 | |||||||||
67 | #define DELETE_REFRESH_OP 5 | |||||||||
68 | #define KEY_LEFT 6 | |||||||||
69 | #define KEY_RIGHT 7 | |||||||||
70 | #define KEY_INSERT 8 | |||||||||
71 | #define PROMPT_OP 9 | |||||||||
72 | #define KEY_DELETE 10 | |||||||||
73 | ||||||||||
74 | static int console_bufferInput(char *buf, int len, char *cmd, int key); | |||||||||
75 | #endif | |||||||||
76 | #endif | |||||||||
77 | ||||||||||
78 | /* | |||||||||
79 | * store a strdup() of the string configured in XML | |||||||||
80 | * bound to each of the 12 function key | |||||||||
81 | */ | |||||||||
82 | static char *console_fnkeys[12]; | |||||||||
83 | ||||||||||
84 | /* | |||||||||
85 | * Load from console.conf XML file the section: | |||||||||
86 | * <keybindings> | |||||||||
87 | * <key name="1" value="show calls"/> | |||||||||
88 | * </keybindings> | |||||||||
89 | */ | |||||||||
90 | static switch_status_t console_xml_config(void) | |||||||||
91 | { | |||||||||
92 | char *cf = "switch.conf"; | |||||||||
93 | switch_xml_t cfg, xml, settings, param; | |||||||||
94 | ||||||||||
95 | /* clear the keybind array */ | |||||||||
96 | int i; | |||||||||
97 | ||||||||||
98 | for (i = 0; i < 12; i++) { | |||||||||
99 | console_fnkeys[i] = NULL((void*)0); | |||||||||
100 | } | |||||||||
101 | ||||||||||
102 | if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL((void*)0)))) { | |||||||||
103 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 103, ((void*)0), SWITCH_LOG_ERROR, "Open of %s failed\n", cf); | |||||||||
104 | return SWITCH_STATUS_TERM; | |||||||||
105 | } | |||||||||
106 | ||||||||||
107 | if ((settings = switch_xml_child(cfg, "cli-keybindings"))) { | |||||||||
108 | for (param = switch_xml_child(settings, "key"); param; param = param->next) { | |||||||||
109 | char *var = (char *) switch_xml_attr_soft(param, "name"); | |||||||||
110 | char *val = (char *) switch_xml_attr_soft(param, "value"); | |||||||||
111 | i = atoi(var); | |||||||||
112 | if ((i < 1) || (i > 12)) { | |||||||||
113 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 113, ((void*)0), SWITCH_LOG_ERROR, "Keybind %s is invalid, range is from 1 to 12\n", var); | |||||||||
114 | } else { | |||||||||
115 | /* Add the command to the fnkey array */ | |||||||||
116 | console_fnkeys[i - 1] = switch_core_permanent_strdup(val)switch_core_perform_permanent_strdup(val, "src/switch_console.c" , (const char *)__func__, 116); | |||||||||
117 | } | |||||||||
118 | } | |||||||||
119 | } | |||||||||
120 | ||||||||||
121 | switch_xml_free(xml); | |||||||||
122 | ||||||||||
123 | return SWITCH_STATUS_SUCCESS; | |||||||||
124 | } | |||||||||
125 | ||||||||||
126 | SWITCH_DECLARE_NONSTD(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_console_stream_raw_write(switch_stream_handle_t *handle, uint8_t *data, switch_size_t datalen) | |||||||||
127 | { | |||||||||
128 | switch_size_t need = handle->data_len + datalen; | |||||||||
129 | ||||||||||
130 | if (need >= handle->data_size) { | |||||||||
131 | void *new_data; | |||||||||
132 | need += handle->alloc_chunk; | |||||||||
133 | ||||||||||
134 | if (!(new_data = realloc(handle->data, need))) { | |||||||||
135 | return SWITCH_STATUS_MEMERR; | |||||||||
136 | } | |||||||||
137 | ||||||||||
138 | handle->data = new_data; | |||||||||
139 | handle->data_size = need; | |||||||||
140 | } | |||||||||
141 | ||||||||||
142 | memcpy((uint8_t *) (handle->data) + handle->data_len, data, datalen); | |||||||||
143 | handle->data_len += datalen; | |||||||||
144 | handle->end = (uint8_t *) (handle->data) + handle->data_len; | |||||||||
145 | *(uint8_t *) handle->end = '\0'; | |||||||||
146 | ||||||||||
147 | return SWITCH_STATUS_SUCCESS; | |||||||||
148 | } | |||||||||
149 | ||||||||||
150 | SWITCH_DECLARE_NONSTD(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_console_stream_write(switch_stream_handle_t *handle, const char *fmt, ...) | |||||||||
151 | { | |||||||||
152 | va_list ap; | |||||||||
153 | char *buf = handle->data; | |||||||||
154 | char *end = handle->end; | |||||||||
155 | int ret = 0; | |||||||||
156 | char *data = NULL((void*)0); | |||||||||
157 | ||||||||||
158 | if (handle->data_len >= handle->data_size) { | |||||||||
159 | return SWITCH_STATUS_FALSE; | |||||||||
160 | } | |||||||||
161 | ||||||||||
162 | va_start(ap, fmt)__builtin_va_start(ap, fmt); | |||||||||
163 | //ret = switch_vasprintf(&data, fmt, ap); | |||||||||
164 | if (!(data = switch_vmprintf(fmt, ap))) { | |||||||||
165 | ret = -1; | |||||||||
166 | } | |||||||||
167 | va_end(ap)__builtin_va_end(ap); | |||||||||
168 | ||||||||||
169 | if (data) { | |||||||||
170 | switch_size_t remaining = handle->data_size - handle->data_len; | |||||||||
171 | switch_size_t need = strlen(data) + 1; | |||||||||
172 | ||||||||||
173 | if ((remaining < need) && handle->alloc_len) { | |||||||||
174 | switch_size_t new_len; | |||||||||
175 | void *new_data; | |||||||||
176 | ||||||||||
177 | new_len = handle->data_size + need + handle->alloc_chunk; | |||||||||
178 | if ((new_data = realloc(handle->data, new_len))) { | |||||||||
179 | handle->data_size = handle->alloc_len = new_len; | |||||||||
180 | handle->data = new_data; | |||||||||
181 | buf = handle->data; | |||||||||
182 | remaining = handle->data_size - handle->data_len; | |||||||||
183 | handle->end = (uint8_t *) (handle->data) + handle->data_len; | |||||||||
184 | end = handle->end; | |||||||||
185 | } else { | |||||||||
186 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 186, ((void*)0), SWITCH_LOG_CRIT, "Memory Error!\n"); | |||||||||
187 | free(data); | |||||||||
188 | return SWITCH_STATUS_FALSE; | |||||||||
189 | } | |||||||||
190 | } | |||||||||
191 | ||||||||||
192 | if (remaining < need) { | |||||||||
193 | ret = -1; | |||||||||
194 | } else { | |||||||||
195 | ret = 0; | |||||||||
196 | switch_snprintf(end, remaining, "%s", data); | |||||||||
197 | handle->data_len = strlen(buf); | |||||||||
198 | handle->end = (uint8_t *) (handle->data) + handle->data_len; | |||||||||
199 | } | |||||||||
200 | free(data); | |||||||||
201 | } | |||||||||
202 | ||||||||||
203 | return ret ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS; | |||||||||
204 | } | |||||||||
205 | ||||||||||
206 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_stream_write_file_contents(switch_stream_handle_t *stream, const char *path) | |||||||||
207 | { | |||||||||
208 | char *dpath = NULL((void*)0); | |||||||||
209 | FILE *fd = NULL((void*)0); | |||||||||
210 | switch_status_t status = SWITCH_STATUS_FALSE; | |||||||||
211 | ||||||||||
212 | if (!switch_is_file_path(path)) { | |||||||||
213 | dpath = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.conf_dir, SWITCH_PATH_SEPARATOR"/", path); | |||||||||
214 | path = dpath; | |||||||||
215 | } | |||||||||
216 | ||||||||||
217 | if ((fd = fopen(path, "r"))) { | |||||||||
218 | char *line_buf = NULL((void*)0); | |||||||||
219 | switch_size_t llen = 0; | |||||||||
220 | ||||||||||
221 | while (switch_fp_read_dline(fd, &line_buf, &llen)) { | |||||||||
222 | stream->write_function(stream, "%s", line_buf); | |||||||||
223 | } | |||||||||
224 | fclose(fd); | |||||||||
225 | switch_safe_free(line_buf)if (line_buf) {free(line_buf);line_buf=((void*)0);}; | |||||||||
226 | status = SWITCH_STATUS_SUCCESS; | |||||||||
227 | } | |||||||||
228 | ||||||||||
229 | switch_safe_free(dpath)if (dpath) {free(dpath);dpath=((void*)0);}; | |||||||||
230 | return status; | |||||||||
231 | } | |||||||||
232 | ||||||||||
233 | static int alias_callback(void *pArg, int argc, char **argv, char **columnNames) | |||||||||
234 | { | |||||||||
235 | char **r = (char **) pArg; | |||||||||
236 | *r = strdup(argv[0])(__extension__ (__builtin_constant_p (argv[0]) && ((size_t )(const void *)((argv[0]) + 1) - (size_t)(const void *)(argv[ 0]) == 1) ? (((const char *) (argv[0]))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ( argv[0]) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, argv[0] , __len); __retval; })) : __strdup (argv[0]))); | |||||||||
237 | return -1; | |||||||||
238 | } | |||||||||
239 | ||||||||||
240 | SWITCH_DECLARE(char *)__attribute__((visibility("default"))) char * switch_console_expand_alias(char *cmd, char *arg) | |||||||||
241 | { | |||||||||
242 | char *errmsg = NULL((void*)0); | |||||||||
243 | char *r = NULL((void*)0); | |||||||||
244 | char *sql = NULL((void*)0); | |||||||||
245 | char *exp = NULL((void*)0); | |||||||||
246 | switch_cache_db_handle_t *db = NULL((void*)0); | |||||||||
247 | switch_core_flag_t cflags = switch_core_flags(); | |||||||||
248 | int full = 0; | |||||||||
249 | ||||||||||
250 | ||||||||||
251 | if (!(cflags & SCF_USE_SQL)) { | |||||||||
252 | return NULL((void*)0); | |||||||||
253 | } | |||||||||
254 | ||||||||||
255 | if (switch_core_db_handle(&db)_switch_core_db_handle(&db, "src/switch_console.c", (const char *)__func__, 255) != SWITCH_STATUS_SUCCESS) { | |||||||||
256 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 256, ((void*)0), SWITCH_LOG_ERROR, "Database Error\n"); | |||||||||
257 | return NULL((void*)0); | |||||||||
258 | } | |||||||||
259 | ||||||||||
260 | ||||||||||
261 | if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) { | |||||||||
262 | sql = switch_mprintf("select command from aliases where alias='%q'", cmd); | |||||||||
263 | } else { | |||||||||
264 | sql = switch_mprintf("select command from aliases where alias='%w'", cmd); | |||||||||
265 | } | |||||||||
266 | ||||||||||
267 | switch_cache_db_execute_sql_callback(db, sql, alias_callback, &r, &errmsg); | |||||||||
268 | ||||||||||
269 | if (errmsg) { | |||||||||
270 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 270, ((void*)0), SWITCH_LOG_ERROR, "error [%s][%s]\n", sql, errmsg); | |||||||||
271 | free(errmsg); | |||||||||
272 | } | |||||||||
273 | ||||||||||
274 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||||||||
275 | ||||||||||
276 | if (!r) { | |||||||||
277 | if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) { | |||||||||
278 | sql = switch_mprintf("select command from aliases where alias='%q %q'", cmd, arg); | |||||||||
279 | } else { | |||||||||
280 | sql = switch_mprintf("select command from aliases where alias='%w %w'", cmd, arg); | |||||||||
281 | } | |||||||||
282 | ||||||||||
283 | switch_cache_db_execute_sql_callback(db, sql, alias_callback, &r, &errmsg); | |||||||||
284 | ||||||||||
285 | if (errmsg) { | |||||||||
286 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 286, ((void*)0), SWITCH_LOG_ERROR, "error [%s][%s]\n", sql, errmsg); | |||||||||
287 | free(errmsg); | |||||||||
288 | } | |||||||||
289 | if (r) { | |||||||||
290 | full++; | |||||||||
291 | } | |||||||||
292 | } | |||||||||
293 | ||||||||||
294 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||||||||
295 | ||||||||||
296 | if (r) { | |||||||||
297 | if (arg && !full) { | |||||||||
298 | exp = switch_mprintf("%s %s", r, arg); | |||||||||
299 | free(r); | |||||||||
300 | } else { | |||||||||
301 | exp = r; | |||||||||
302 | } | |||||||||
303 | } else { | |||||||||
304 | exp = cmd; | |||||||||
305 | } | |||||||||
306 | ||||||||||
307 | switch_cache_db_release_db_handle(&db); | |||||||||
308 | ||||||||||
309 | return exp; | |||||||||
310 | } | |||||||||
311 | ||||||||||
312 | ||||||||||
313 | static int switch_console_process(char *xcmd) | |||||||||
314 | { | |||||||||
315 | switch_stream_handle_t stream = { 0 }; | |||||||||
316 | switch_status_t status; | |||||||||
317 | FILE *handle = switch_core_get_console(); | |||||||||
318 | int r = 1; | |||||||||
319 | ||||||||||
320 | SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc( 1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data" , "src/switch_console.c", 320, __PRETTY_FUNCTION__)); memset( stream.data, 0, 1024); stream.end = stream.data; stream.data_size = 1024; stream.write_function = switch_console_stream_write; stream.raw_write_function = switch_console_stream_raw_write; stream.alloc_len = 1024; stream.alloc_chunk = 1024; | |||||||||
321 | switch_assert(stream.data)((stream.data) ? (void) (0) : __assert_fail ("stream.data", "src/switch_console.c" , 321, __PRETTY_FUNCTION__)); | |||||||||
322 | ||||||||||
323 | status = switch_console_execute(xcmd, 0, &stream); | |||||||||
324 | ||||||||||
325 | if (status == SWITCH_STATUS_SUCCESS) { | |||||||||
326 | if (handle) { | |||||||||
327 | fprintf(handle, "\n%s\n", (char *) stream.data); | |||||||||
328 | fflush(handle); | |||||||||
329 | } | |||||||||
330 | } else { | |||||||||
331 | if (!strcasecmp(xcmd, "...") || !strcasecmp(xcmd, "shutdown")) { | |||||||||
332 | r = 0; | |||||||||
333 | } | |||||||||
334 | if (handle) { | |||||||||
335 | fprintf(handle, "Unknown Command: %s\n", xcmd); | |||||||||
336 | fflush(handle); | |||||||||
337 | } | |||||||||
338 | } | |||||||||
339 | ||||||||||
340 | switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);}; | |||||||||
341 | ||||||||||
342 | return r; | |||||||||
343 | ||||||||||
344 | } | |||||||||
345 | ||||||||||
346 | ||||||||||
347 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_console_execute(char *xcmd, int rec, switch_stream_handle_t *istream) | |||||||||
348 | { | |||||||||
349 | char *arg = NULL((void*)0), *alias = NULL((void*)0); | |||||||||
350 | ||||||||||
351 | char *delim = ";;"; | |||||||||
352 | int argc; | |||||||||
353 | char *argv[128]; | |||||||||
354 | int x; | |||||||||
355 | char *dup = strdup(xcmd)(__extension__ (__builtin_constant_p (xcmd) && ((size_t )(const void *)((xcmd) + 1) - (size_t)(const void *)(xcmd) == 1) ? (((const char *) (xcmd))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen (xcmd) + 1 ; char *__retval = (char *) malloc (__len); if (__retval != ( (void*)0)) __retval = (char *) memcpy (__retval, xcmd, __len) ; __retval; })) : __strdup (xcmd))); | |||||||||
356 | char *cmd; | |||||||||
357 | ||||||||||
358 | switch_status_t status = SWITCH_STATUS_FALSE; | |||||||||
359 | ||||||||||
360 | ||||||||||
361 | if (rec > 100) { | |||||||||
362 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 362, ((void*)0), SWITCH_LOG_CRIT, "Too much recursion!\n"); | |||||||||
363 | goto end; | |||||||||
364 | } | |||||||||
365 | ||||||||||
366 | if (!strncasecmp(xcmd, "alias", 5)) { | |||||||||
367 | argc = 1; | |||||||||
368 | argv[0] = xcmd; | |||||||||
369 | } else { | |||||||||
370 | argc = switch_separate_string_string(dup, delim, argv, 128); | |||||||||
371 | } | |||||||||
372 | ||||||||||
373 | for (x = 0; x < argc; x++) { | |||||||||
374 | cmd = argv[x]; | |||||||||
375 | if ((arg = strchr(cmd, '\r')(__extension__ (__builtin_constant_p ('\r') && !__builtin_constant_p (cmd) && ('\r') == '\0' ? (char *) __rawmemchr (cmd, '\r') : __builtin_strchr (cmd, '\r')))) != 0 || (arg = strchr(cmd, '\n')(__extension__ (__builtin_constant_p ('\n') && !__builtin_constant_p (cmd) && ('\n') == '\0' ? (char *) __rawmemchr (cmd, '\n') : __builtin_strchr (cmd, '\n')))) != 0) { | |||||||||
376 | *arg = '\0'; | |||||||||
377 | arg = NULL((void*)0); | |||||||||
378 | } | |||||||||
379 | if ((arg = strchr(cmd, ' ')(__extension__ (__builtin_constant_p (' ') && !__builtin_constant_p (cmd) && (' ') == '\0' ? (char *) __rawmemchr (cmd, ' ' ) : __builtin_strchr (cmd, ' ')))) != 0) { | |||||||||
380 | *arg++ = '\0'; | |||||||||
381 | } | |||||||||
382 | ||||||||||
383 | if ((alias = switch_console_expand_alias(cmd, arg)) && alias != cmd) { | |||||||||
384 | istream->write_function(istream, "\nExpand Alias [%s]->[%s]\n\n", cmd, alias); | |||||||||
385 | status = switch_console_execute(alias, ++rec, istream); | |||||||||
386 | free(alias); | |||||||||
387 | continue; | |||||||||
388 | } | |||||||||
389 | ||||||||||
390 | ||||||||||
391 | status = switch_api_execute(cmd, arg, NULL((void*)0), istream); | |||||||||
392 | } | |||||||||
393 | ||||||||||
394 | end: | |||||||||
395 | ||||||||||
396 | switch_safe_free(dup)if (dup) {free(dup);dup=((void*)0);}; | |||||||||
397 | ||||||||||
398 | return status; | |||||||||
399 | } | |||||||||
400 | ||||||||||
401 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_console_printf(switch_text_channel_t channel, const char *file, const char *func, int line, const char *fmt, ...) | |||||||||
402 | { | |||||||||
403 | char *data = NULL((void*)0); | |||||||||
404 | int ret = 0; | |||||||||
405 | va_list ap; | |||||||||
406 | FILE *handle = switch_core_data_channel(channel); | |||||||||
407 | const char *filep = switch_cut_path(file); | |||||||||
408 | char date[80] = ""; | |||||||||
409 | switch_size_t retsize; | |||||||||
410 | switch_time_exp_t tm; | |||||||||
411 | switch_event_t *event; | |||||||||
412 | ||||||||||
413 | va_start(ap, fmt)__builtin_va_start(ap, fmt); | |||||||||
414 | ret = switch_vasprintf(&data, fmt, ap); | |||||||||
415 | va_end(ap)__builtin_va_end(ap); | |||||||||
416 | ||||||||||
417 | if (ret == -1) { | |||||||||
418 | fprintf(stderrstderr, "Memory Error\n"); | |||||||||
419 | goto done; | |||||||||
420 | } | |||||||||
421 | ||||||||||
422 | if (channel == SWITCH_CHANNEL_ID_LOG_CLEAN) { | |||||||||
423 | fprintf(handle, "%s", data); | |||||||||
424 | goto done; | |||||||||
425 | } | |||||||||
426 | ||||||||||
427 | switch_time_exp_lt(&tm, switch_micro_time_now()); | |||||||||
428 | switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm); | |||||||||
429 | ||||||||||
430 | if (channel == SWITCH_CHANNEL_ID_LOG) { | |||||||||
431 | fprintf(handle, "[%d] %s %s:%d %s() %s", (int) getpid(), date, filep, line, func, data); | |||||||||
432 | goto done; | |||||||||
433 | } | |||||||||
434 | ||||||||||
435 | if (channel == SWITCH_CHANNEL_ID_EVENT && | |||||||||
436 | switch_event_running() == SWITCH_STATUS_SUCCESS && switch_event_create(&event, SWITCH_EVENT_LOG)switch_event_create_subclass_detailed("src/switch_console.c", (const char * )(const char *)__func__, 436, &event, SWITCH_EVENT_LOG , ((void*)0)) == SWITCH_STATUS_SUCCESS) { | |||||||||
437 | ||||||||||
438 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Log-Data", data); | |||||||||
439 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Log-File", filep); | |||||||||
440 | switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Log-Function", func); | |||||||||
441 | switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Line", "%d", line); | |||||||||
442 | switch_event_fire(&event)switch_event_fire_detailed("src/switch_console.c", (const char * )(const char *)__func__, 442, &event, ((void*)0)); | |||||||||
443 | } | |||||||||
444 | ||||||||||
445 | done: | |||||||||
446 | if (data) { | |||||||||
447 | free(data); | |||||||||
448 | } | |||||||||
449 | fflush(handle); | |||||||||
450 | } | |||||||||
451 | ||||||||||
452 | static int32_t running = 1; | |||||||||
453 | ||||||||||
454 | struct helper { | |||||||||
455 | int len; | |||||||||
456 | int hits; | |||||||||
457 | int words; | |||||||||
458 | char last[512]; | |||||||||
459 | char partial[512]; | |||||||||
460 | FILE *out; | |||||||||
461 | switch_stream_handle_t *stream; | |||||||||
462 | switch_xml_t xml; | |||||||||
463 | int xml_off; | |||||||||
464 | }; | |||||||||
465 | ||||||||||
466 | static int comp_callback(void *pArg, int argc, char **argv, char **columnNames) | |||||||||
467 | { | |||||||||
468 | struct helper *h = (struct helper *) pArg; | |||||||||
469 | char *target = NULL((void*)0), *str = NULL((void*)0), *cur = NULL((void*)0); | |||||||||
470 | switch_size_t x, y, i; | |||||||||
471 | ||||||||||
472 | ||||||||||
473 | if (argc > 0) | |||||||||
| ||||||||||
474 | target = argv[0]; | |||||||||
475 | if (argc > 1) | |||||||||
476 | str = argv[1]; | |||||||||
477 | if (argc > 2) | |||||||||
478 | cur = argv[2]; | |||||||||
479 | ||||||||||
480 | if (cur) { | |||||||||
481 | while (*cur == ' ') | |||||||||
482 | cur++; | |||||||||
483 | } | |||||||||
484 | ||||||||||
485 | if (zstr(cur)_zstr(cur)) | |||||||||
486 | cur = NULL((void*)0); | |||||||||
487 | if (zstr(str)_zstr(str)) | |||||||||
488 | str = NULL((void*)0); | |||||||||
489 | ||||||||||
490 | if (!target) { | |||||||||
491 | return -1; | |||||||||
492 | } | |||||||||
493 | ||||||||||
494 | if (!zstr(target)_zstr(target) && *target == ':' && *(target + 1) == ':' && *(target + 2) == '[') { | |||||||||
495 | char *p = target + 3, *list = NULL((void*)0); | |||||||||
496 | ||||||||||
497 | if (p) { | |||||||||
498 | char *s_argv[100] = { 0 }; | |||||||||
499 | char *r_argv[1] = { 0 }, *r_cols[1] = {0}; | |||||||||
500 | list = strdup(p)(__extension__ (__builtin_constant_p (p) && ((size_t) (const void *)((p) + 1) - (size_t)(const void *)(p) == 1) ? ( ((const char *) (p))[0] == '\0' ? (char *) calloc ((size_t) 1 , (size_t) 1) : ({ size_t __len = strlen (p) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, p, __len); __retval; })) : __strdup (p))); | |||||||||
501 | ||||||||||
502 | argc = switch_separate_string(list, ':', s_argv, (sizeof(s_argv) / sizeof(s_argv[0]))); | |||||||||
503 | ||||||||||
504 | for (i = 0; (int)i < argc; i++) { | |||||||||
505 | if (!cur || !strncmp(s_argv[i], cur, strlen(cur))(__extension__ (__builtin_constant_p (strlen(cur)) && ((__builtin_constant_p (s_argv[i]) && strlen (s_argv [i]) < ((size_t) (strlen(cur)))) || (__builtin_constant_p ( cur) && strlen (cur) < ((size_t) (strlen(cur))))) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (s_argv[i]) && __builtin_constant_p (cur) && (__s1_len = __builtin_strlen (s_argv[i]), __s2_len = __builtin_strlen (cur), (!((size_t)(const void *)((s_argv[i]) + 1) - (size_t) (const void *)(s_argv[i]) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((cur) + 1) - (size_t)(const void * )(cur) == 1) || __s2_len >= 4)) ? __builtin_strcmp (s_argv [i], cur) : (__builtin_constant_p (s_argv[i]) && ((size_t )(const void *)((s_argv[i]) + 1) - (size_t)(const void *)(s_argv [i]) == 1) && (__s1_len = __builtin_strlen (s_argv[i] ), __s1_len < 4) ? (__builtin_constant_p (cur) && ( (size_t)(const void *)((cur) + 1) - (size_t)(const void *)(cur ) == 1) ? __builtin_strcmp (s_argv[i], cur) : (__extension__ ( { const unsigned char *__s2 = (const unsigned char *) (const char *) (cur); int __result = (((const unsigned char *) (const char *) (s_argv[i]))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (s_argv[i]))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (s_argv[i]))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (s_argv[i]))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (cur) && ((size_t)(const void *)((cur) + 1) - (size_t )(const void *)(cur) == 1) && (__s2_len = __builtin_strlen (cur), __s2_len < 4) ? (__builtin_constant_p (s_argv[i]) && ((size_t)(const void *)((s_argv[i]) + 1) - (size_t)(const void *)(s_argv[i]) == 1) ? __builtin_strcmp (s_argv[i], cur) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (s_argv[i]); int __result = (((const unsigned char *) (const char *) (cur))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (cur))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (cur))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (cur))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (s_argv[i], cur)))); }) : strncmp (s_argv[i], cur, strlen(cur ))))) { | |||||||||
506 | r_argv[0] = s_argv[i]; | |||||||||
507 | comp_callback(h, 1, r_argv, r_cols); | |||||||||
508 | } | |||||||||
509 | } | |||||||||
510 | switch_safe_free(list)if (list) {free(list);list=((void*)0);}; | |||||||||
511 | } | |||||||||
512 | return 0; | |||||||||
513 | } | |||||||||
514 | ||||||||||
515 | if (!zstr(target)_zstr(target) && *target == ':' && *(target + 1) == ':') { | |||||||||
516 | char *r_argv[1] = { 0 }, *r_cols[1] = {0}; | |||||||||
517 | switch_console_callback_match_t *matches; | |||||||||
518 | if (switch_console_run_complete_func(target, str, cur, &matches) == SWITCH_STATUS_SUCCESS) { | |||||||||
519 | switch_console_callback_match_node_t *m; | |||||||||
520 | for (m = matches->head; m; m = m->next) { | |||||||||
521 | if (!cur || !strncmp(m->val, cur, strlen(cur))(__extension__ (__builtin_constant_p (strlen(cur)) && ((__builtin_constant_p (m->val) && strlen (m-> val) < ((size_t) (strlen(cur)))) || (__builtin_constant_p ( cur) && strlen (cur) < ((size_t) (strlen(cur))))) ? __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (m->val) && __builtin_constant_p (cur) && (__s1_len = __builtin_strlen (m->val), __s2_len = __builtin_strlen (cur), (!((size_t)(const void *)((m->val) + 1) - (size_t) (const void *)(m->val) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((cur) + 1) - (size_t)(const void * )(cur) == 1) || __s2_len >= 4)) ? __builtin_strcmp (m-> val, cur) : (__builtin_constant_p (m->val) && ((size_t )(const void *)((m->val) + 1) - (size_t)(const void *)(m-> val) == 1) && (__s1_len = __builtin_strlen (m->val ), __s1_len < 4) ? (__builtin_constant_p (cur) && ( (size_t)(const void *)((cur) + 1) - (size_t)(const void *)(cur ) == 1) ? __builtin_strcmp (m->val, cur) : (__extension__ ( { const unsigned char *__s2 = (const unsigned char *) (const char *) (cur); int __result = (((const unsigned char *) (const char *) (m->val))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (m->val))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (m->val))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (m->val))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (cur) && ((size_t)(const void *)((cur) + 1) - (size_t )(const void *)(cur) == 1) && (__s2_len = __builtin_strlen (cur), __s2_len < 4) ? (__builtin_constant_p (m->val) && ((size_t)(const void *)((m->val) + 1) - (size_t)(const void *)(m->val) == 1) ? __builtin_strcmp (m->val, cur) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (m->val); int __result = (((const unsigned char *) (const char *) (cur))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (cur))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (cur))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (cur))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (m->val, cur)))); }) : strncmp (m->val, cur, strlen(cur ))))) { | |||||||||
522 | r_argv[0] = m->val; | |||||||||
523 | comp_callback(h, 1, r_argv, r_cols); | |||||||||
524 | } | |||||||||
525 | } | |||||||||
526 | switch_console_free_matches(&matches); | |||||||||
527 | } | |||||||||
528 | return 0; | |||||||||
529 | } | |||||||||
530 | ||||||||||
531 | if (!zstr(target)_zstr(target)) { | |||||||||
532 | if (h->out) { | |||||||||
533 | fprintf(h->out, "[%20s]\t", target); | |||||||||
534 | } | |||||||||
535 | if (h->stream) { | |||||||||
536 | h->stream->write_function(h->stream, "[%20s]\t", target); | |||||||||
537 | } | |||||||||
538 | if (h->xml) { | |||||||||
539 | switch_xml_set_txt_d(switch_xml_add_child_d(h->xml, "match", h->xml_off++), target)switch_xml_set_flag(switch_xml_set_txt(switch_xml_set_flag(switch_xml_add_child (h->xml, (__extension__ (__builtin_constant_p ("match") && ((size_t)(const void *)(("match") + 1) - (size_t)(const void *)("match") == 1) ? (((const char *) ("match"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("match") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "match", __len); __retval; })) : __strdup ("match"))), h-> xml_off++), SWITCH_XML_NAMEM), (__extension__ (__builtin_constant_p (target) && ((size_t)(const void *)((target) + 1) - ( size_t)(const void *)(target) == 1) ? (((const char *) (target ))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (target) + 1; char *__retval = (char * ) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, target, __len); __retval; })) : __strdup (target)))), SWITCH_XML_TXTM); | |||||||||
| ||||||||||
540 | } | |||||||||
541 | ||||||||||
542 | switch_copy_string(h->last, target, sizeof(h->last)); | |||||||||
543 | h->hits++; | |||||||||
544 | } | |||||||||
545 | ||||||||||
546 | x = strlen(h->last); | |||||||||
547 | y = strlen(h->partial); | |||||||||
548 | ||||||||||
549 | if (h->hits > 1) { | |||||||||
550 | for (i = 0; i < x && i < y; i++) { | |||||||||
551 | if (h->last[i] != h->partial[i]) { | |||||||||
552 | h->partial[i] = '\0'; | |||||||||
553 | break; | |||||||||
554 | } | |||||||||
555 | } | |||||||||
556 | } else if (h->hits == 1) { | |||||||||
557 | switch_copy_string(h->partial, target, sizeof(h->last)); | |||||||||
558 | } | |||||||||
559 | ||||||||||
560 | if (!zstr(target)_zstr(target)) { | |||||||||
561 | #ifdef _MSC_VER | |||||||||
562 | if ((h->hits % 3) == 0) { | |||||||||
563 | #else | |||||||||
564 | if ((h->hits % 4) == 0) { | |||||||||
565 | #endif | |||||||||
566 | if (h->out) { | |||||||||
567 | fprintf(h->out, "\n"); | |||||||||
568 | } | |||||||||
569 | if (h->stream) { | |||||||||
570 | h->stream->write_function(h->stream, "\n"); | |||||||||
571 | } | |||||||||
572 | } | |||||||||
573 | } | |||||||||
574 | ||||||||||
575 | return 0; | |||||||||
576 | } | |||||||||
577 | ||||||||||
578 | ||||||||||
579 | ||||||||||
580 | struct match_helper { | |||||||||
581 | switch_console_callback_match_t *my_matches; | |||||||||
582 | }; | |||||||||
583 | ||||||||||
584 | static int modulename_callback(void *pArg, const char *module_name) | |||||||||
585 | { | |||||||||
586 | struct match_helper *h = (struct match_helper *) pArg; | |||||||||
587 | ||||||||||
588 | switch_console_push_match(&h->my_matches, module_name); | |||||||||
589 | return 0; | |||||||||
590 | } | |||||||||
591 | ||||||||||
592 | SWITCH_DECLARE_NONSTD(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_console_list_available_modules(const char *line, const char *cursor, switch_console_callback_match_t **matches) | |||||||||
593 | { | |||||||||
594 | struct match_helper h = { 0 }; | |||||||||
595 | ||||||||||
596 | if (switch_loadable_module_enumerate_available(SWITCH_GLOBAL_dirs.mod_dir, modulename_callback, &h) != SWITCH_STATUS_SUCCESS) { | |||||||||
597 | return SWITCH_STATUS_GENERR; | |||||||||
598 | } | |||||||||
599 | ||||||||||
600 | if (h.my_matches) { | |||||||||
601 | *matches = h.my_matches; | |||||||||
602 | return SWITCH_STATUS_SUCCESS; | |||||||||
603 | } | |||||||||
604 | ||||||||||
605 | return SWITCH_STATUS_FALSE; | |||||||||
606 | } | |||||||||
607 | ||||||||||
608 | SWITCH_DECLARE_NONSTD(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_console_list_loaded_modules(const char *line, const char *cursor, switch_console_callback_match_t **matches) | |||||||||
609 | { | |||||||||
610 | struct match_helper h = { 0 }; | |||||||||
611 | ||||||||||
612 | if (switch_loadable_module_enumerate_loaded(modulename_callback, &h) != SWITCH_STATUS_SUCCESS) { | |||||||||
613 | return SWITCH_STATUS_GENERR; | |||||||||
614 | } | |||||||||
615 | ||||||||||
616 | if (h.my_matches) { | |||||||||
617 | *matches = h.my_matches; | |||||||||
618 | return SWITCH_STATUS_SUCCESS; | |||||||||
619 | } | |||||||||
620 | ||||||||||
621 | return SWITCH_STATUS_FALSE; | |||||||||
622 | } | |||||||||
623 | ||||||||||
624 | #ifdef HAVE_GETIFADDRS1 | |||||||||
625 | #include <ifaddrs.h> | |||||||||
626 | #include <net/if.h> | |||||||||
627 | SWITCH_DECLARE_NONSTD(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_console_list_interfaces(const char *line, const char *cursor, switch_console_callback_match_t **matches) | |||||||||
628 | { | |||||||||
629 | struct match_helper h = { 0 }; | |||||||||
630 | struct ifaddrs *addrs, *addr; | |||||||||
631 | ||||||||||
632 | getifaddrs(&addrs); | |||||||||
633 | for(addr = addrs; addr; addr = addr->ifa_next) { | |||||||||
634 | if (addr->ifa_flags & IFF_UPIFF_UP) { | |||||||||
635 | switch_console_push_match_unique(&h.my_matches, addr->ifa_name); | |||||||||
636 | } | |||||||||
637 | } | |||||||||
638 | freeifaddrs(addrs); | |||||||||
639 | ||||||||||
640 | if (h.my_matches) { | |||||||||
641 | *matches = h.my_matches; | |||||||||
642 | return SWITCH_STATUS_SUCCESS; | |||||||||
643 | } | |||||||||
644 | ||||||||||
645 | return SWITCH_STATUS_FALSE; | |||||||||
646 | } | |||||||||
647 | #else | |||||||||
648 | SWITCH_DECLARE_NONSTD(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_console_list_interfaces(const char *line, const char *cursor, switch_console_callback_match_t **matches) | |||||||||
649 | { | |||||||||
650 | return SWITCH_STATUS_FALSE; | |||||||||
651 | } | |||||||||
652 | #endif | |||||||||
653 | ||||||||||
654 | static int uuid_callback(void *pArg, int argc, char **argv, char **columnNames) | |||||||||
655 | { | |||||||||
656 | struct match_helper *h = (struct match_helper *) pArg; | |||||||||
657 | ||||||||||
658 | switch_console_push_match(&h->my_matches, argv[0]); | |||||||||
659 | return 0; | |||||||||
660 | ||||||||||
661 | } | |||||||||
662 | ||||||||||
663 | SWITCH_DECLARE_NONSTD(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_console_list_uuid(const char *line, const char *cursor, switch_console_callback_match_t **matches) | |||||||||
664 | { | |||||||||
665 | char *sql; | |||||||||
666 | struct match_helper h = { 0 }; | |||||||||
667 | switch_cache_db_handle_t *db = NULL((void*)0); | |||||||||
668 | switch_status_t status = SWITCH_STATUS_FALSE; | |||||||||
669 | char *errmsg; | |||||||||
670 | ||||||||||
671 | ||||||||||
672 | if (switch_core_db_handle(&db)_switch_core_db_handle(&db, "src/switch_console.c", (const char *)__func__, 672) != SWITCH_STATUS_SUCCESS) { | |||||||||
673 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 673, ((void*)0), SWITCH_LOG_ERROR, "Database Error\n"); | |||||||||
674 | return SWITCH_STATUS_GENERR; | |||||||||
675 | } | |||||||||
676 | ||||||||||
677 | if (!zstr(cursor)_zstr(cursor)) { | |||||||||
678 | sql = switch_mprintf("select distinct uuid from channels where uuid like '%q%%' and hostname='%q' order by uuid", | |||||||||
679 | cursor, switch_core_get_switchname()); | |||||||||
680 | } else { | |||||||||
681 | sql = switch_mprintf("select distinct uuid from channels where hostname='%q' order by uuid", switch_core_get_switchname()); | |||||||||
682 | } | |||||||||
683 | ||||||||||
684 | switch_cache_db_execute_sql_callback(db, sql, uuid_callback, &h, &errmsg); | |||||||||
685 | free(sql); | |||||||||
686 | ||||||||||
687 | switch_cache_db_release_db_handle(&db); | |||||||||
688 | ||||||||||
689 | if (h.my_matches) { | |||||||||
690 | *matches = h.my_matches; | |||||||||
691 | status = SWITCH_STATUS_SUCCESS; | |||||||||
692 | } | |||||||||
693 | ||||||||||
694 | ||||||||||
695 | return status; | |||||||||
696 | } | |||||||||
697 | ||||||||||
698 | ||||||||||
699 | SWITCH_DECLARE(unsigned char)__attribute__((visibility("default"))) unsigned char switch_console_complete(const char *line, const char *cursor, FILE * console_out, | |||||||||
700 | switch_stream_handle_t *stream, switch_xml_t xml) | |||||||||
701 | { | |||||||||
702 | switch_cache_db_handle_t *db = NULL((void*)0); | |||||||||
703 | char *sql = NULL((void*)0); | |||||||||
704 | char *dup = strdup(line)(__extension__ (__builtin_constant_p (line) && ((size_t )(const void *)((line) + 1) - (size_t)(const void *)(line) == 1) ? (((const char *) (line))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen (line) + 1 ; char *__retval = (char *) malloc (__len); if (__retval != ( (void*)0)) __retval = (char *) memcpy (__retval, line, __len) ; __retval; })) : __strdup (line))); | |||||||||
705 | char *buf = dup; | |||||||||
706 | char *p, *lp = NULL((void*)0); | |||||||||
707 | char *errmsg = NULL((void*)0); | |||||||||
708 | struct helper h = { 0 }; | |||||||||
709 | unsigned char ret = CC_REDISPLAY8; | |||||||||
710 | int pos = 0; | |||||||||
711 | int sc = 0; | |||||||||
712 | ||||||||||
713 | #ifndef HAVE_LIBEDIT1 | |||||||||
714 | #ifndef _MSC_VER | |||||||||
715 | if (!stream) { | |||||||||
716 | return CC_ERROR6; | |||||||||
717 | } | |||||||||
718 | #endif | |||||||||
719 | #endif | |||||||||
720 | ||||||||||
721 | if (switch_core_db_handle(&db)_switch_core_db_handle(&db, "src/switch_console.c", (const char *)__func__, 721) != SWITCH_STATUS_SUCCESS) { | |||||||||
722 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 722, ((void*)0), SWITCH_LOG_ERROR, "Database Error\n"); | |||||||||
723 | return CC_ERROR6; | |||||||||
724 | } | |||||||||
725 | ||||||||||
726 | if (!zstr(cursor)_zstr(cursor) && !zstr(line)_zstr(line)) { | |||||||||
727 | pos = (int)(cursor - line); | |||||||||
728 | } | |||||||||
729 | ||||||||||
730 | h.out = console_out; | |||||||||
731 | h.stream = stream; | |||||||||
732 | h.xml = xml; | |||||||||
733 | ||||||||||
734 | if (pos > 0) { | |||||||||
735 | *(buf + pos) = '\0'; | |||||||||
736 | } | |||||||||
737 | ||||||||||
738 | if ((p = strchr(buf, '\r')(__extension__ (__builtin_constant_p ('\r') && !__builtin_constant_p (buf) && ('\r') == '\0' ? (char *) __rawmemchr (buf, '\r') : __builtin_strchr (buf, '\r')))) || (p = strchr(buf, '\n')(__extension__ (__builtin_constant_p ('\n') && !__builtin_constant_p (buf) && ('\n') == '\0' ? (char *) __rawmemchr (buf, '\n') : __builtin_strchr (buf, '\n'))))) { | |||||||||
739 | *p = '\0'; | |||||||||
740 | } | |||||||||
741 | ||||||||||
742 | while (*buf == ' ') { | |||||||||
743 | sc++; | |||||||||
744 | buf++; | |||||||||
745 | } | |||||||||
746 | ||||||||||
747 | if (!*buf) { | |||||||||
748 | #ifdef HAVE_LIBEDIT1 | |||||||||
749 | if (h.out && sc) { | |||||||||
750 | el_deletestr(el, sc); | |||||||||
751 | } | |||||||||
752 | #endif | |||||||||
753 | } | |||||||||
754 | ||||||||||
755 | sc = 0; | |||||||||
756 | p = end_of_p(buf)(*buf == '\0' ? buf : buf + strlen(buf) - 1); | |||||||||
757 | while (p >= buf && *p == ' ') { | |||||||||
758 | sc++; | |||||||||
759 | p--; | |||||||||
760 | } | |||||||||
761 | ||||||||||
762 | if (sc > 1) { | |||||||||
763 | #ifdef HAVE_LIBEDIT1 | |||||||||
764 | if (h.out) { | |||||||||
765 | el_deletestr(el, sc - 1); | |||||||||
766 | } | |||||||||
767 | #endif | |||||||||
768 | *(p + 2) = '\0'; | |||||||||
769 | } | |||||||||
770 | ||||||||||
771 | for (p = buf; p && *p; p++) { | |||||||||
772 | if (*p == ' ') { | |||||||||
773 | lp = p; | |||||||||
774 | h.words++; | |||||||||
775 | while (*p == ' ') | |||||||||
776 | p++; | |||||||||
777 | if (!*p) | |||||||||
778 | break; | |||||||||
779 | } | |||||||||
780 | } | |||||||||
781 | ||||||||||
782 | if (lp) { | |||||||||
783 | buf = lp + 1; | |||||||||
784 | } | |||||||||
785 | ||||||||||
786 | h.len = (int)strlen(buf); | |||||||||
787 | ||||||||||
788 | if (h.out) { | |||||||||
789 | fprintf(h.out, "\n\n"); | |||||||||
790 | } | |||||||||
791 | ||||||||||
792 | if (h.stream) { | |||||||||
793 | h.stream->write_function(h.stream, "\n\n"); | |||||||||
794 | } | |||||||||
795 | ||||||||||
796 | ||||||||||
797 | ||||||||||
798 | if (h.words == 0) { | |||||||||
799 | sql = switch_mprintf("select distinct name from interfaces where type='api' and name like '%q%%' and hostname='%q' order by name", | |||||||||
800 | buf, switch_core_get_hostname()); | |||||||||
801 | } | |||||||||
802 | ||||||||||
803 | if (sql) { | |||||||||
804 | switch_cache_db_execute_sql_callback(db, sql, comp_callback, &h, &errmsg); | |||||||||
805 | ||||||||||
806 | if (errmsg) { | |||||||||
807 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 807, ((void*)0), SWITCH_LOG_ERROR, "error [%s][%s]\n", sql, errmsg); | |||||||||
808 | free(errmsg); | |||||||||
809 | ret = CC_ERROR6; | |||||||||
810 | goto end; | |||||||||
811 | } | |||||||||
812 | free(sql); | |||||||||
813 | sql = NULL((void*)0); | |||||||||
814 | } | |||||||||
815 | ||||||||||
816 | if (h.hits != -1) { | |||||||||
817 | char *dupdup = strdup(dup)(__extension__ (__builtin_constant_p (dup) && ((size_t )(const void *)((dup) + 1) - (size_t)(const void *)(dup) == 1 ) ? (((const char *) (dup))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (dup) + 1; char * __retval = (char *) malloc (__len); if (__retval != ((void*)0 )) __retval = (char *) memcpy (__retval, dup, __len); __retval ; })) : __strdup (dup))); | |||||||||
818 | int x, argc = 0; | |||||||||
819 | char *argv[10] = { 0 }; | |||||||||
820 | switch_stream_handle_t stream = { 0 }; | |||||||||
821 | SWITCH_STANDARD_STREAM(stream)memset(&stream, 0, sizeof(stream)); stream.data = malloc( 1024); ((stream.data) ? (void) (0) : __assert_fail ("stream.data" , "src/switch_console.c", 821, __PRETTY_FUNCTION__)); memset( stream.data, 0, 1024); stream.end = stream.data; stream.data_size = 1024; stream.write_function = switch_console_stream_write; stream.raw_write_function = switch_console_stream_raw_write; stream.alloc_len = 1024; stream.alloc_chunk = 1024; | |||||||||
822 | switch_assert(dupdup)((dupdup) ? (void) (0) : __assert_fail ("dupdup", "src/switch_console.c" , 822, __PRETTY_FUNCTION__)); | |||||||||
823 | ||||||||||
824 | argc = switch_separate_string(dupdup, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); | |||||||||
825 | ||||||||||
826 | if (h.words == 0) { | |||||||||
827 | stream.write_function(&stream, "select distinct a1 from complete where " "a1 not in (select name from interfaces where hostname='%s') %s ", | |||||||||
828 | switch_core_get_hostname(), argc ? "and" : ""); | |||||||||
829 | } else { | |||||||||
830 | if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) { | |||||||||
831 | stream.write_function(&stream, "select distinct a%d,'%q','%q' from complete where ", h.words + 1, switch_str_nil(dup)(dup ? dup : ""), switch_str_nil(lp)(lp ? lp : "")); | |||||||||
832 | } else { | |||||||||
833 | stream.write_function(&stream, "select distinct a%d,'%q','%w' from complete where ", h.words + 1, switch_str_nil(dup)(dup ? dup : ""), switch_str_nil(lp)(lp ? lp : "")); | |||||||||
834 | } | |||||||||
835 | } | |||||||||
836 | ||||||||||
837 | for (x = 0; x < argc && x < 11; x++) { | |||||||||
838 | if (h.words + 1 > argc) { | |||||||||
839 | if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) { | |||||||||
840 | stream.write_function(&stream, "(a%d like '::%%' or a%d = '' or a%d = '%q')%q", | |||||||||
841 | x + 1, x + 1, x + 1, switch_str_nil(argv[x])(argv[x] ? argv[x] : ""), x == argc - 1 ? "" : " and "); | |||||||||
842 | } else { | |||||||||
843 | stream.write_function(&stream, "(a%d like '::%%' or a%d = '' or a%d = '%w')%w", | |||||||||
844 | x + 1, x + 1, x + 1, switch_str_nil(argv[x])(argv[x] ? argv[x] : ""), x == argc - 1 ? "" : " and "); | |||||||||
845 | } | |||||||||
846 | } else { | |||||||||
847 | if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) { | |||||||||
848 | stream.write_function(&stream, "(a%d like '::%%' or a%d = '' or a%d like '%q%%')%q", | |||||||||
849 | x + 1, x + 1, x + 1, switch_str_nil(argv[x])(argv[x] ? argv[x] : ""), x == argc - 1 ? "" : " and "); | |||||||||
850 | } else { | |||||||||
851 | stream.write_function(&stream, "(a%d like '::%%' or a%d = '' or a%d like '%w%%')%w", | |||||||||
852 | x + 1, x + 1, x + 1, switch_str_nil(argv[x])(argv[x] ? argv[x] : ""), x == argc - 1 ? "" : " and "); | |||||||||
853 | } | |||||||||
854 | } | |||||||||
855 | } | |||||||||
856 | ||||||||||
857 | stream.write_function(&stream, " and hostname='%s' order by a%d", switch_core_get_hostname(), h.words + 1); | |||||||||
858 | ||||||||||
859 | switch_cache_db_execute_sql_callback(db, stream.data, comp_callback, &h, &errmsg); | |||||||||
860 | ||||||||||
861 | if (errmsg) { | |||||||||
862 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 862, ((void*)0), SWITCH_LOG_ERROR, "error [%s][%s]\n", (char *) stream.data, errmsg); | |||||||||
863 | free(errmsg); | |||||||||
864 | ret = CC_ERROR6; | |||||||||
865 | } | |||||||||
866 | ||||||||||
867 | switch_safe_free(dupdup)if (dupdup) {free(dupdup);dupdup=((void*)0);}; | |||||||||
868 | switch_safe_free(stream.data)if (stream.data) {free(stream.data);stream.data=((void*)0);}; | |||||||||
869 | ||||||||||
870 | if (ret == CC_ERROR6) { | |||||||||
871 | goto end; | |||||||||
872 | } | |||||||||
873 | } | |||||||||
874 | ||||||||||
875 | if (h.out) { | |||||||||
876 | fprintf(h.out, "\n\n"); | |||||||||
877 | } | |||||||||
878 | ||||||||||
879 | if (h.stream) { | |||||||||
880 | h.stream->write_function(h.stream, "\n\n"); | |||||||||
881 | if (h.hits == 1 && !zstr(h.last)_zstr(h.last)) { | |||||||||
882 | h.stream->write_function(h.stream, "write=%d:%s ", h.len, h.last); | |||||||||
883 | } else if (h.hits > 1 && !zstr(h.partial)_zstr(h.partial)) { | |||||||||
884 | h.stream->write_function(h.stream, "write=%d:%s", h.len, h.partial); | |||||||||
885 | } | |||||||||
886 | } | |||||||||
887 | ||||||||||
888 | if (h.xml) { | |||||||||
889 | switch_xml_t x_write = switch_xml_add_child_d(h.xml, "write", h.xml_off++)switch_xml_set_flag(switch_xml_add_child(h.xml, (__extension__ (__builtin_constant_p ("write") && ((size_t)(const void *)(("write") + 1) - (size_t)(const void *)("write") == 1) ? ( ((const char *) ("write"))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen ("write") + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, "write", __len); __retval ; })) : __strdup ("write"))), h.xml_off++), SWITCH_XML_NAMEM); | |||||||||
890 | char buf[32]; | |||||||||
891 | ||||||||||
892 | snprintf(buf, sizeof(buf), "%d", h.len); | |||||||||
893 | switch_xml_set_attr_d_buf(x_write, "length", buf)switch_xml_set_attr(switch_xml_set_flag(x_write, SWITCH_XML_DUP ), (__extension__ (__builtin_constant_p ("length") && ((size_t)(const void *)(("length") + 1) - (size_t)(const void *)("length") == 1) ? (((const char *) ("length"))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen ("length") + 1; char *__retval = (char *) malloc (__len ); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval , "length", __len); __retval; })) : __strdup ("length"))), (__extension__ (__builtin_constant_p (buf) && ((size_t)(const void * )((buf) + 1) - (size_t)(const void *)(buf) == 1) ? (((const char *) (buf))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (buf) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, buf, __len); __retval; })) : __strdup ( buf)))); | |||||||||
894 | ||||||||||
895 | if (h.hits == 1 && !zstr(h.last)_zstr(h.last)) { | |||||||||
896 | switch_xml_set_txt_d(x_write, h.last)switch_xml_set_flag(switch_xml_set_txt(x_write, (__extension__ (__builtin_constant_p (h.last) && ((size_t)(const void *)((h.last) + 1) - (size_t)(const void *)(h.last) == 1) ? (( (const char *) (h.last))[0] == '\0' ? (char *) calloc ((size_t ) 1, (size_t) 1) : ({ size_t __len = strlen (h.last) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void* )0)) __retval = (char *) memcpy (__retval, h.last, __len); __retval ; })) : __strdup (h.last)))), SWITCH_XML_TXTM); | |||||||||
897 | } else if (h.hits > 1 && !zstr(h.partial)_zstr(h.partial)) { | |||||||||
898 | switch_xml_set_txt_d(x_write, h.partial)switch_xml_set_flag(switch_xml_set_txt(x_write, (__extension__ (__builtin_constant_p (h.partial) && ((size_t)(const void *)((h.partial) + 1) - (size_t)(const void *)(h.partial) == 1) ? (((const char *) (h.partial))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (h.partial ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, h.partial , __len); __retval; })) : __strdup (h.partial)))), SWITCH_XML_TXTM ); | |||||||||
899 | } | |||||||||
900 | } | |||||||||
901 | #ifdef HAVE_LIBEDIT1 | |||||||||
902 | if (h.out) { | |||||||||
903 | if (h.hits == 1 && !zstr(h.last)_zstr(h.last)) { | |||||||||
904 | el_deletestr(el, h.len); | |||||||||
905 | el_insertstr(el, h.last); | |||||||||
906 | el_insertstr(el, " "); | |||||||||
907 | } else if (h.hits > 1 && !zstr(h.partial)_zstr(h.partial)) { | |||||||||
908 | el_deletestr(el, h.len); | |||||||||
909 | el_insertstr(el, h.partial); | |||||||||
910 | } | |||||||||
911 | } | |||||||||
912 | #else | |||||||||
913 | #ifdef _MSC_VER | |||||||||
914 | if (h.out) { | |||||||||
915 | if (h.hits == 1 && !zstr(h.last)_zstr(h.last)) { | |||||||||
916 | console_bufferInput(0, h.len, (char *) line, DELETE_REFRESH_OP); | |||||||||
917 | console_bufferInput(h.last, (int) strlen(h.last), (char *) line, 0); | |||||||||
918 | console_bufferInput(" ", 1, (char *) line, 0); | |||||||||
919 | } else if (h.hits > 1 && !zstr(h.partial)_zstr(h.partial)) { | |||||||||
920 | console_bufferInput(0, h.len, (char *) line, DELETE_REFRESH_OP); | |||||||||
921 | console_bufferInput(h.partial, (int) strlen(h.partial), (char *) line, 0); | |||||||||
922 | } else { | |||||||||
923 | console_bufferInput(0, 0, (char *) line, DELETE_REFRESH_OP); | |||||||||
924 | } | |||||||||
925 | } | |||||||||
926 | #endif | |||||||||
927 | #endif | |||||||||
928 | ||||||||||
929 | end: | |||||||||
930 | ||||||||||
931 | if (h.out) { | |||||||||
932 | fflush(h.out); | |||||||||
933 | } | |||||||||
934 | ||||||||||
935 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||||||||
936 | switch_safe_free(dup)if (dup) {free(dup);dup=((void*)0);}; | |||||||||
937 | ||||||||||
938 | switch_cache_db_release_db_handle(&db); | |||||||||
939 | ||||||||||
940 | return (ret); | |||||||||
941 | } | |||||||||
942 | ||||||||||
943 | ||||||||||
944 | #if defined(HAVE_LIBEDIT1) || defined(_MSC_VER) | |||||||||
945 | /* | |||||||||
946 | * If a fnkey is configured then process the command | |||||||||
947 | */ | |||||||||
948 | static unsigned char console_fnkey_pressed(int i) | |||||||||
949 | { | |||||||||
950 | char *c, *cmd; | |||||||||
951 | ||||||||||
952 | switch_assert((i > 0) && (i <= 12))(((i > 0) && (i <= 12)) ? (void) (0) : __assert_fail ("(i > 0) && (i <= 12)", "src/switch_console.c" , 952, __PRETTY_FUNCTION__)); | |||||||||
953 | ||||||||||
954 | c = console_fnkeys[i - 1]; | |||||||||
955 | ||||||||||
956 | /* This new line is necessary to avoid output to begin after the ">" of the CLI's prompt */ | |||||||||
957 | switch_log_printf(SWITCH_CHANNEL_LOG_CLEANSWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_console.c", (const char *)__func__, 957, ((void*)0), SWITCH_LOG_CONSOLE, "\n"); | |||||||||
958 | ||||||||||
959 | if (c == NULL((void*)0)) { | |||||||||
960 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 960, ((void*)0), SWITCH_LOG_CONSOLE, "FUNCTION KEY F%d IS NOT BOUND, please edit switch.conf XML file\n", i); | |||||||||
961 | return CC_REDISPLAY8; | |||||||||
962 | } | |||||||||
963 | ||||||||||
964 | cmd = strdup(c)(__extension__ (__builtin_constant_p (c) && ((size_t) (const void *)((c) + 1) - (size_t)(const void *)(c) == 1) ? ( ((const char *) (c))[0] == '\0' ? (char *) calloc ((size_t) 1 , (size_t) 1) : ({ size_t __len = strlen (c) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, c, __len); __retval; })) : __strdup (c))); | |||||||||
965 | switch_console_process(cmd); | |||||||||
966 | free(cmd); | |||||||||
967 | ||||||||||
968 | return CC_REDISPLAY8; | |||||||||
969 | } | |||||||||
970 | #endif | |||||||||
971 | ||||||||||
972 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_console_save_history(void) | |||||||||
973 | { | |||||||||
974 | #ifdef HAVE_LIBEDIT1 | |||||||||
975 | history(myhistory, &ev, H_SAVE18, hfile); | |||||||||
976 | #else | |||||||||
977 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 977, ((void*)0), SWITCH_LOG_CONSOLE, "NOT IMPLEMENTED!\n"); | |||||||||
978 | #endif | |||||||||
979 | } | |||||||||
980 | ||||||||||
981 | #ifdef HAVE_LIBEDIT1 | |||||||||
982 | static char prompt_str[512] = ""; | |||||||||
983 | ||||||||||
984 | static unsigned char console_f1key(EditLine * el, int ch) | |||||||||
985 | { | |||||||||
986 | return console_fnkey_pressed(1); | |||||||||
987 | } | |||||||||
988 | static unsigned char console_f2key(EditLine * el, int ch) | |||||||||
989 | { | |||||||||
990 | return console_fnkey_pressed(2); | |||||||||
991 | } | |||||||||
992 | static unsigned char console_f3key(EditLine * el, int ch) | |||||||||
993 | { | |||||||||
994 | return console_fnkey_pressed(3); | |||||||||
995 | } | |||||||||
996 | static unsigned char console_f4key(EditLine * el, int ch) | |||||||||
997 | { | |||||||||
998 | return console_fnkey_pressed(4); | |||||||||
999 | } | |||||||||
1000 | static unsigned char console_f5key(EditLine * el, int ch) | |||||||||
1001 | { | |||||||||
1002 | return console_fnkey_pressed(5); | |||||||||
1003 | } | |||||||||
1004 | static unsigned char console_f6key(EditLine * el, int ch) | |||||||||
1005 | { | |||||||||
1006 | return console_fnkey_pressed(6); | |||||||||
1007 | } | |||||||||
1008 | static unsigned char console_f7key(EditLine * el, int ch) | |||||||||
1009 | { | |||||||||
1010 | return console_fnkey_pressed(7); | |||||||||
1011 | } | |||||||||
1012 | static unsigned char console_f8key(EditLine * el, int ch) | |||||||||
1013 | { | |||||||||
1014 | return console_fnkey_pressed(8); | |||||||||
1015 | } | |||||||||
1016 | static unsigned char console_f9key(EditLine * el, int ch) | |||||||||
1017 | { | |||||||||
1018 | return console_fnkey_pressed(9); | |||||||||
1019 | } | |||||||||
1020 | static unsigned char console_f10key(EditLine * el, int ch) | |||||||||
1021 | { | |||||||||
1022 | return console_fnkey_pressed(10); | |||||||||
1023 | } | |||||||||
1024 | static unsigned char console_f11key(EditLine * el, int ch) | |||||||||
1025 | { | |||||||||
1026 | return console_fnkey_pressed(11); | |||||||||
1027 | } | |||||||||
1028 | static unsigned char console_f12key(EditLine * el, int ch) | |||||||||
1029 | { | |||||||||
1030 | return console_fnkey_pressed(12); | |||||||||
1031 | } | |||||||||
1032 | ||||||||||
1033 | ||||||||||
1034 | char *prompt(EditLine * e) | |||||||||
1035 | { | |||||||||
1036 | if (*prompt_str == '\0') { | |||||||||
1037 | switch_snprintf(prompt_str, sizeof(prompt_str), "freeswitch@%s> ", switch_core_get_switchname()); | |||||||||
1038 | } | |||||||||
1039 | ||||||||||
1040 | return prompt_str; | |||||||||
1041 | } | |||||||||
1042 | ||||||||||
1043 | static void *SWITCH_THREAD_FUNC console_thread(switch_thread_t *thread, void *obj) | |||||||||
1044 | { | |||||||||
1045 | int count; | |||||||||
1046 | const char *line; | |||||||||
1047 | switch_memory_pool_t *pool = (switch_memory_pool_t *) obj; | |||||||||
1048 | ||||||||||
1049 | while (running) { | |||||||||
1050 | int32_t arg = 0; | |||||||||
1051 | ||||||||||
1052 | if (getppid() == 1) { | |||||||||
1053 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 1053, ((void*)0), SWITCH_LOG_WARNING, "We've become an orphan, no more console for us.\n"); | |||||||||
1054 | break; | |||||||||
1055 | } | |||||||||
1056 | ||||||||||
1057 | switch_core_session_ctl(SCSC_CHECK_RUNNING, &arg); | |||||||||
1058 | if (!arg) { | |||||||||
1059 | break; | |||||||||
1060 | } | |||||||||
1061 | ||||||||||
1062 | line = el_gets(el, &count); | |||||||||
1063 | ||||||||||
1064 | if (count > 1) { | |||||||||
1065 | if (!zstr(line)_zstr(line)) { | |||||||||
1066 | char *cmd = strdup(line)(__extension__ (__builtin_constant_p (line) && ((size_t )(const void *)((line) + 1) - (size_t)(const void *)(line) == 1) ? (((const char *) (line))[0] == '\0' ? (char *) calloc ( (size_t) 1, (size_t) 1) : ({ size_t __len = strlen (line) + 1 ; char *__retval = (char *) malloc (__len); if (__retval != ( (void*)0)) __retval = (char *) memcpy (__retval, line, __len) ; __retval; })) : __strdup (line))); | |||||||||
1067 | char *p; | |||||||||
1068 | const LineInfo *lf = el_line(el); | |||||||||
1069 | char *foo = (char *) lf->buffer; | |||||||||
1070 | if ((p = strrchr(cmd, '\r')) || (p = strrchr(cmd, '\n'))) { | |||||||||
1071 | *p = '\0'; | |||||||||
1072 | } | |||||||||
1073 | assert(cmd != NULL)((cmd != ((void*)0)) ? (void) (0) : __assert_fail ("cmd != ((void*)0)" , "src/switch_console.c", 1073, __PRETTY_FUNCTION__)); | |||||||||
1074 | history(myhistory, &ev, H_ENTER10, line); | |||||||||
1075 | running = switch_console_process(cmd); | |||||||||
1076 | el_deletestr(el, strlen(foo) + 1); | |||||||||
1077 | memset(foo, 0, strlen(foo)); | |||||||||
1078 | free(cmd); | |||||||||
1079 | } | |||||||||
1080 | } | |||||||||
1081 | switch_cond_next(); | |||||||||
1082 | } | |||||||||
1083 | ||||||||||
1084 | switch_core_destroy_memory_pool(&pool)switch_core_perform_destroy_memory_pool(&pool, "src/switch_console.c" , (const char *)__func__, 1084); | |||||||||
1085 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 1085, ((void*)0), SWITCH_LOG_DEBUG, "Editline thread exiting\n"); | |||||||||
1086 | return NULL((void*)0); | |||||||||
1087 | } | |||||||||
1088 | ||||||||||
1089 | static unsigned char complete(EditLine * el, int ch) | |||||||||
1090 | { | |||||||||
1091 | const LineInfo *lf = el_line(el); | |||||||||
1092 | ||||||||||
1093 | return switch_console_complete(lf->buffer, lf->cursor, switch_core_get_console(), NULL((void*)0), NULL((void*)0)); | |||||||||
1094 | } | |||||||||
1095 | ||||||||||
1096 | ||||||||||
1097 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_console_loop(void) | |||||||||
1098 | { | |||||||||
1099 | switch_thread_t *thread; | |||||||||
1100 | switch_threadattr_t *thd_attr = NULL((void*)0); | |||||||||
1101 | switch_memory_pool_t *pool; | |||||||||
1102 | ||||||||||
1103 | if (switch_core_new_memory_pool(&pool)switch_core_perform_new_memory_pool(&pool, "src/switch_console.c" , (const char *)__func__, 1103) != SWITCH_STATUS_SUCCESS) { | |||||||||
1104 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 1104, ((void*)0), SWITCH_LOG_CRIT, "Pool Failure\n"); | |||||||||
1105 | return; | |||||||||
1106 | } | |||||||||
1107 | ||||||||||
1108 | el = el_init(__FILE__"src/switch_console.c", switch_core_get_console(), switch_core_get_console(), switch_core_get_console()); | |||||||||
1109 | el_set(el, EL_PROMPT0, &prompt); | |||||||||
1110 | el_set(el, EL_EDITOR2, "emacs"); | |||||||||
1111 | /* AGX: Bind Keyboard function keys. This has been tested with: | |||||||||
1112 | * - linux console keyabord | |||||||||
1113 | * - putty.exe connected via ssh to linux | |||||||||
1114 | */ | |||||||||
1115 | /* Load/Init the config first */ | |||||||||
1116 | console_xml_config(); | |||||||||
1117 | /* Bind the functions to the key */ | |||||||||
1118 | el_set(el, EL_ADDFN9, "f1-key", "F1 KEY PRESS", console_f1key); | |||||||||
1119 | el_set(el, EL_ADDFN9, "f2-key", "F2 KEY PRESS", console_f2key); | |||||||||
1120 | el_set(el, EL_ADDFN9, "f3-key", "F3 KEY PRESS", console_f3key); | |||||||||
1121 | el_set(el, EL_ADDFN9, "f4-key", "F4 KEY PRESS", console_f4key); | |||||||||
1122 | el_set(el, EL_ADDFN9, "f5-key", "F5 KEY PRESS", console_f5key); | |||||||||
1123 | el_set(el, EL_ADDFN9, "f6-key", "F6 KEY PRESS", console_f6key); | |||||||||
1124 | el_set(el, EL_ADDFN9, "f7-key", "F7 KEY PRESS", console_f7key); | |||||||||
1125 | el_set(el, EL_ADDFN9, "f8-key", "F8 KEY PRESS", console_f8key); | |||||||||
1126 | el_set(el, EL_ADDFN9, "f9-key", "F9 KEY PRESS", console_f9key); | |||||||||
1127 | el_set(el, EL_ADDFN9, "f10-key", "F10 KEY PRESS", console_f10key); | |||||||||
1128 | el_set(el, EL_ADDFN9, "f11-key", "F11 KEY PRESS", console_f11key); | |||||||||
1129 | el_set(el, EL_ADDFN9, "f12-key", "F12 KEY PRESS", console_f12key); | |||||||||
1130 | ||||||||||
1131 | el_set(el, EL_BIND4, "\033OP", "f1-key", NULL((void*)0)); | |||||||||
1132 | el_set(el, EL_BIND4, "\033OQ", "f2-key", NULL((void*)0)); | |||||||||
1133 | el_set(el, EL_BIND4, "\033OR", "f3-key", NULL((void*)0)); | |||||||||
1134 | el_set(el, EL_BIND4, "\033OS", "f4-key", NULL((void*)0)); | |||||||||
1135 | ||||||||||
1136 | ||||||||||
1137 | el_set(el, EL_BIND4, "\033[11~", "f1-key", NULL((void*)0)); | |||||||||
1138 | el_set(el, EL_BIND4, "\033[12~", "f2-key", NULL((void*)0)); | |||||||||
1139 | el_set(el, EL_BIND4, "\033[13~", "f3-key", NULL((void*)0)); | |||||||||
1140 | el_set(el, EL_BIND4, "\033[14~", "f4-key", NULL((void*)0)); | |||||||||
1141 | el_set(el, EL_BIND4, "\033[15~", "f5-key", NULL((void*)0)); | |||||||||
1142 | el_set(el, EL_BIND4, "\033[17~", "f6-key", NULL((void*)0)); | |||||||||
1143 | el_set(el, EL_BIND4, "\033[18~", "f7-key", NULL((void*)0)); | |||||||||
1144 | el_set(el, EL_BIND4, "\033[19~", "f8-key", NULL((void*)0)); | |||||||||
1145 | el_set(el, EL_BIND4, "\033[20~", "f9-key", NULL((void*)0)); | |||||||||
1146 | el_set(el, EL_BIND4, "\033[21~", "f10-key", NULL((void*)0)); | |||||||||
1147 | el_set(el, EL_BIND4, "\033[23~", "f11-key", NULL((void*)0)); | |||||||||
1148 | el_set(el, EL_BIND4, "\033[24~", "f12-key", NULL((void*)0)); | |||||||||
1149 | ||||||||||
1150 | ||||||||||
1151 | el_set(el, EL_ADDFN9, "ed-complete", "Complete argument", complete); | |||||||||
1152 | el_set(el, EL_BIND4, "^I", "ed-complete", NULL((void*)0)); | |||||||||
1153 | ||||||||||
1154 | /* "Delete" key. */ | |||||||||
1155 | el_set(el, EL_BIND4, "\033[3~", "ed-delete-next-char", NULL((void*)0)); | |||||||||
1156 | ||||||||||
1157 | myhistory = history_init(); | |||||||||
1158 | if (myhistory == 0) { | |||||||||
1159 | fprintf(stderrstderr, "history could not be initialized\n"); | |||||||||
1160 | return; | |||||||||
1161 | } | |||||||||
1162 | ||||||||||
1163 | hfile = switch_mprintf("%s%sfreeswitch.history", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR"/"); | |||||||||
1164 | assert(hfile != NULL)((hfile != ((void*)0)) ? (void) (0) : __assert_fail ("hfile != ((void*)0)" , "src/switch_console.c", 1164, __PRETTY_FUNCTION__)); | |||||||||
1165 | ||||||||||
1166 | history(myhistory, &ev, H_SETSIZE1, 800); | |||||||||
1167 | el_set(el, EL_HIST10, history, myhistory); | |||||||||
1168 | history(myhistory, &ev, H_LOAD17, hfile); | |||||||||
1169 | ||||||||||
1170 | el_source(el, NULL((void*)0)); | |||||||||
1171 | ||||||||||
1172 | switch_threadattr_create(&thd_attr, pool); | |||||||||
1173 | switch_threadattr_detach_set(thd_attr, 1); | |||||||||
1174 | switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE240 * 1024); | |||||||||
1175 | switch_thread_create(&thread, thd_attr, console_thread, pool, pool); | |||||||||
1176 | ||||||||||
1177 | while (running) { | |||||||||
1178 | int32_t arg = 0; | |||||||||
1179 | switch_core_session_ctl(SCSC_CHECK_RUNNING, &arg); | |||||||||
1180 | if (!arg) { | |||||||||
1181 | break; | |||||||||
1182 | } | |||||||||
1183 | switch_yield(1000000)switch_sleep(1000000);; | |||||||||
1184 | } | |||||||||
1185 | ||||||||||
1186 | history(myhistory, &ev, H_SAVE18, hfile); | |||||||||
1187 | free(hfile); | |||||||||
1188 | ||||||||||
1189 | /* Clean up our memory */ | |||||||||
1190 | history_end(myhistory); | |||||||||
1191 | el_end(el); | |||||||||
1192 | } | |||||||||
1193 | ||||||||||
1194 | #else | |||||||||
1195 | ||||||||||
1196 | #ifdef _MSC_VER | |||||||||
1197 | char history[HISTLEN][CMD_BUFLEN1024 + 1]; | |||||||||
1198 | int iHistory = 0; | |||||||||
1199 | int iHistorySel = 0; | |||||||||
1200 | ||||||||||
1201 | static int console_history(char *cmd, int direction) | |||||||||
1202 | { | |||||||||
1203 | int i; | |||||||||
1204 | static int first; | |||||||||
1205 | ||||||||||
1206 | if (direction == 0) { | |||||||||
1207 | first = 1; | |||||||||
1208 | if (iHistory < HISTLEN) { | |||||||||
1209 | if (iHistory && strcmp(history[iHistory - 1], cmd)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (history[iHistory - 1]) && __builtin_constant_p (cmd ) && (__s1_len = __builtin_strlen (history[iHistory - 1]), __s2_len = __builtin_strlen (cmd), (!((size_t)(const void *)((history[iHistory - 1]) + 1) - (size_t)(const void *)(history [iHistory - 1]) == 1) || __s1_len >= 4) && (!((size_t )(const void *)((cmd) + 1) - (size_t)(const void *)(cmd) == 1 ) || __s2_len >= 4)) ? __builtin_strcmp (history[iHistory - 1], cmd) : (__builtin_constant_p (history[iHistory - 1]) && ((size_t)(const void *)((history[iHistory - 1]) + 1) - (size_t )(const void *)(history[iHistory - 1]) == 1) && (__s1_len = __builtin_strlen (history[iHistory - 1]), __s1_len < 4) ? (__builtin_constant_p (cmd) && ((size_t)(const void *)((cmd) + 1) - (size_t)(const void *)(cmd) == 1) ? __builtin_strcmp (history[iHistory - 1], cmd) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (cmd); int __result = (((const unsigned char *) (const char *) (history [iHistory - 1]))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (history[iHistory - 1]))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (history[iHistory - 1]))[2] - __s2[2] ); if (__s1_len > 2 && __result == 0) __result = ( ((const unsigned char *) (const char *) (history[iHistory - 1 ]))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (cmd) && ((size_t)(const void *)((cmd) + 1) - (size_t )(const void *)(cmd) == 1) && (__s2_len = __builtin_strlen (cmd), __s2_len < 4) ? (__builtin_constant_p (history[iHistory - 1]) && ((size_t)(const void *)((history[iHistory - 1]) + 1) - (size_t)(const void *)(history[iHistory - 1]) == 1 ) ? __builtin_strcmp (history[iHistory - 1], cmd) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (history[iHistory - 1]); int __result = (((const unsigned char *) (const char *) (cmd))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (cmd))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (cmd))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (cmd))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp (history[iHistory - 1], cmd)))); })) { | |||||||||
1210 | iHistorySel = iHistory; | |||||||||
1211 | strcpy(history[iHistory++], cmd); | |||||||||
1212 | } else if (iHistory == 0) { | |||||||||
1213 | iHistorySel = iHistory; | |||||||||
1214 | strcpy(history[iHistory++], cmd); | |||||||||
1215 | } | |||||||||
1216 | } else { | |||||||||
1217 | iHistory = HISTLEN - 1; | |||||||||
1218 | for (i = 0; i < HISTLEN - 1; i++) { | |||||||||
1219 | strcpy(history[i], history[i + 1]); | |||||||||
1220 | } | |||||||||
1221 | iHistorySel = iHistory; | |||||||||
1222 | strcpy(history[iHistory++], cmd); | |||||||||
1223 | } | |||||||||
1224 | } else { | |||||||||
1225 | if (!first) { | |||||||||
1226 | iHistorySel += direction; | |||||||||
1227 | } | |||||||||
1228 | first = 0; | |||||||||
1229 | if (iHistorySel < 0) { | |||||||||
1230 | iHistorySel = 0; | |||||||||
1231 | } | |||||||||
1232 | if (iHistory && iHistorySel >= iHistory) { | |||||||||
1233 | iHistorySel = iHistory - 1; | |||||||||
1234 | } | |||||||||
1235 | strcpy(cmd, history[iHistorySel]); | |||||||||
1236 | } | |||||||||
1237 | return (SWITCH_STATUS_SUCCESS); | |||||||||
1238 | } | |||||||||
1239 | ||||||||||
1240 | static int console_bufferInput(char *addchars, int len, char *cmd, int key) | |||||||||
1241 | { | |||||||||
1242 | static int iCmdBuffer = 0; | |||||||||
1243 | static int iCmdCursor = 0; | |||||||||
1244 | static int ignoreNext = 0; | |||||||||
1245 | static int insertMode = 1; | |||||||||
1246 | static COORD orgPosition; | |||||||||
1247 | static char prompt[80]; | |||||||||
1248 | int iBuf; | |||||||||
1249 | int i; | |||||||||
1250 | ||||||||||
1251 | HANDLE hOut; | |||||||||
1252 | CONSOLE_SCREEN_BUFFER_INFO info; | |||||||||
1253 | COORD position; | |||||||||
1254 | hOut = GetStdHandle(STD_OUTPUT_HANDLE); | |||||||||
1255 | GetConsoleScreenBufferInfo(hOut, &info); | |||||||||
1256 | position = info.dwCursorPosition; | |||||||||
1257 | if (iCmdCursor == 0) { | |||||||||
1258 | orgPosition = position; | |||||||||
1259 | } | |||||||||
1260 | ||||||||||
1261 | if (key == PROMPT_OP) { | |||||||||
1262 | if (strlen(cmd) < sizeof(prompt)) { | |||||||||
1263 | strcpy(prompt, cmd); | |||||||||
1264 | } | |||||||||
1265 | return 0; | |||||||||
1266 | } | |||||||||
1267 | ||||||||||
1268 | if (key == KEY_TAB) { | |||||||||
1269 | switch_console_complete(cmd, cmd + iCmdBuffer, switch_core_get_console(), NULL((void*)0), NULL((void*)0)); | |||||||||
1270 | return 0; | |||||||||
1271 | } | |||||||||
1272 | if (key == KEY_UP || key == KEY_DOWN || key == CLEAR_OP) { | |||||||||
1273 | SetConsoleCursorPosition(hOut, orgPosition); | |||||||||
1274 | for (i = 0; i < (int) strlen(cmd); i++) { | |||||||||
1275 | printf(" "); | |||||||||
1276 | } | |||||||||
1277 | SetConsoleCursorPosition(hOut, orgPosition); | |||||||||
1278 | iCmdBuffer = 0; | |||||||||
1279 | iCmdCursor = 0; | |||||||||
1280 | memset(cmd, 0, CMD_BUFLEN1024); | |||||||||
1281 | } | |||||||||
1282 | if (key == DELETE_REFRESH_OP) { | |||||||||
1283 | int l = len < (int) strlen(cmd) ? len : (int) strlen(cmd); | |||||||||
1284 | for (i = 0; i < l; i++) { | |||||||||
1285 | cmd[--iCmdBuffer] = 0; | |||||||||
1286 | } | |||||||||
1287 | iCmdCursor = (int) strlen(cmd); | |||||||||
1288 | printf("%s", prompt); | |||||||||
1289 | GetConsoleScreenBufferInfo(hOut, &info); | |||||||||
1290 | orgPosition = info.dwCursorPosition; | |||||||||
1291 | printf("%s", cmd); | |||||||||
1292 | return 0; | |||||||||
1293 | } | |||||||||
1294 | ||||||||||
1295 | if (key == KEY_LEFT) { | |||||||||
1296 | if (iCmdCursor) { | |||||||||
1297 | if (position.X == 0) { | |||||||||
1298 | position.Y -= 1; | |||||||||
1299 | position.X = info.dwSize.X - 1; | |||||||||
1300 | } else { | |||||||||
1301 | position.X -= 1; | |||||||||
1302 | } | |||||||||
1303 | ||||||||||
1304 | SetConsoleCursorPosition(hOut, position); | |||||||||
1305 | iCmdCursor--; | |||||||||
1306 | } | |||||||||
1307 | } | |||||||||
1308 | if (key == KEY_RIGHT) { | |||||||||
1309 | if (iCmdCursor < (int) strlen(cmd)) { | |||||||||
1310 | if (position.X == info.dwSize.X - 1) { | |||||||||
1311 | position.Y += 1; | |||||||||
1312 | position.X = 0; | |||||||||
1313 | } else { | |||||||||
1314 | position.X += 1; | |||||||||
1315 | } | |||||||||
1316 | ||||||||||
1317 | SetConsoleCursorPosition(hOut, position); | |||||||||
1318 | iCmdCursor++; | |||||||||
1319 | } | |||||||||
1320 | } | |||||||||
1321 | if (key == KEY_INSERT) { | |||||||||
1322 | insertMode = !insertMode; | |||||||||
1323 | } | |||||||||
1324 | if (key == KEY_DELETE) { | |||||||||
1325 | if (iCmdCursor < iCmdBuffer) { | |||||||||
1326 | int pos; | |||||||||
1327 | for (pos = iCmdCursor; pos < iCmdBuffer; pos++) { | |||||||||
1328 | cmd[pos] = cmd[pos + 1]; | |||||||||
1329 | } | |||||||||
1330 | cmd[pos] = 0; | |||||||||
1331 | iCmdBuffer--; | |||||||||
1332 | ||||||||||
1333 | for (pos = iCmdCursor; pos < iCmdBuffer; pos++) { | |||||||||
1334 | printf("%c", cmd[pos]); | |||||||||
1335 | } | |||||||||
1336 | printf(" "); | |||||||||
1337 | SetConsoleCursorPosition(hOut, position); | |||||||||
1338 | } | |||||||||
1339 | } | |||||||||
1340 | for (iBuf = 0; iBuf < len; iBuf++) { | |||||||||
1341 | switch (addchars[iBuf]) { | |||||||||
1342 | case '\r': | |||||||||
1343 | case '\n': | |||||||||
1344 | if (ignoreNext) { | |||||||||
1345 | ignoreNext = 0; | |||||||||
1346 | } else { | |||||||||
1347 | int ret = iCmdBuffer; | |||||||||
1348 | if (iCmdBuffer == 0) { | |||||||||
1349 | strcpy(cmd, "Empty"); | |||||||||
1350 | ret = (int) strlen(cmd); | |||||||||
1351 | } else { | |||||||||
1352 | console_history(cmd, 0); | |||||||||
1353 | cmd[iCmdBuffer] = 0; | |||||||||
1354 | } | |||||||||
1355 | iCmdBuffer = 0; | |||||||||
1356 | iCmdCursor = 0; | |||||||||
1357 | printf("\n"); | |||||||||
1358 | return (ret); | |||||||||
1359 | } | |||||||||
1360 | break; | |||||||||
1361 | case '\b': | |||||||||
1362 | if (iCmdCursor) { | |||||||||
1363 | if (position.X == 0) { | |||||||||
1364 | position.Y -= 1; | |||||||||
1365 | position.X = info.dwSize.X - 1; | |||||||||
1366 | SetConsoleCursorPosition(hOut, position); | |||||||||
1367 | } else { | |||||||||
1368 | position.X -= 1; | |||||||||
1369 | SetConsoleCursorPosition(hOut, position); | |||||||||
1370 | } | |||||||||
1371 | printf(" "); | |||||||||
1372 | if (iCmdCursor < iCmdBuffer) { | |||||||||
1373 | int pos; | |||||||||
1374 | iCmdCursor--; | |||||||||
1375 | for (pos = iCmdCursor; pos < iCmdBuffer; pos++) { | |||||||||
1376 | cmd[pos] = cmd[pos + 1]; | |||||||||
1377 | } | |||||||||
1378 | cmd[pos] = 0; | |||||||||
1379 | iCmdBuffer--; | |||||||||
1380 | ||||||||||
1381 | SetConsoleCursorPosition(hOut, position); | |||||||||
1382 | for (pos = iCmdCursor; pos < iCmdBuffer; pos++) { | |||||||||
1383 | printf("%c", cmd[pos]); | |||||||||
1384 | } | |||||||||
1385 | printf(" "); | |||||||||
1386 | SetConsoleCursorPosition(hOut, position); | |||||||||
1387 | } else { | |||||||||
1388 | SetConsoleCursorPosition(hOut, position); | |||||||||
1389 | iCmdBuffer--; | |||||||||
1390 | iCmdCursor--; | |||||||||
1391 | cmd[iCmdBuffer] = 0; | |||||||||
1392 | } | |||||||||
1393 | } | |||||||||
1394 | break; | |||||||||
1395 | default: | |||||||||
1396 | if (!ignoreNext) { | |||||||||
1397 | if (iCmdCursor < iCmdBuffer) { | |||||||||
1398 | int pos; | |||||||||
1399 | ||||||||||
1400 | if (position.X == info.dwSize.X - 1) { | |||||||||
1401 | position.Y += 1; | |||||||||
1402 | position.X = 0; | |||||||||
1403 | } else { | |||||||||
1404 | position.X += 1; | |||||||||
1405 | } | |||||||||
1406 | ||||||||||
1407 | if (insertMode) { | |||||||||
1408 | for (pos = iCmdBuffer - 1; pos >= iCmdCursor; pos--) { | |||||||||
1409 | cmd[pos + 1] = cmd[pos]; | |||||||||
1410 | } | |||||||||
1411 | } | |||||||||
1412 | iCmdBuffer++; | |||||||||
1413 | cmd[iCmdCursor++] = addchars[iBuf]; | |||||||||
1414 | printf("%c", addchars[iBuf]); | |||||||||
1415 | for (pos = iCmdCursor; pos < iCmdBuffer; pos++) { | |||||||||
1416 | GetConsoleScreenBufferInfo(hOut, &info); | |||||||||
1417 | if (info.dwCursorPosition.X == info.dwSize.X - 1 && info.dwCursorPosition.Y == info.dwSize.Y - 1) { | |||||||||
1418 | orgPosition.Y -= 1; | |||||||||
1419 | position.Y -= 1; | |||||||||
1420 | } | |||||||||
1421 | printf("%c", cmd[pos]); | |||||||||
1422 | } | |||||||||
1423 | SetConsoleCursorPosition(hOut, position); | |||||||||
1424 | } else { | |||||||||
1425 | if (position.X == info.dwSize.X - 1 && position.Y == info.dwSize.Y - 1) { | |||||||||
1426 | orgPosition.Y -= 1; | |||||||||
1427 | } | |||||||||
1428 | cmd[iCmdBuffer++] = addchars[iBuf]; | |||||||||
1429 | iCmdCursor++; | |||||||||
1430 | printf("%c", addchars[iBuf]); | |||||||||
1431 | } | |||||||||
1432 | } | |||||||||
1433 | } | |||||||||
1434 | if (iCmdBuffer == CMD_BUFLEN1024) { | |||||||||
1435 | printf("Read Console... BUFFER OVERRUN\n"); | |||||||||
1436 | iCmdBuffer = 0; | |||||||||
1437 | ignoreNext = 1; | |||||||||
1438 | } | |||||||||
1439 | } | |||||||||
1440 | return (SWITCH_STATUS_SUCCESS); | |||||||||
1441 | } | |||||||||
1442 | ||||||||||
1443 | ||||||||||
1444 | static BOOL console_readConsole(HANDLE conIn, char *buf, int len, int *pRed, int *key) | |||||||||
1445 | { | |||||||||
1446 | DWORD recordIndex, bufferIndex, toRead = 0, red; | |||||||||
1447 | PINPUT_RECORD pInput; | |||||||||
1448 | ||||||||||
1449 | GetNumberOfConsoleInputEvents(conIn, &toRead); | |||||||||
1450 | if (len < (int) toRead) { | |||||||||
1451 | toRead = len; | |||||||||
1452 | } | |||||||||
1453 | if (toRead == 0) { | |||||||||
1454 | return (FALSE0); | |||||||||
1455 | } | |||||||||
1456 | ||||||||||
1457 | if ((pInput = (PINPUT_RECORD) malloc(toRead * sizeof(INPUT_RECORD))) == NULL((void*)0)) { | |||||||||
1458 | return (FALSE0); | |||||||||
1459 | } | |||||||||
1460 | *key = 0; | |||||||||
1461 | ReadConsoleInput(conIn, pInput, toRead, &red); | |||||||||
1462 | ||||||||||
1463 | for (recordIndex = bufferIndex = 0; recordIndex < red; recordIndex++) { | |||||||||
1464 | KEY_EVENT_RECORD keyEvent = pInput[recordIndex].Event.KeyEvent; | |||||||||
1465 | if (pInput[recordIndex].EventType == KEY_EVENT && keyEvent.bKeyDown) { | |||||||||
1466 | if (keyEvent.wVirtualKeyCode == 38 && keyEvent.wVirtualScanCode == 72) { | |||||||||
1467 | buf[0] = 0; | |||||||||
1468 | console_history(buf, -1); | |||||||||
1469 | *key = KEY_UP; | |||||||||
1470 | bufferIndex += (DWORD) strlen(buf); | |||||||||
1471 | } | |||||||||
1472 | if (keyEvent.wVirtualKeyCode == 40 && keyEvent.wVirtualScanCode == 80) { | |||||||||
1473 | buf[0] = 0; | |||||||||
1474 | console_history(buf, 1); | |||||||||
1475 | *key = KEY_DOWN; | |||||||||
1476 | bufferIndex += (DWORD) strlen(buf); | |||||||||
1477 | } | |||||||||
1478 | if (keyEvent.wVirtualKeyCode == 112 && keyEvent.wVirtualScanCode == 59) { | |||||||||
1479 | console_fnkey_pressed(1); | |||||||||
1480 | } | |||||||||
1481 | if (keyEvent.wVirtualKeyCode == 113 && keyEvent.wVirtualScanCode == 60) { | |||||||||
1482 | console_fnkey_pressed(2); | |||||||||
1483 | } | |||||||||
1484 | if (keyEvent.wVirtualKeyCode == 114 && keyEvent.wVirtualScanCode == 61) { | |||||||||
1485 | console_fnkey_pressed(3); | |||||||||
1486 | } | |||||||||
1487 | if (keyEvent.wVirtualKeyCode == 115 && keyEvent.wVirtualScanCode == 62) { | |||||||||
1488 | console_fnkey_pressed(4); | |||||||||
1489 | } | |||||||||
1490 | if (keyEvent.wVirtualKeyCode == 116 && keyEvent.wVirtualScanCode == 63) { | |||||||||
1491 | console_fnkey_pressed(5); | |||||||||
1492 | } | |||||||||
1493 | if (keyEvent.wVirtualKeyCode == 117 && keyEvent.wVirtualScanCode == 64) { | |||||||||
1494 | console_fnkey_pressed(6); | |||||||||
1495 | } | |||||||||
1496 | if (keyEvent.wVirtualKeyCode == 118 && keyEvent.wVirtualScanCode == 65) { | |||||||||
1497 | console_fnkey_pressed(7); | |||||||||
1498 | } | |||||||||
1499 | if (keyEvent.wVirtualKeyCode == 119 && keyEvent.wVirtualScanCode == 66) { | |||||||||
1500 | console_fnkey_pressed(8); | |||||||||
1501 | } | |||||||||
1502 | if (keyEvent.wVirtualKeyCode == 120 && keyEvent.wVirtualScanCode == 67) { | |||||||||
1503 | console_fnkey_pressed(9); | |||||||||
1504 | } | |||||||||
1505 | if (keyEvent.wVirtualKeyCode == 121 && keyEvent.wVirtualScanCode == 68) { | |||||||||
1506 | console_fnkey_pressed(10); | |||||||||
1507 | } | |||||||||
1508 | if (keyEvent.wVirtualKeyCode == 122 && keyEvent.wVirtualScanCode == 87) { | |||||||||
1509 | console_fnkey_pressed(11); | |||||||||
1510 | } | |||||||||
1511 | if (keyEvent.wVirtualKeyCode == 123 && keyEvent.wVirtualScanCode == 88) { | |||||||||
1512 | console_fnkey_pressed(12); | |||||||||
1513 | } | |||||||||
1514 | if (keyEvent.uChar.AsciiChar == 9) { | |||||||||
1515 | *key = KEY_TAB; | |||||||||
1516 | break; | |||||||||
1517 | } | |||||||||
1518 | if (keyEvent.uChar.AsciiChar == 27) { | |||||||||
1519 | *key = CLEAR_OP; | |||||||||
1520 | break; | |||||||||
1521 | } | |||||||||
1522 | if (keyEvent.wVirtualKeyCode == 37 && keyEvent.wVirtualScanCode == 75) { | |||||||||
1523 | *key = KEY_LEFT; | |||||||||
1524 | } | |||||||||
1525 | if (keyEvent.wVirtualKeyCode == 39 && keyEvent.wVirtualScanCode == 77) { | |||||||||
1526 | *key = KEY_RIGHT; | |||||||||
1527 | } | |||||||||
1528 | if (keyEvent.wVirtualKeyCode == 45 && keyEvent.wVirtualScanCode == 82) { | |||||||||
1529 | *key = KEY_INSERT; | |||||||||
1530 | } | |||||||||
1531 | if (keyEvent.wVirtualKeyCode == 46 && keyEvent.wVirtualScanCode == 83) { | |||||||||
1532 | *key = KEY_DELETE; | |||||||||
1533 | } | |||||||||
1534 | while (keyEvent.wRepeatCount && keyEvent.uChar.AsciiChar) { | |||||||||
1535 | buf[bufferIndex] = keyEvent.uChar.AsciiChar; | |||||||||
1536 | if (buf[bufferIndex] == '\r') { | |||||||||
1537 | buf[bufferIndex] = '\n'; | |||||||||
1538 | } | |||||||||
1539 | bufferIndex++; | |||||||||
1540 | keyEvent.wRepeatCount--; | |||||||||
1541 | } | |||||||||
1542 | } | |||||||||
1543 | } | |||||||||
1544 | ||||||||||
1545 | free(pInput); | |||||||||
1546 | *pRed = bufferIndex; | |||||||||
1547 | return (TRUE(!0)); | |||||||||
1548 | } | |||||||||
1549 | #endif | |||||||||
1550 | ||||||||||
1551 | ||||||||||
1552 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_console_loop(void) | |||||||||
1553 | { | |||||||||
1554 | char cmd[CMD_BUFLEN1024 + 1] = ""; | |||||||||
1555 | int32_t activity = 1; | |||||||||
1556 | #ifndef _MSC_VER | |||||||||
1557 | int x = 0; | |||||||||
1558 | #else | |||||||||
1559 | char keys[CMD_BUFLEN1024]; | |||||||||
1560 | #endif | |||||||||
1561 | ||||||||||
1562 | /* Load/Init the config first */ | |||||||||
1563 | console_xml_config(); | |||||||||
1564 | ||||||||||
1565 | #ifdef _MSC_VER | |||||||||
1566 | sprintf(cmd, "\nfreeswitch@%s> ", switch_core_get_switchname()); | |||||||||
1567 | console_bufferInput(0, 0, cmd, PROMPT_OP); | |||||||||
1568 | memset(cmd, 0, sizeof(cmd)); | |||||||||
1569 | #endif | |||||||||
1570 | ||||||||||
1571 | while (running) { | |||||||||
1572 | int32_t arg; | |||||||||
1573 | #ifdef _MSC_VER | |||||||||
1574 | int read, key; | |||||||||
1575 | HANDLE stdinHandle = GetStdHandle(STD_INPUT_HANDLE); | |||||||||
1576 | #else | |||||||||
1577 | fd_set rfds, efds; | |||||||||
1578 | struct timeval tv = { 0, 20000 }; | |||||||||
1579 | #endif | |||||||||
1580 | ||||||||||
1581 | switch_core_session_ctl(SCSC_CHECK_RUNNING, &arg); | |||||||||
1582 | if (!arg) { | |||||||||
1583 | break; | |||||||||
1584 | } | |||||||||
1585 | ||||||||||
1586 | if (activity) { | |||||||||
1587 | switch_log_printf(SWITCH_CHANNEL_LOG_CLEANSWITCH_CHANNEL_ID_LOG_CLEAN, "src/switch_console.c", (const char *)__func__, 1587, ((void*)0), SWITCH_LOG_CONSOLE, "\nfreeswitch@%s> ", switch_core_get_switchname()); | |||||||||
1588 | } | |||||||||
1589 | #ifdef _MSC_VER | |||||||||
1590 | activity = 0; | |||||||||
1591 | if (console_readConsole(stdinHandle, keys, (int) sizeof(keys), &read, &key)) { | |||||||||
1592 | if (console_bufferInput(keys, read, cmd, key)) { | |||||||||
1593 | if (!strcmp(cmd, "Empty")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (cmd) && __builtin_constant_p ("Empty") && ( __s1_len = __builtin_strlen (cmd), __s2_len = __builtin_strlen ("Empty"), (!((size_t)(const void *)((cmd) + 1) - (size_t)(const void *)(cmd) == 1) || __s1_len >= 4) && (!((size_t )(const void *)(("Empty") + 1) - (size_t)(const void *)("Empty" ) == 1) || __s2_len >= 4)) ? __builtin_strcmp (cmd, "Empty" ) : (__builtin_constant_p (cmd) && ((size_t)(const void *)((cmd) + 1) - (size_t)(const void *)(cmd) == 1) && (__s1_len = __builtin_strlen (cmd), __s1_len < 4) ? (__builtin_constant_p ("Empty") && ((size_t)(const void *)(("Empty") + 1) - (size_t)(const void *)("Empty") == 1) ? __builtin_strcmp (cmd , "Empty") : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) ("Empty"); int __result = (( (const unsigned char *) (const char *) (cmd))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (cmd))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (cmd))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (cmd))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p ("Empty") && ((size_t)(const void *)(("Empty") + 1) - (size_t)(const void *)("Empty") == 1) && (__s2_len = __builtin_strlen ("Empty"), __s2_len < 4) ? ( __builtin_constant_p (cmd) && ((size_t)(const void *) ((cmd) + 1) - (size_t)(const void *)(cmd) == 1) ? __builtin_strcmp (cmd, "Empty") : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (cmd); int __result = (((const unsigned char *) (const char *) ("Empty"))[0] - __s2 [0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ("Empty"))[1] - __s2 [1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) ("Empty"))[2] - __s2 [2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ("Empty"))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (cmd, "Empty"))) ); })) { | |||||||||
1594 | cmd[0] = 0; | |||||||||
1595 | } | |||||||||
1596 | activity = 1; | |||||||||
1597 | if (cmd[0]) { | |||||||||
1598 | running = switch_console_process(cmd); | |||||||||
1599 | } | |||||||||
1600 | memset(cmd, 0, sizeof(cmd)); | |||||||||
1601 | } | |||||||||
1602 | } | |||||||||
1603 | Sleep(20); | |||||||||
1604 | #else | |||||||||
1605 | FD_ZERO(&rfds)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&rfds)->fds_bits)[0] ) : "memory"); } while (0); | |||||||||
1606 | FD_ZERO(&efds)do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&efds)->fds_bits)[0] ) : "memory"); } while (0); | |||||||||
1607 | FD_SET(fileno(stdin), &rfds)((void) (((&rfds)->fds_bits)[((fileno(stdin)) / (8 * ( int) sizeof (__fd_mask)))] |= ((__fd_mask) 1 << ((fileno (stdin)) % (8 * (int) sizeof (__fd_mask)))))); | |||||||||
1608 | FD_SET(fileno(stdin), &efds)((void) (((&efds)->fds_bits)[((fileno(stdin)) / (8 * ( int) sizeof (__fd_mask)))] |= ((__fd_mask) 1 << ((fileno (stdin)) % (8 * (int) sizeof (__fd_mask)))))); | |||||||||
1609 | if ((activity = select(fileno(stdinstdin) + 1, &rfds, NULL((void*)0), &efds, &tv)) < 0) { | |||||||||
1610 | break; | |||||||||
1611 | } | |||||||||
1612 | ||||||||||
1613 | if (FD_ISSET(fileno(stdin), &efds)((((&efds)->fds_bits)[((fileno(stdin)) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) 1 << ((fileno(stdin) ) % (8 * (int) sizeof (__fd_mask))))) != 0)) { | |||||||||
1614 | continue; | |||||||||
1615 | } | |||||||||
1616 | ||||||||||
1617 | if (!FD_ISSET(fileno(stdin), &rfds)((((&rfds)->fds_bits)[((fileno(stdin)) / (8 * (int) sizeof (__fd_mask)))] & ((__fd_mask) 1 << ((fileno(stdin) ) % (8 * (int) sizeof (__fd_mask))))) != 0)) { | |||||||||
1618 | activity = 0; | |||||||||
1619 | } | |||||||||
1620 | ||||||||||
1621 | if (activity == 0) { | |||||||||
1622 | fflush(stdoutstdout); | |||||||||
1623 | continue; | |||||||||
1624 | } | |||||||||
1625 | ||||||||||
1626 | memset(&cmd, 0, sizeof(cmd)); | |||||||||
1627 | for (x = 0; x < (sizeof(cmd) - 1); x++) { | |||||||||
1628 | int c = getchar(); | |||||||||
1629 | if (c < 0) { | |||||||||
1630 | int y = read(fileno(stdinstdin), cmd, sizeof(cmd) - 1); | |||||||||
1631 | cmd[y - 1] = '\0'; | |||||||||
1632 | break; | |||||||||
1633 | } | |||||||||
1634 | ||||||||||
1635 | cmd[x] = (char) c; | |||||||||
1636 | ||||||||||
1637 | if (cmd[x] == '\n') { | |||||||||
1638 | cmd[x] = '\0'; | |||||||||
1639 | break; | |||||||||
1640 | } | |||||||||
1641 | } | |||||||||
1642 | ||||||||||
1643 | if (cmd[0]) { | |||||||||
1644 | running = switch_console_process(cmd); | |||||||||
1645 | } | |||||||||
1646 | #endif | |||||||||
1647 | } | |||||||||
1648 | } | |||||||||
1649 | ||||||||||
1650 | ||||||||||
1651 | ||||||||||
1652 | #endif | |||||||||
1653 | ||||||||||
1654 | ||||||||||
1655 | static struct { | |||||||||
1656 | switch_hash_t *func_hash; | |||||||||
1657 | switch_mutex_t *func_mutex; | |||||||||
1658 | } globals; | |||||||||
1659 | ||||||||||
1660 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_console_init(switch_memory_pool_t *pool) | |||||||||
1661 | { | |||||||||
1662 | switch_mutex_init(&globals.func_mutex, SWITCH_MUTEX_NESTED0x1, pool); | |||||||||
1663 | switch_core_hash_init(&globals.func_hash)switch_core_hash_init_case(&globals.func_hash, SWITCH_TRUE ); | |||||||||
1664 | switch_console_add_complete_func("::console::list_available_modules", (switch_console_complete_callback_t) switch_console_list_available_modules); | |||||||||
1665 | switch_console_add_complete_func("::console::list_loaded_modules", (switch_console_complete_callback_t) switch_console_list_loaded_modules); | |||||||||
1666 | switch_console_add_complete_func("::console::list_interfaces", (switch_console_complete_callback_t) switch_console_list_interfaces); | |||||||||
1667 | switch_console_add_complete_func("::console::list_uuid", (switch_console_complete_callback_t) switch_console_list_uuid); | |||||||||
1668 | return SWITCH_STATUS_SUCCESS; | |||||||||
1669 | } | |||||||||
1670 | ||||||||||
1671 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_console_shutdown(void) | |||||||||
1672 | { | |||||||||
1673 | return switch_core_hash_destroy(&globals.func_hash); | |||||||||
1674 | } | |||||||||
1675 | ||||||||||
1676 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_console_add_complete_func(const char *name, switch_console_complete_callback_t cb) | |||||||||
1677 | { | |||||||||
1678 | switch_status_t status; | |||||||||
1679 | ||||||||||
1680 | switch_mutex_lock(globals.func_mutex); | |||||||||
1681 | status = switch_core_hash_insert(globals.func_hash, name, (void *) (intptr_t) cb)switch_core_hash_insert_destructor(globals.func_hash, name, ( void *) (intptr_t) cb, ((void*)0)); | |||||||||
1682 | switch_mutex_unlock(globals.func_mutex); | |||||||||
1683 | ||||||||||
1684 | return status; | |||||||||
1685 | } | |||||||||
1686 | ||||||||||
1687 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_console_del_complete_func(const char *name) | |||||||||
1688 | { | |||||||||
1689 | switch_status_t status; | |||||||||
1690 | ||||||||||
1691 | switch_mutex_lock(globals.func_mutex); | |||||||||
1692 | status = switch_core_hash_insert(globals.func_hash, name, NULL)switch_core_hash_insert_destructor(globals.func_hash, name, ( (void*)0), ((void*)0)); | |||||||||
1693 | switch_mutex_unlock(globals.func_mutex); | |||||||||
1694 | ||||||||||
1695 | return status; | |||||||||
1696 | } | |||||||||
1697 | ||||||||||
1698 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_console_free_matches(switch_console_callback_match_t **matches) | |||||||||
1699 | { | |||||||||
1700 | switch_console_callback_match_t *my_match = *matches; | |||||||||
1701 | switch_console_callback_match_node_t *m, *cur; | |||||||||
1702 | ||||||||||
1703 | /* Don't play with matches */ | |||||||||
1704 | *matches = NULL((void*)0); | |||||||||
1705 | ||||||||||
1706 | m = my_match->head; | |||||||||
1707 | while (m) { | |||||||||
1708 | cur = m; | |||||||||
1709 | m = m->next; | |||||||||
1710 | free(cur->val); | |||||||||
1711 | free(cur); | |||||||||
1712 | } | |||||||||
1713 | ||||||||||
1714 | if (my_match->dynamic) { | |||||||||
1715 | free(my_match); | |||||||||
1716 | } | |||||||||
1717 | } | |||||||||
1718 | ||||||||||
1719 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_console_sort_matches(switch_console_callback_match_t *matches) | |||||||||
1720 | { | |||||||||
1721 | switch_console_callback_match_node_t *p = NULL((void*)0), *sort[4] = { 0 }; | |||||||||
1722 | int i, j; | |||||||||
1723 | ||||||||||
1724 | switch_assert(matches)((matches) ? (void) (0) : __assert_fail ("matches", "src/switch_console.c" , 1724, __PRETTY_FUNCTION__)); | |||||||||
1725 | ||||||||||
1726 | if (matches->count < 2) { | |||||||||
1727 | return; | |||||||||
1728 | } | |||||||||
1729 | ||||||||||
1730 | for (i = 1; i < matches->count; i++) { | |||||||||
1731 | sort[0] = NULL((void*)0); | |||||||||
1732 | sort[1] = matches->head; | |||||||||
1733 | sort[2] = sort[1] ? sort[1]->next : NULL((void*)0); | |||||||||
1734 | sort[3] = sort[2] ? sort[2]->next : NULL((void*)0); | |||||||||
1735 | ||||||||||
1736 | for (j = 1; j <= (matches->count - i); j++) { | |||||||||
1737 | switch_assert(sort[1] && sort[2])((sort[1] && sort[2]) ? (void) (0) : __assert_fail ("sort[1] && sort[2]" , "src/switch_console.c", 1737, __PRETTY_FUNCTION__)); | |||||||||
1738 | if (strcmp(sort[1]->val, sort[2]->val)__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (sort[1]->val) && __builtin_constant_p (sort[2]-> val) && (__s1_len = __builtin_strlen (sort[1]->val ), __s2_len = __builtin_strlen (sort[2]->val), (!((size_t) (const void *)((sort[1]->val) + 1) - (size_t)(const void * )(sort[1]->val) == 1) || __s1_len >= 4) && (!(( size_t)(const void *)((sort[2]->val) + 1) - (size_t)(const void *)(sort[2]->val) == 1) || __s2_len >= 4)) ? __builtin_strcmp (sort[1]->val, sort[2]->val) : (__builtin_constant_p ( sort[1]->val) && ((size_t)(const void *)((sort[1]-> val) + 1) - (size_t)(const void *)(sort[1]->val) == 1) && (__s1_len = __builtin_strlen (sort[1]->val), __s1_len < 4) ? (__builtin_constant_p (sort[2]->val) && ((size_t )(const void *)((sort[2]->val) + 1) - (size_t)(const void * )(sort[2]->val) == 1) ? __builtin_strcmp (sort[1]->val, sort[2]->val) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (sort[2]->val); int __result = (((const unsigned char *) (const char *) (sort[1] ->val))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) ( sort[1]->val))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (sort[1]->val))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char * ) (const char *) (sort[1]->val))[3] - __s2[3]); } } __result ; }))) : (__builtin_constant_p (sort[2]->val) && ( (size_t)(const void *)((sort[2]->val) + 1) - (size_t)(const void *)(sort[2]->val) == 1) && (__s2_len = __builtin_strlen (sort[2]->val), __s2_len < 4) ? (__builtin_constant_p ( sort[1]->val) && ((size_t)(const void *)((sort[1]-> val) + 1) - (size_t)(const void *)(sort[1]->val) == 1) ? __builtin_strcmp (sort[1]->val, sort[2]->val) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (sort[1]->val); int __result = (((const unsigned char *) ( const char *) (sort[2]->val))[0] - __s2[0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (sort[2]->val))[1] - __s2[1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (sort[2]->val))[2] - __s2[2]); if ( __s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (sort[2]->val))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (sort[1]->val , sort[2]->val)))); }) > 0) { | |||||||||
1739 | sort[1]->next = sort[3]; | |||||||||
1740 | sort[2]->next = sort[1]; | |||||||||
1741 | ||||||||||
1742 | if (sort[0]) | |||||||||
1743 | sort[0]->next = sort[2]; | |||||||||
1744 | if (sort[1] == matches->head) | |||||||||
1745 | matches->head = sort[2]; | |||||||||
1746 | ||||||||||
1747 | ||||||||||
1748 | ||||||||||
1749 | ||||||||||
1750 | sort[0] = sort[2]; | |||||||||
1751 | sort[2] = sort[1]->next; | |||||||||
1752 | if (sort[3] && sort[3]->next) | |||||||||
1753 | sort[3] = sort[3]->next; | |||||||||
1754 | ||||||||||
1755 | } else { | |||||||||
1756 | sort[0] = sort[1]; | |||||||||
1757 | sort[1] = sort[2]; | |||||||||
1758 | sort[2] = sort[3]; | |||||||||
1759 | if (sort[3] && sort[3]->next) | |||||||||
1760 | sort[3] = sort[3]->next; | |||||||||
1761 | } | |||||||||
1762 | ||||||||||
1763 | } | |||||||||
1764 | } | |||||||||
1765 | ||||||||||
1766 | p = matches->head; | |||||||||
1767 | ||||||||||
1768 | for (i = 1; i < matches->count; i++) | |||||||||
1769 | p = p->next; | |||||||||
1770 | ||||||||||
1771 | if (p) { | |||||||||
1772 | p->next = NULL((void*)0); | |||||||||
1773 | matches->end = p; | |||||||||
1774 | } | |||||||||
1775 | } | |||||||||
1776 | ||||||||||
1777 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_console_push_match_unique(switch_console_callback_match_t **matches, const char *new_val) | |||||||||
1778 | { | |||||||||
1779 | /* Ignore the entry if it is already in the list */ | |||||||||
1780 | if (*matches) { | |||||||||
1781 | switch_console_callback_match_node_t *node; | |||||||||
1782 | ||||||||||
1783 | for(node = (*matches)->head; node; node = node->next) { | |||||||||
1784 | if (!strcasecmp(node->val, new_val)) return; | |||||||||
1785 | } | |||||||||
1786 | } | |||||||||
1787 | ||||||||||
1788 | switch_console_push_match(matches, new_val); | |||||||||
1789 | } | |||||||||
1790 | ||||||||||
1791 | SWITCH_DECLARE(void)__attribute__((visibility("default"))) void switch_console_push_match(switch_console_callback_match_t **matches, const char *new_val) | |||||||||
1792 | { | |||||||||
1793 | switch_console_callback_match_node_t *match; | |||||||||
1794 | ||||||||||
1795 | if (!*matches) { | |||||||||
1796 | switch_zmalloc(*matches, sizeof(**matches))(void)((((*matches = calloc(1, (sizeof(**matches))))) ? (void ) (0) : __assert_fail ("(*matches = calloc(1, (sizeof(**matches))))" , "src/switch_console.c", 1796, __PRETTY_FUNCTION__)),*matches ); | |||||||||
1797 | (*matches)->dynamic = 1; | |||||||||
1798 | } | |||||||||
1799 | ||||||||||
1800 | switch_zmalloc(match, sizeof(*match))(void)((((match = calloc(1, (sizeof(*match))))) ? (void) (0) : __assert_fail ("(match = calloc(1, (sizeof(*match))))", "src/switch_console.c" , 1800, __PRETTY_FUNCTION__)),match); | |||||||||
1801 | match->val = strdup(new_val)(__extension__ (__builtin_constant_p (new_val) && ((size_t )(const void *)((new_val) + 1) - (size_t)(const void *)(new_val ) == 1) ? (((const char *) (new_val))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (new_val ) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, new_val , __len); __retval; })) : __strdup (new_val))); | |||||||||
1802 | ||||||||||
1803 | if ((*matches)->head) { | |||||||||
1804 | (*matches)->end->next = match; | |||||||||
1805 | } else { | |||||||||
1806 | (*matches)->head = match; | |||||||||
1807 | } | |||||||||
1808 | ||||||||||
1809 | (*matches)->count++; | |||||||||
1810 | ||||||||||
1811 | (*matches)->end = match; | |||||||||
1812 | } | |||||||||
1813 | ||||||||||
1814 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_console_run_complete_func(const char *func, const char *line, const char *last_word, | |||||||||
1815 | switch_console_callback_match_t **matches) | |||||||||
1816 | { | |||||||||
1817 | switch_console_complete_callback_t cb; | |||||||||
1818 | switch_status_t status = SWITCH_STATUS_FALSE; | |||||||||
1819 | ||||||||||
1820 | switch_mutex_lock(globals.func_mutex); | |||||||||
1821 | if ((cb = (switch_console_complete_callback_t) (intptr_t) switch_core_hash_find(globals.func_hash, func))) { | |||||||||
1822 | if ((status = cb(line, last_word, matches)) == SWITCH_STATUS_SUCCESS) { | |||||||||
1823 | switch_console_sort_matches(*matches); | |||||||||
1824 | } | |||||||||
1825 | } | |||||||||
1826 | switch_mutex_unlock(globals.func_mutex); | |||||||||
1827 | ||||||||||
1828 | return status; | |||||||||
1829 | } | |||||||||
1830 | ||||||||||
1831 | ||||||||||
1832 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_console_set_complete(const char *string) | |||||||||
1833 | { | |||||||||
1834 | char *mydata = NULL((void*)0), *argv[11] = { 0 }; | |||||||||
1835 | int argc, x; | |||||||||
1836 | switch_status_t status = SWITCH_STATUS_FALSE; | |||||||||
1837 | switch_core_flag_t cflags = switch_core_flags(); | |||||||||
1838 | ||||||||||
1839 | if (!(cflags & SCF_USE_SQL)) { | |||||||||
1840 | return SWITCH_STATUS_FALSE; | |||||||||
1841 | } | |||||||||
1842 | ||||||||||
1843 | if (string && (mydata = strdup(string)(__extension__ (__builtin_constant_p (string) && ((size_t )(const void *)((string) + 1) - (size_t)(const void *)(string ) == 1) ? (((const char *) (string))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (string) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, string, __len ); __retval; })) : __strdup (string))))) { | |||||||||
1844 | if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0]))))) { | |||||||||
1845 | switch_stream_handle_t mystream = { 0 }; | |||||||||
1846 | SWITCH_STANDARD_STREAM(mystream)memset(&mystream, 0, sizeof(mystream)); mystream.data = malloc (1024); ((mystream.data) ? (void) (0) : __assert_fail ("mystream.data" , "src/switch_console.c", 1846, __PRETTY_FUNCTION__)); memset (mystream.data, 0, 1024); mystream.end = mystream.data; mystream .data_size = 1024; mystream.write_function = switch_console_stream_write ; mystream.raw_write_function = switch_console_stream_raw_write ; mystream.alloc_len = 1024; mystream.alloc_chunk = 1024; | |||||||||
1847 | ||||||||||
1848 | if (!strcasecmp(argv[0], "stickyadd")) { | |||||||||
1849 | mystream.write_function(&mystream, "insert into complete values (1,"); | |||||||||
1850 | for (x = 0; x < 10; x++) { | |||||||||
1851 | if (argv[x + 1] && !strcasecmp(argv[x + 1], "_any_")) { | |||||||||
1852 | mystream.write_function(&mystream, "%s", "'', "); | |||||||||
1853 | } else { | |||||||||
1854 | if (switch_core_dbtype() == SCDB_TYPE_CORE_DB) { | |||||||||
1855 | mystream.write_function(&mystream, "'%q', ", switch_str_nil(argv[x + 1])(argv[x + 1] ? argv[x + 1] : "")); | |||||||||
1856 | } else { | |||||||||
1857 | mystream.write_function(&mystream, "'%w', ", switch_str_nil(argv[x + 1])(argv[x + 1] ? argv[x + 1] : "")); | |||||||||
1858 | } | |||||||||
1859 | } | |||||||||
1860 | } | |||||||||
1861 | mystream.write_function(&mystream, " '%s')", switch_core_get_hostname()); | |||||||||
1862 | switch_core_sql_exec(mystream.data); | |||||||||
1863 | status = SWITCH_STATUS_SUCCESS; | |||||||||
1864 | } else if (!strcasecmp(argv[0], "add")) { | |||||||||
1865 | mystream.write_function(&mystream, "insert into complete values (0,"); | |||||||||
1866 | for (x = 0; x < 10; x++) { | |||||||||
1867 | if (argv[x + 1] && !strcasecmp(argv[x + 1], "_any_")) { | |||||||||
1868 | mystream.write_function(&mystream, "%s", "'', "); | |||||||||
1869 | } else { | |||||||||
1870 | if (switch_core_dbtype() == SCDB_TYPE_CORE_DB) { | |||||||||
1871 | mystream.write_function(&mystream, "'%q', ", switch_str_nil(argv[x + 1])(argv[x + 1] ? argv[x + 1] : "")); | |||||||||
1872 | } else { | |||||||||
1873 | mystream.write_function(&mystream, "'%w', ", switch_str_nil(argv[x + 1])(argv[x + 1] ? argv[x + 1] : "")); | |||||||||
1874 | } | |||||||||
1875 | } | |||||||||
1876 | } | |||||||||
1877 | mystream.write_function(&mystream, " '%s')", switch_core_get_hostname()); | |||||||||
1878 | ||||||||||
1879 | switch_core_sql_exec(mystream.data); | |||||||||
1880 | status = SWITCH_STATUS_SUCCESS; | |||||||||
1881 | } else if (!strcasecmp(argv[0], "del")) { | |||||||||
1882 | char *what = argv[1]; | |||||||||
1883 | if (zstr(what)_zstr(what)) { | |||||||||
1884 | switch_safe_free(mystream.data)if (mystream.data) {free(mystream.data);mystream.data=((void* )0);}; | |||||||||
1885 | switch_safe_free(mydata)if (mydata) {free(mydata);mydata=((void*)0);}; | |||||||||
1886 | return SWITCH_STATUS_FALSE; | |||||||||
1887 | } else if (!strcasecmp(what, "*")) { | |||||||||
1888 | mystream.write_function(&mystream, "delete from complete where hostname='%s'", switch_core_get_hostname()); | |||||||||
1889 | switch_core_sql_exec(mystream.data); | |||||||||
1890 | } else { | |||||||||
1891 | mystream.write_function(&mystream, "delete from complete where "); | |||||||||
1892 | for (x = 0; x < argc - 1; x++) { | |||||||||
1893 | if (switch_core_dbtype() == SCDB_TYPE_CORE_DB) { | |||||||||
1894 | mystream.write_function(&mystream, "a%d = '%q'%q", x + 1, switch_str_nil(argv[x + 1])(argv[x + 1] ? argv[x + 1] : ""), x == argc - 2 ? "" : " and "); | |||||||||
1895 | } else { | |||||||||
1896 | mystream.write_function(&mystream, "a%d = '%w'%w", x + 1, switch_str_nil(argv[x + 1])(argv[x + 1] ? argv[x + 1] : ""), x == argc - 2 ? "" : " and "); | |||||||||
1897 | } | |||||||||
1898 | } | |||||||||
1899 | mystream.write_function(&mystream, " and hostname='%s'", switch_core_get_hostname()); | |||||||||
1900 | switch_core_sql_exec(mystream.data); | |||||||||
1901 | } | |||||||||
1902 | status = SWITCH_STATUS_SUCCESS; | |||||||||
1903 | } | |||||||||
1904 | ||||||||||
1905 | switch_safe_free(mystream.data)if (mystream.data) {free(mystream.data);mystream.data=((void* )0);}; | |||||||||
1906 | } | |||||||||
1907 | } | |||||||||
1908 | ||||||||||
1909 | switch_safe_free(mydata)if (mydata) {free(mydata);mydata=((void*)0);}; | |||||||||
1910 | ||||||||||
1911 | return status; | |||||||||
1912 | ||||||||||
1913 | } | |||||||||
1914 | ||||||||||
1915 | ||||||||||
1916 | SWITCH_DECLARE(switch_status_t)__attribute__((visibility("default"))) switch_status_t switch_console_set_alias(const char *string) | |||||||||
1917 | { | |||||||||
1918 | char *mydata = NULL((void*)0), *argv[3] = { 0 }; | |||||||||
1919 | int argc; | |||||||||
1920 | switch_status_t status = SWITCH_STATUS_FALSE; | |||||||||
1921 | ||||||||||
1922 | if (string && (mydata = strdup(string)(__extension__ (__builtin_constant_p (string) && ((size_t )(const void *)((string) + 1) - (size_t)(const void *)(string ) == 1) ? (((const char *) (string))[0] == '\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (string) + 1; char *__retval = (char *) malloc (__len); if (__retval != ((void*)0)) __retval = (char *) memcpy (__retval, string, __len ); __retval; })) : __strdup (string))))) { | |||||||||
1923 | if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 2) { | |||||||||
1924 | switch_cache_db_handle_t *db = NULL((void*)0); | |||||||||
1925 | char *sql = NULL((void*)0); | |||||||||
1926 | ||||||||||
1927 | if (argc > 2 && !strcmp(argv[1], argv[2])__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p (argv[1]) && __builtin_constant_p (argv[2]) && (__s1_len = __builtin_strlen (argv[1]), __s2_len = __builtin_strlen (argv[2]), (!((size_t)(const void *)((argv[1]) + 1) - (size_t )(const void *)(argv[1]) == 1) || __s1_len >= 4) && (!((size_t)(const void *)((argv[2]) + 1) - (size_t)(const void *)(argv[2]) == 1) || __s2_len >= 4)) ? __builtin_strcmp ( argv[1], argv[2]) : (__builtin_constant_p (argv[1]) && ((size_t)(const void *)((argv[1]) + 1) - (size_t)(const void *)(argv[1]) == 1) && (__s1_len = __builtin_strlen (argv [1]), __s1_len < 4) ? (__builtin_constant_p (argv[2]) && ((size_t)(const void *)((argv[2]) + 1) - (size_t)(const void *)(argv[2]) == 1) ? __builtin_strcmp (argv[1], argv[2]) : (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (argv[2]); int __result = (((const unsigned char *) ( const char *) (argv[1]))[0] - __s2[0]); if (__s1_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (argv[1]))[1] - __s2[1]); if (__s1_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (argv[1]))[2] - __s2[2]); if (__s1_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (argv[1]))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p (argv[2]) && ((size_t)(const void *)((argv[2]) + 1) - (size_t)(const void *)(argv[2]) == 1) && (__s2_len = __builtin_strlen (argv[2]), __s2_len < 4) ? (__builtin_constant_p (argv[1]) && ((size_t)(const void *)((argv[1]) + 1) - (size_t)(const void *)(argv[1]) == 1) ? __builtin_strcmp (argv [1], argv[2]) : (- (__extension__ ({ const unsigned char *__s2 = (const unsigned char *) (const char *) (argv[1]); int __result = (((const unsigned char *) (const char *) (argv[2]))[0] - __s2 [0]); if (__s2_len > 0 && __result == 0) { __result = (((const unsigned char *) (const char *) (argv[2]))[1] - __s2 [1]); if (__s2_len > 1 && __result == 0) { __result = (((const unsigned char *) (const char *) (argv[2]))[2] - __s2 [2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) (argv[2]))[3] - __s2 [3]); } } __result; })))) : __builtin_strcmp (argv[1], argv[2 ])))); })) { | |||||||||
1928 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 1928, ((void*)0), SWITCH_LOG_ERROR, "Alias and command cannot be the same, this will cause loop!\n"); | |||||||||
1929 | return SWITCH_STATUS_FALSE; | |||||||||
1930 | } | |||||||||
1931 | ||||||||||
1932 | if (switch_core_db_handle(&db)_switch_core_db_handle(&db, "src/switch_console.c", (const char *)__func__, 1932) != SWITCH_STATUS_SUCCESS) { | |||||||||
1933 | switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "src/switch_console.c", (const char *) __func__, 1933, ((void*)0), SWITCH_LOG_ERROR, "Database Error\n"); | |||||||||
1934 | free(mydata); | |||||||||
1935 | return SWITCH_STATUS_FALSE; | |||||||||
1936 | } | |||||||||
1937 | ||||||||||
1938 | if (!strcasecmp(argv[0], "stickyadd") && argc == 3) { | |||||||||
1939 | sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_switchname()); | |||||||||
1940 | switch_cache_db_persistant_execute(db, sql, 5); | |||||||||
1941 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||||||||
1942 | if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) { | |||||||||
1943 | sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (1, '%q','%q','%q')", | |||||||||
1944 | argv[1], argv[2], switch_core_get_switchname()); | |||||||||
1945 | } else { | |||||||||
1946 | sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (1, '%w','%w','%w')", | |||||||||
1947 | argv[1], argv[2], switch_core_get_switchname()); | |||||||||
1948 | } | |||||||||
1949 | switch_cache_db_persistant_execute(db, sql, 5); | |||||||||
1950 | status = SWITCH_STATUS_SUCCESS; | |||||||||
1951 | } else if (!strcasecmp(argv[0], "add") && argc == 3) { | |||||||||
1952 | sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_switchname()); | |||||||||
1953 | switch_cache_db_persistant_execute(db, sql, 5); | |||||||||
1954 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||||||||
1955 | if (switch_cache_db_get_type(db) == SCDB_TYPE_CORE_DB) { | |||||||||
1956 | sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (0, '%q','%q','%q')", | |||||||||
1957 | argv[1], argv[2], switch_core_get_switchname()); | |||||||||
1958 | } else { | |||||||||
1959 | sql = switch_mprintf("insert into aliases (sticky, alias, command, hostname) values (0, '%w','%w','%w')", | |||||||||
1960 | argv[1], argv[2], switch_core_get_switchname()); | |||||||||
1961 | } | |||||||||
1962 | switch_cache_db_persistant_execute(db, sql, 5); | |||||||||
1963 | status = SWITCH_STATUS_SUCCESS; | |||||||||
1964 | } else if (!strcasecmp(argv[0], "del") && argc == 2) { | |||||||||
1965 | char *what = argv[1]; | |||||||||
1966 | if (!strcasecmp(what, "*")) { | |||||||||
1967 | sql = switch_mprintf("delete from aliases where hostname='%q'", switch_core_get_switchname()); | |||||||||
1968 | switch_cache_db_persistant_execute(db, sql, 1); | |||||||||
1969 | } else { | |||||||||
1970 | sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_switchname()); | |||||||||
1971 | switch_cache_db_persistant_execute(db, sql, 5); | |||||||||
1972 | } | |||||||||
1973 | status = SWITCH_STATUS_SUCCESS; | |||||||||
1974 | } | |||||||||
1975 | switch_safe_free(sql)if (sql) {free(sql);sql=((void*)0);}; | |||||||||
1976 | switch_cache_db_release_db_handle(&db); | |||||||||
1977 | } | |||||||||
1978 | } | |||||||||
1979 | ||||||||||
1980 | switch_safe_free(mydata)if (mydata) {free(mydata);mydata=((void*)0);}; | |||||||||
1981 | ||||||||||
1982 | return status; | |||||||||
1983 | ||||||||||
1984 | } | |||||||||
1985 | ||||||||||
1986 | ||||||||||
1987 | ||||||||||
1988 | ||||||||||
1989 | /* For Emacs: | |||||||||
1990 | * Local Variables: | |||||||||
1991 | * mode:c | |||||||||
1992 | * indent-tabs-mode:t | |||||||||
1993 | * tab-width:4 | |||||||||
1994 | * c-basic-offset:4 | |||||||||
1995 | * End: | |||||||||
1996 | * For VIM: | |||||||||
1997 | * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet: | |||||||||
1998 | */ |