FreeSWITCH API Documentation  1.7.0
switch_console.c
Go to the documentation of this file.
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_BUFLEN 1024
39 
40 #ifdef HAVE_LIBEDIT
41 #include <histedit.h>
42 
43 static EditLine *el;
44 static History *myhistory;
45 static HistEvent ev;
46 static char *hfile = NULL;
47 
48 #else
49 
50 #define CC_NORM 0
51 #define CC_NEWLINE 1
52 #define CC_EOF 2
53 #define CC_ARGHACK 3
54 #define CC_REFRESH 4
55 #define CC_CURSOR 5
56 #define CC_ERROR 6
57 #define CC_FATAL 7
58 #define CC_REDISPLAY 8
59 #define CC_REFRESH_BEEP 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  */
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;
100  }
101 
102  if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
103  switch_log_printf(SWITCH_CHANNEL_LOG, 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_LOG, 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 */
117  }
118  }
119  }
120 
121  switch_xml_free(xml);
122 
123  return SWITCH_STATUS_SUCCESS;
124 }
125 
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 
151 {
152  va_list ap;
153  char *buf = handle->data;
154  char *end = handle->end;
155  int ret = 0;
156  char *data = NULL;
157 
158  if (handle->data_len >= handle->data_size) {
159  return SWITCH_STATUS_FALSE;
160  }
161 
162  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);
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 {
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 
204 }
205 
207 {
208  char *dpath = NULL;
209  FILE *fd = NULL;
211 
212  if (!switch_is_file_path(path)) {
214  path = dpath;
215  }
216 
217  if ((fd = fopen(path, "r"))) {
218  char *line_buf = NULL;
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);
226  status = SWITCH_STATUS_SUCCESS;
227  }
228 
229  switch_safe_free(dpath);
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]);
237  return -1;
238 }
239 
240 SWITCH_DECLARE(char *) switch_console_expand_alias(char *cmd, char *arg)
241 {
242  char *errmsg = NULL;
243  char *r = NULL;
244  char *sql = NULL;
245  char *exp = NULL;
246  switch_cache_db_handle_t *db = NULL;
248  int full = 0;
249 
250 
251  if (!(cflags & SCF_USE_SQL)) {
252  return NULL;
253  }
254 
257  return NULL;
258  }
259 
260 
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 
268 
269  if (errmsg) {
270  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error [%s][%s]\n", sql, errmsg);
271  free(errmsg);
272  }
273 
274  switch_safe_free(sql);
275 
276  if (!r) {
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 
284 
285  if (errmsg) {
286  switch_log_printf(SWITCH_CHANNEL_LOG, 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);
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 
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);
321  switch_assert(stream.data);
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);
341 
342  return r;
343 
344 }
345 
346 
348 {
349  char *arg = NULL, *alias = NULL;
350 
351  char *delim = ";;";
352  int argc;
353  char *argv[128];
354  int x;
355  char *dup = strdup(xcmd);
356  char *cmd;
357 
359 
360 
361  if (rec > 100) {
362  switch_log_printf(SWITCH_CHANNEL_LOG, 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')) != 0 || (arg = strchr(cmd, '\n')) != 0) {
376  *arg = '\0';
377  arg = NULL;
378  }
379  if ((arg = 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, istream);
392  }
393 
394  end:
395 
396  switch_safe_free(dup);
397 
398  return status;
399 }
400 
401 SWITCH_DECLARE(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;
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;
411  switch_event_t *event;
412 
413  va_start(ap, fmt);
414  ret = switch_vasprintf(&data, fmt, ap);
415  va_end(ap);
416 
417  if (ret == -1) {
418  fprintf(stderr, "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 
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 &&
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);
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;
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, *str = NULL, *cur = NULL;
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))
486  cur = NULL;
487  if (zstr(str))
488  str = NULL;
489 
490  if (!target) {
491  return -1;
492  }
493 
494  if (!zstr(target) && *target == ':' && *(target + 1) == ':' && *(target + 2) == '[') {
495  char *p = target + 3, *list = NULL;
496 
497  if (p) {
498  char *s_argv[100] = { 0 };
499  char *r_argv[1] = { 0 }, *r_cols[1] = {0};
500  list = 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))) {
506  r_argv[0] = s_argv[i];
507  comp_callback(h, 1, r_argv, r_cols);
508  }
509  }
510  switch_safe_free(list);
511  }
512  return 0;
513  }
514 
515  if (!zstr(target) && *target == ':' && *(target + 1) == ':') {
516  char *r_argv[1] = { 0 }, *r_cols[1] = {0};
518  if (switch_console_run_complete_func(target, str, cur, &matches) == SWITCH_STATUS_SUCCESS) {
520  for (m = matches->head; m; m = m->next) {
521  if (!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)) {
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);
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)) {
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 {
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 
593 {
594  struct match_helper h = { 0 };
595 
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 
609 {
610  struct match_helper h = { 0 };
611 
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_GETIFADDRS
625 #include <ifaddrs.h>
626 #include <net/if.h>
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_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
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 
659  return 0;
660 
661 }
662 
664 {
665  char *sql;
666  struct match_helper h = { 0 };
667  switch_cache_db_handle_t *db = NULL;
669  char *errmsg;
670 
671 
674  return SWITCH_STATUS_GENERR;
675  }
676 
677  if (!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 
685  free(sql);
686 
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) switch_console_complete(const char *line, const char *cursor, FILE * console_out,
701 {
702  switch_cache_db_handle_t *db = NULL;
703  char *sql = NULL;
704  char *dup = strdup(line);
705  char *buf = dup;
706  char *p, *lp = NULL;
707  char *errmsg = NULL;
708  struct helper h = { 0 };
709  unsigned char ret = CC_REDISPLAY;
710  int pos = 0;
711  int sc = 0;
712 
713 #ifndef HAVE_LIBEDIT
714 #ifndef _MSC_VER
715  if (!stream) {
716  return CC_ERROR;
717  }
718 #endif
719 #endif
720 
723  return CC_ERROR;
724  }
725 
726  if (!zstr(cursor) && !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')) || (p = strchr(buf, '\n'))) {
739  *p = '\0';
740  }
741 
742  while (*buf == ' ') {
743  sc++;
744  buf++;
745  }
746 
747  if (!*buf) {
748 #ifdef HAVE_LIBEDIT
749  if (h.out && sc) {
750  el_deletestr(el, sc);
751  }
752 #endif
753  }
754 
755  sc = 0;
756  p = end_of_p(buf);
757  while (p >= buf && *p == ' ') {
758  sc++;
759  p--;
760  }
761 
762  if (sc > 1) {
763 #ifdef HAVE_LIBEDIT
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) {
805 
806  if (errmsg) {
807  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "error [%s][%s]\n", sql, errmsg);
808  free(errmsg);
809  ret = CC_ERROR;
810  goto end;
811  }
812  free(sql);
813  sql = NULL;
814  }
815 
816  if (h.hits != -1) {
817  char *dupdup = strdup(dup);
818  int x, argc = 0;
819  char *argv[10] = { 0 };
820  switch_stream_handle_t stream = { 0 };
821  SWITCH_STANDARD_STREAM(stream);
822  switch_assert(dupdup);
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 {
831  stream.write_function(&stream, "select distinct a%d,'%q','%q' from complete where ", h.words + 1, switch_str_nil(dup), switch_str_nil(lp));
832  } else {
833  stream.write_function(&stream, "select distinct a%d,'%q','%w' from complete where ", h.words + 1, switch_str_nil(dup), switch_str_nil(lp));
834  }
835  }
836 
837  for (x = 0; x < argc && x < 11; x++) {
838  if (h.words + 1 > argc) {
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]), 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]), x == argc - 1 ? "" : " and ");
845  }
846  } else {
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]), 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]), 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_LOG, SWITCH_LOG_ERROR, "error [%s][%s]\n", (char *) stream.data, errmsg);
863  free(errmsg);
864  ret = CC_ERROR;
865  }
866 
867  switch_safe_free(dupdup);
868  switch_safe_free(stream.data);
869 
870  if (ret == CC_ERROR) {
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)) {
882  h.stream->write_function(h.stream, "write=%d:%s ", h.len, h.last);
883  } else if (h.hits > 1 && !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++);
890  char buf[32];
891 
892  snprintf(buf, sizeof(buf), "%d", h.len);
893  switch_xml_set_attr_d_buf(x_write, "length", buf);
894 
895  if (h.hits == 1 && !zstr(h.last)) {
896  switch_xml_set_txt_d(x_write, h.last);
897  } else if (h.hits > 1 && !zstr(h.partial)) {
898  switch_xml_set_txt_d(x_write, h.partial);
899  }
900  }
901 #ifdef HAVE_LIBEDIT
902  if (h.out) {
903  if (h.hits == 1 && !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)) {
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)) {
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)) {
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);
936  switch_safe_free(dup);
937 
939 
940  return (ret);
941 }
942 
943 
944 #if defined(HAVE_LIBEDIT) || 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));
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 */
958 
959  if (c == NULL) {
960  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "FUNCTION KEY F%d IS NOT BOUND, please edit switch.conf XML file\n", i);
961  return CC_REDISPLAY;
962  }
963 
964  cmd = strdup(c);
966  free(cmd);
967 
968  return CC_REDISPLAY;
969 }
970 #endif
971 
973 {
974 #ifdef HAVE_LIBEDIT
975  history(myhistory, &ev, H_SAVE, hfile);
976 #else
978 #endif
979 }
980 
981 #ifdef HAVE_LIBEDIT
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;
1048 
1049  while (running) {
1050  int32_t arg = 0;
1051 
1052  if (getppid() == 1) {
1053  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "We've become an orphan, no more console for us.\n");
1054  break;
1055  }
1056 
1058  if (!arg) {
1059  break;
1060  }
1061 
1062  line = el_gets(el, &count);
1063 
1064  if (count > 1) {
1065  if (!zstr(line)) {
1066  char *cmd = 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);
1074  history(myhistory, &ev, H_ENTER, line);
1076  el_deletestr(el, strlen(foo) + 1);
1077  memset(foo, 0, strlen(foo));
1078  free(cmd);
1079  }
1080  }
1081  switch_cond_next();
1082  }
1083 
1085  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Editline thread exiting\n");
1086  return NULL;
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, NULL);
1094 }
1095 
1096 
1098 {
1100  switch_threadattr_t *thd_attr = NULL;
1102 
1105  return;
1106  }
1107 
1109  el_set(el, EL_PROMPT, &prompt);
1110  el_set(el, EL_EDITOR, "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 */
1117  /* Bind the functions to the key */
1118  el_set(el, EL_ADDFN, "f1-key", "F1 KEY PRESS", console_f1key);
1119  el_set(el, EL_ADDFN, "f2-key", "F2 KEY PRESS", console_f2key);
1120  el_set(el, EL_ADDFN, "f3-key", "F3 KEY PRESS", console_f3key);
1121  el_set(el, EL_ADDFN, "f4-key", "F4 KEY PRESS", console_f4key);
1122  el_set(el, EL_ADDFN, "f5-key", "F5 KEY PRESS", console_f5key);
1123  el_set(el, EL_ADDFN, "f6-key", "F6 KEY PRESS", console_f6key);
1124  el_set(el, EL_ADDFN, "f7-key", "F7 KEY PRESS", console_f7key);
1125  el_set(el, EL_ADDFN, "f8-key", "F8 KEY PRESS", console_f8key);
1126  el_set(el, EL_ADDFN, "f9-key", "F9 KEY PRESS", console_f9key);
1127  el_set(el, EL_ADDFN, "f10-key", "F10 KEY PRESS", console_f10key);
1128  el_set(el, EL_ADDFN, "f11-key", "F11 KEY PRESS", console_f11key);
1129  el_set(el, EL_ADDFN, "f12-key", "F12 KEY PRESS", console_f12key);
1130 
1131  el_set(el, EL_BIND, "\033OP", "f1-key", NULL);
1132  el_set(el, EL_BIND, "\033OQ", "f2-key", NULL);
1133  el_set(el, EL_BIND, "\033OR", "f3-key", NULL);
1134  el_set(el, EL_BIND, "\033OS", "f4-key", NULL);
1135 
1136 
1137  el_set(el, EL_BIND, "\033[11~", "f1-key", NULL);
1138  el_set(el, EL_BIND, "\033[12~", "f2-key", NULL);
1139  el_set(el, EL_BIND, "\033[13~", "f3-key", NULL);
1140  el_set(el, EL_BIND, "\033[14~", "f4-key", NULL);
1141  el_set(el, EL_BIND, "\033[15~", "f5-key", NULL);
1142  el_set(el, EL_BIND, "\033[17~", "f6-key", NULL);
1143  el_set(el, EL_BIND, "\033[18~", "f7-key", NULL);
1144  el_set(el, EL_BIND, "\033[19~", "f8-key", NULL);
1145  el_set(el, EL_BIND, "\033[20~", "f9-key", NULL);
1146  el_set(el, EL_BIND, "\033[21~", "f10-key", NULL);
1147  el_set(el, EL_BIND, "\033[23~", "f11-key", NULL);
1148  el_set(el, EL_BIND, "\033[24~", "f12-key", NULL);
1149 
1150 
1151  el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete);
1152  el_set(el, EL_BIND, "^I", "ed-complete", NULL);
1153 
1154  /* "Delete" key. */
1155  el_set(el, EL_BIND, "\033[3~", "ed-delete-next-char", NULL);
1156 
1157  myhistory = history_init();
1158  if (myhistory == 0) {
1159  fprintf(stderr, "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);
1165 
1166  history(myhistory, &ev, H_SETSIZE, 800);
1167  el_set(el, EL_HIST, history, myhistory);
1168  history(myhistory, &ev, H_LOAD, hfile);
1169 
1170  el_source(el, NULL);
1171 
1172  switch_threadattr_create(&thd_attr, pool);
1173  switch_threadattr_detach_set(thd_attr, 1);
1175  switch_thread_create(&thread, thd_attr, console_thread, pool, pool);
1176 
1177  while (running) {
1178  int32_t arg = 0;
1180  if (!arg) {
1181  break;
1182  }
1183  switch_yield(1000000);
1184  }
1185 
1186  history(myhistory, &ev, H_SAVE, 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_BUFLEN + 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)) {
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, NULL);
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_BUFLEN);
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_BUFLEN) {
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 (FALSE);
1455  }
1456 
1457  if ((pInput = (PINPUT_RECORD) malloc(toRead * sizeof(INPUT_RECORD))) == NULL) {
1458  return (FALSE);
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);
1548 }
1549 #endif
1550 
1551 
1553 {
1554  char cmd[CMD_BUFLEN + 1] = "";
1555  int32_t activity = 1;
1556 #ifndef _MSC_VER
1557  int x = 0;
1558 #else
1559  char keys[CMD_BUFLEN];
1560 #endif
1561 
1562  /* Load/Init the config first */
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 
1582  if (!arg) {
1583  break;
1584  }
1585 
1586  if (activity) {
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")) {
1594  cmd[0] = 0;
1595  }
1596  activity = 1;
1597  if (cmd[0]) {
1599  }
1600  memset(cmd, 0, sizeof(cmd));
1601  }
1602  }
1603  Sleep(20);
1604 #else
1605  FD_ZERO(&rfds);
1606  FD_ZERO(&efds);
1607  FD_SET(fileno(stdin), &rfds);
1608  FD_SET(fileno(stdin), &efds);
1609  if ((activity = select(fileno(stdin) + 1, &rfds, NULL, &efds, &tv)) < 0) {
1610  break;
1611  }
1612 
1613  if (FD_ISSET(fileno(stdin), &efds)) {
1614  continue;
1615  }
1616 
1617  if (!FD_ISSET(fileno(stdin), &rfds)) {
1618  activity = 0;
1619  }
1620 
1621  if (activity == 0) {
1622  fflush(stdout);
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(stdin), 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]) {
1645  }
1646 #endif
1647  }
1648 }
1649 
1650 
1651 
1652 #endif
1653 
1654 
1655 static struct {
1658 } globals;
1659 
1661 {
1662  switch_mutex_init(&globals.func_mutex, SWITCH_MUTEX_NESTED, pool);
1663  switch_core_hash_init(&globals.func_hash);
1668  return SWITCH_STATUS_SUCCESS;
1669 }
1670 
1672 {
1673  return switch_core_hash_destroy(&globals.func_hash);
1674 }
1675 
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);
1682  switch_mutex_unlock(globals.func_mutex);
1683 
1684  return status;
1685 }
1686 
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);
1693  switch_mutex_unlock(globals.func_mutex);
1694 
1695  return status;
1696 }
1697 
1699 {
1700  switch_console_callback_match_t *my_match = *matches;
1702 
1703  /* Don't play with matches */
1704  *matches = NULL;
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 
1720 {
1721  switch_console_callback_match_node_t *p = NULL, *sort[4] = { 0 };
1722  int i, j;
1723 
1724  switch_assert(matches);
1725 
1726  if (matches->count < 2) {
1727  return;
1728  }
1729 
1730  for (i = 1; i < matches->count; i++) {
1731  sort[0] = NULL;
1732  sort[1] = matches->head;
1733  sort[2] = sort[1] ? sort[1]->next : NULL;
1734  sort[3] = sort[2] ? sort[2]->next : NULL;
1735 
1736  for (j = 1; j <= (matches->count - i); j++) {
1737  switch_assert(sort[1] && sort[2]);
1738  if (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;
1773  matches->end = p;
1774  }
1775 }
1776 
1778 {
1779  /* Ignore the entry if it is already in the list */
1780  if (*matches) {
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 
1792 {
1794 
1795  if (!*matches) {
1796  switch_zmalloc(*matches, sizeof(**matches));
1797  (*matches)->dynamic = 1;
1798  }
1799 
1800  switch_zmalloc(match, sizeof(*match));
1801  match->val = 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) switch_console_run_complete_func(const char *func, const char *line, const char *last_word,
1816 {
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 
1833 {
1834  char *mydata = NULL, *argv[11] = { 0 };
1835  int argc, x;
1838 
1839  if (!(cflags & SCF_USE_SQL)) {
1840  return SWITCH_STATUS_FALSE;
1841  }
1842 
1843  if (string && (mydata = 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);
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 {
1855  mystream.write_function(&mystream, "'%q', ", switch_str_nil(argv[x + 1]));
1856  } else {
1857  mystream.write_function(&mystream, "'%w', ", switch_str_nil(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 {
1871  mystream.write_function(&mystream, "'%q', ", switch_str_nil(argv[x + 1]));
1872  } else {
1873  mystream.write_function(&mystream, "'%w', ", switch_str_nil(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)) {
1884  switch_safe_free(mystream.data);
1885  switch_safe_free(mydata);
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++) {
1894  mystream.write_function(&mystream, "a%d = '%q'%q", x + 1, switch_str_nil(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]), 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);
1906  }
1907  }
1908 
1909  switch_safe_free(mydata);
1910 
1911  return status;
1912 
1913 }
1914 
1915 
1917 {
1918  char *mydata = NULL, *argv[3] = { 0 };
1919  int argc;
1921 
1922  if (string && (mydata = strdup(string))) {
1923  if ((argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) >= 2) {
1924  switch_cache_db_handle_t *db = NULL;
1925  char *sql = NULL;
1926 
1927  if (argc > 2 && !strcmp(argv[1], argv[2])) {
1928  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Alias and command cannot be the same, this will cause loop!\n");
1929  return SWITCH_STATUS_FALSE;
1930  }
1931 
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());
1941  switch_safe_free(sql);
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  }
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());
1954  switch_safe_free(sql);
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  }
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());
1969  } else {
1970  sql = switch_mprintf("delete from aliases where alias='%q' and hostname='%q'", argv[1], switch_core_get_switchname());
1972  }
1973  status = SWITCH_STATUS_SUCCESS;
1974  }
1975  switch_safe_free(sql);
1977  }
1978  }
1979 
1980  switch_safe_free(mydata);
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  */
#define switch_core_permanent_strdup(_todup)
Copy a string using permanent memory allocation.
Definition: switch_core.h:705
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:310
const char * switch_core_get_switchname(void)
Definition: switch_core.c:349
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:412
switch_status_t switch_console_set_complete(const char *string)
void switch_xml_free(_In_opt_ switch_xml_t xml)
frees the memory allocated for an switch_xml structure
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
const char * switch_xml_attr_soft(_In_ switch_xml_t xml, _In_z_ const char *attr)
returns the value of the requested tag attribute, or "" if not found
switch_xml_t switch_status_t switch_event_running(void)
Determine if the event system has been initialized.
Definition: switch_event.c:417
#define CC_ERROR
switch_status_t switch_console_shutdown(void)
#define SWITCH_THREAD_FUNC
switch_text_channel_t
A target to write log/debug info to.
#define CC_REDISPLAY
#define SWITCH_CHANNEL_LOG
void switch_console_push_match_unique(switch_console_callback_match_t **matches, const char *new_val)
switch_status_t switch_core_hash_destroy(_Inout_ switch_hash_t **hash)
Destroy an existing hash table.
switch_status_t switch_console_execute(char *xcmd, int rec, switch_stream_handle_t *istream)
void * switch_core_hash_find(_In_ switch_hash_t *hash, _In_z_ const char *key)
Retrieve data from a given hash.
#define switch_core_hash_init(_hash)
Definition: switch_core.h:1390
switch_console_callback_match_t * my_matches
switch_status_t switch_console_init(switch_memory_pool_t *pool)
switch_status_t switch_console_add_complete_func(const char *name, switch_console_complete_callback_t cb)
switch_status_t switch_console_list_uuid(const char *line, const char *cursor, switch_console_callback_match_t **matches)
void switch_console_sort_matches(switch_console_callback_match_t *matches)
switch_status_t switch_loadable_module_enumerate_available(const char *dir_path, switch_modulename_callback_func_t callback, void *user_data)
Enumerates a list of all modules discovered in a directory.
unsigned int switch_separate_string_string(char *buf, char *delim, _Post_count_(return) char **array, unsigned int arraylen)
switch_status_t switch_api_execute(const char *cmd, const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream)
Execute a registered API command.
switch_status_t(* switch_console_complete_callback_t)(const char *, const char *, switch_console_callback_match_t **matches)
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:660
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
switch_memory_pool_t * pool
static int comp_callback(void *pArg, int argc, char **argv, char **columnNames)
switch_status_t switch_event_add_header(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *fmt,...) PRINTF_FUNCTION(4
Add a header to an event.
#define switch_xml_add_child_d(xml, name, off)
wrapper for switch_xml_add_child() that strdup()s name
Definition: switch_xml.h:269
Representation of an event.
Definition: switch_event.h:80
static struct @1 globals
void switch_console_printf(switch_text_channel_t channel, const char *file, const char *func, int line, const char *fmt,...)
Simple Console.
struct switch_console_callback_match_node * head
switch_status_t switch_time_exp_lt(switch_time_exp_t *result, switch_time_t input)
Definition: switch_apr.c:323
FILE * out
A representation of an XML tree.
Definition: switch_xml.h:76
switch_status_t switch_console_list_interfaces(const char *line, const char *cursor, switch_console_callback_match_t **matches)
void switch_console_free_matches(switch_console_callback_match_t **matches)
switch_status_t switch_console_run_complete_func(const char *func, const char *line, const char *last_word, switch_console_callback_match_t **matches)
switch_status_t switch_strftime_nocheck(char *s, switch_size_t *retsize, switch_size_t max, const char *format, switch_time_exp_t *tm)
Definition: switch_apr.c:179
pack cur
static switch_thread_t * thread
Definition: switch_log.c:279
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
uint32_t switch_core_flag_t
Definition: switch_types.h:376
void switch_console_save_history(void)
switch_status_t switch_console_del_complete_func(const char *name)
switch_status_t switch_stream_write_file_contents(switch_stream_handle_t *stream, const char *path)
switch_status_t switch_cache_db_execute_sql_callback(switch_cache_db_handle_t *dbh, const char *sql, switch_core_db_callback_func_t callback, void *pdata, char **err)
Executes the sql and uses callback for row-by-row processing.
#define end_of_p(_s)
Definition: switch_utils.h:617
#define zstr(x)
Definition: switch_utils.h:281
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
void switch_cache_db_release_db_handle(switch_cache_db_handle_t **dbh)
Returns the handle to the pool, handle is NOT available to other threads until the allocating thread ...
switch_hash_t * func_hash
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:122
switch_status_t switch_threadattr_detach_set(switch_threadattr_t *attr, int32_t on)
Definition: switch_apr.c:655
if((uint32_t)(unpack->cur-unpack->buf) > unpack->buflen)
switch_xml_t next
Definition: switch_xml.h:88
switch_byte_t switch_byte_t * buf
switch_status_t switch_console_set_alias(const char *string)
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:908
unsigned int switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen)
Separate a string into an array based on a character delimiter.
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
switch_core_flag_t switch_core_flags(void)
return core flags
Definition: switch_core.c:2852
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:551
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
#define switch_zmalloc(ptr, len)
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
switch_stream_handle_t * stream
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
static char * console_fnkeys[12]
#define SWITCH_CHANNEL_LOG_CLEAN
static int uuid_callback(void *pArg, int argc, char **argv, char **columnNames)
uintptr_t switch_size_t
static int alias_callback(void *pArg, int argc, char **argv, char **columnNames)
int switch_vasprintf(_Out_opt_ char **buf, _In_z_ _Printf_format_string_ const char *format, _In_ va_list ap)
FILE * switch_core_data_channel(switch_text_channel_t channel)
Retrieve a FILE stream of a given text channel name.
Definition: switch_core.c:263
switch_size_t switch_fp_read_dline(FILE *fd, char **buf, switch_size_t *len)
Definition: switch_utils.c:757
void switch_cond_next(void)
Definition: switch_time.c:638
switch_status_t switch_console_stream_write(switch_stream_handle_t *handle, const char *fmt,...)
#define SWITCH_STANDARD_STREAM(s)
char * switch_copy_string(_Out_z_cap_(dst_size) char *dst, _In_z_ const char *src, _In_ switch_size_t dst_size)
static int modulename_callback(void *pArg, const char *module_name)
switch_status_t switch_cache_db_persistant_execute(switch_cache_db_handle_t *dbh, const char *sql, uint32_t retries)
static int32_t running
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:60
switch_status_t switch_console_list_available_modules(const char *line, const char *cursor, switch_console_callback_match_t **matches)
#define switch_core_db_handle(_a)
Definition: switch_core.h:2606
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:903
#define SWITCH_DECLARE_NONSTD(type)
void switch_core_sql_exec(const char *sql)
#define switch_xml_set_attr_d_buf(xml, name, value)
Definition: switch_xml.h:302
char partial[512]
switch_stream_handle_write_function_t write_function
struct apr_thread_mutex_t switch_mutex_t
Definition: switch_apr.h:314
switch_status_t
Common return values.
switch_status_t switch_console_list_loaded_modules(const char *line, const char *cursor, switch_console_callback_match_t **matches)
void switch_console_loop(void)
A simple comand loop that reads input from the terminal.
switch_cache_db_handle_type_t switch_cache_db_get_type(switch_cache_db_handle_t *dbh)
switch_xml_t switch_xml_open_cfg(_In_z_ const char *file_path, _Out_ switch_xml_t *node, _In_opt_ switch_event_t *params)
open a config in the core registry
const char * switch_core_get_hostname(void)
Definition: switch_core.c:344
#define switch_core_hash_insert(_h, _k, _d)
Definition: switch_core.h:1410
struct apr_thread_t switch_thread_t
Definition: switch_apr.h:941
#define FALSE
Main Library Header.
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:383
static switch_bool_t switch_is_file_path(const char *file)
#define switch_xml_set_txt_d(xml, txt)
wrapper for switch_xml_set_txt() that strdup()s txt \ sets the character content for the given tag an...
Definition: switch_xml.h:283
#define SWITCH_DECLARE(type)
unsigned char switch_console_complete(const char *line, const char *cursor, FILE *console_out, switch_stream_handle_t *stream, switch_xml_t xml)
switch_xml_t switch_xml_child(_In_ switch_xml_t xml, _In_z_ const char *name)
returns the first child tag (one level deeper) with the given name or NULL \ if not found ...
static switch_status_t console_xml_config(void)
switch_status_t switch_loadable_module_enumerate_loaded(switch_modulename_callback_func_t callback, void *user_data)
Enumerates a list of all currently loaded modules.
static int switch_console_process(char *xcmd)
switch_cache_db_handle_type_t switch_core_dbtype(void)
switch_mutex_t * func_mutex
char * switch_console_expand_alias(char *cmd, char *arg)
struct apr_pool_t switch_memory_pool_t
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
Definition: switch_apr.c:642
switch_status_t switch_thread_create(switch_thread_t **new_thread, switch_threadattr_t *attr, switch_thread_start_t func, void *data, switch_memory_pool_t *cont)
Definition: switch_apr.c:675
#define CMD_BUFLEN
FILE * switch_core_get_console(void)
Get the output console.
Definition: switch_core.c:230
#define TRUE
int32_t switch_core_session_ctl(switch_session_ctl_t cmd, void *val)
send a control message to the core
Definition: switch_core.c:2528
#define switch_assert(expr)
const char * switch_cut_path(const char *in)
Create a pointer to the file name in a given file path eliminating the directory name.
char last[512]
void switch_console_push_match(switch_console_callback_match_t **matches, const char *new_val)
switch_xml_t xml
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)
memset(buf, 0, buflen)
char * switch_vmprintf(const char *zFormat, va_list ap)
struct switch_console_callback_match_node * next
switch_status_t switch_console_stream_raw_write(switch_stream_handle_t *handle, uint8_t *data, switch_size_t datalen)