| File: | src/switch_console.c |
| Location: | line 897, column 14 |
| 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 | */ |