2005-11-19 20:07:43 +00:00
|
|
|
/*
|
|
|
|
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
|
|
|
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
|
|
|
|
*
|
|
|
|
* Version: MPL 1.1
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
* the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/MPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* License.
|
|
|
|
*
|
|
|
|
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
* Anthony Minessale II <anthmct@yahoo.com>
|
|
|
|
* Portions created by the Initial Developer are Copyright (C)
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
*
|
|
|
|
* Anthony Minessale II <anthmct@yahoo.com>
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* switch_console.c -- Simple Console
|
|
|
|
*
|
|
|
|
*/
|
2005-12-14 21:29:46 +00:00
|
|
|
#include <switch.h>
|
2006-04-29 06:05:03 +00:00
|
|
|
#include <switch_console.h>
|
2006-05-15 15:00:10 +00:00
|
|
|
#include <switch_version.h>
|
2006-09-07 03:58:01 +00:00
|
|
|
#define CMD_BUFLEN 1024;
|
2005-11-19 20:07:43 +00:00
|
|
|
|
2006-05-10 15:47:54 +00:00
|
|
|
|
2007-02-14 02:53:23 +00:00
|
|
|
SWITCH_DECLARE(switch_status_t) switch_console_stream_write(switch_stream_handle_t *handle, const char *fmt, ...)
|
2006-05-10 15:47:54 +00:00
|
|
|
{
|
|
|
|
va_list ap;
|
|
|
|
char *buf = handle->data;
|
|
|
|
char *end = handle->end;
|
|
|
|
int ret = 0;
|
2007-03-23 22:44:28 +00:00
|
|
|
char *data = NULL;
|
2006-05-10 15:47:54 +00:00
|
|
|
|
|
|
|
if (handle->data_len >= handle->data_size) {
|
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
2007-03-09 20:44:13 +00:00
|
|
|
ret = switch_vasprintf(&data, fmt, ap);
|
2006-05-10 15:47:54 +00:00
|
|
|
va_end(ap);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-05-10 15:47:54 +00:00
|
|
|
if (data) {
|
2006-09-07 03:58:01 +00:00
|
|
|
switch_size_t remaining = handle->data_size - handle->data_len;
|
|
|
|
switch_size_t need = strlen(data) + 1;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
|
|
|
|
2006-09-07 03:58:01 +00:00
|
|
|
if ((remaining < need) && handle->alloc_len) {
|
|
|
|
switch_size_t new_len;
|
2007-01-06 16:40:46 +00:00
|
|
|
void *new_data;
|
2006-05-10 15:47:54 +00:00
|
|
|
|
2007-01-06 16:40:46 +00:00
|
|
|
new_len = handle->data_size + need + handle->alloc_chunk;
|
|
|
|
if ((new_data = realloc(handle->data, new_len))) {
|
2006-09-07 03:58:01 +00:00
|
|
|
handle->data_size = handle->alloc_len = new_len;
|
2007-03-29 22:31:56 +00:00
|
|
|
handle->data = new_data;
|
2006-09-07 03:58:01 +00:00
|
|
|
buf = handle->data;
|
|
|
|
remaining = handle->data_size - handle->data_len;
|
2007-03-29 22:31:56 +00:00
|
|
|
handle->end = (uint8_t *) (handle->data) + handle->data_len;
|
2006-09-07 03:58:01 +00:00
|
|
|
end = handle->end;
|
|
|
|
} else {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
|
|
|
|
free(data);
|
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (remaining < need) {
|
2006-05-10 15:47:54 +00:00
|
|
|
ret = -1;
|
|
|
|
} else {
|
|
|
|
ret = 0;
|
2006-10-06 22:39:49 +00:00
|
|
|
snprintf(end, remaining, "%s", data);
|
2006-05-10 15:47:54 +00:00
|
|
|
handle->data_len = strlen(buf);
|
2007-03-29 22:31:56 +00:00
|
|
|
handle->end = (uint8_t *) (handle->data) + handle->data_len;
|
2006-05-10 15:47:54 +00:00
|
|
|
}
|
|
|
|
free(data);
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-05-10 15:47:54 +00:00
|
|
|
return ret ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-09-07 03:58:01 +00:00
|
|
|
static int switch_console_process(char *cmd)
|
2005-11-19 20:07:43 +00:00
|
|
|
{
|
2006-01-03 01:17:59 +00:00
|
|
|
char *arg = NULL;
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_stream_handle_t stream = { 0 };
|
2006-03-29 19:11:20 +00:00
|
|
|
|
2005-11-19 20:07:43 +00:00
|
|
|
if (!strcmp(cmd, "shutdown") || !strcmp(cmd, "...")) {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bye!\n");
|
2005-11-19 20:07:43 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2006-01-06 17:44:19 +00:00
|
|
|
if (!strcmp(cmd, "version")) {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_CONSOLE, "FreeSwitch Version %s\n", SWITCH_VERSION_FULL);
|
2006-01-06 17:44:19 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
if ((arg = strchr(cmd, '\r')) != 0 || (arg = strchr(cmd, '\n')) != 0) {
|
2005-12-23 16:54:49 +00:00
|
|
|
*arg = '\0';
|
|
|
|
arg = NULL;
|
|
|
|
}
|
2006-02-20 00:23:25 +00:00
|
|
|
if ((arg = strchr(cmd, ' ')) != 0) {
|
2005-12-23 16:54:49 +00:00
|
|
|
*arg++ = '\0';
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-09-07 03:58:01 +00:00
|
|
|
SWITCH_STANDARD_STREAM(stream);
|
|
|
|
if (stream.data) {
|
|
|
|
if (switch_api_execute(cmd, arg, NULL, &stream) == SWITCH_STATUS_SUCCESS) {
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_CONSOLE, "API CALL [%s(%s)] output:\n%s\n", cmd, arg ? arg : "", (char *) stream.data);
|
2006-09-07 03:58:01 +00:00
|
|
|
} else {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Unknown Command: %s\n", cmd);
|
|
|
|
}
|
|
|
|
free(stream.data);
|
2005-12-23 02:55:25 +00:00
|
|
|
} else {
|
2006-09-07 03:58:01 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
|
2005-12-23 02:55:25 +00:00
|
|
|
}
|
2006-09-07 03:58:01 +00:00
|
|
|
|
2005-11-19 20:07:43 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
SWITCH_DECLARE(void) switch_console_printf(switch_text_channel_t channel, const char *file, const char *func, int line, const char *fmt, ...)
|
2005-11-19 20:07:43 +00:00
|
|
|
{
|
2006-02-13 18:34:39 +00:00
|
|
|
char *data = NULL;
|
2005-11-19 20:07:43 +00:00
|
|
|
int ret = 0;
|
|
|
|
va_list ap;
|
|
|
|
FILE *handle;
|
2007-02-13 21:03:06 +00:00
|
|
|
const char *filep = switch_cut_path(file);
|
2005-11-19 20:07:43 +00:00
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
|
|
|
|
handle = switch_core_data_channel(channel);
|
|
|
|
|
2007-03-09 20:44:13 +00:00
|
|
|
ret = switch_vasprintf(&data, fmt, ap);
|
2005-11-19 20:07:43 +00:00
|
|
|
va_end(ap);
|
|
|
|
if (ret == -1) {
|
|
|
|
fprintf(stderr, "Memory Error\n");
|
|
|
|
} else {
|
|
|
|
char date[80] = "";
|
|
|
|
|
2006-04-11 21:13:44 +00:00
|
|
|
if (channel == SWITCH_CHANNEL_ID_LOG_CLEAN) {
|
2005-11-19 20:07:43 +00:00
|
|
|
fprintf(handle, "%s", data);
|
|
|
|
} else {
|
2006-03-30 23:02:50 +00:00
|
|
|
switch_size_t retsize;
|
2005-11-19 20:07:43 +00:00
|
|
|
switch_time_exp_t tm;
|
2006-04-29 01:00:52 +00:00
|
|
|
switch_event_t *event;
|
2005-11-19 20:07:43 +00:00
|
|
|
switch_time_exp_lt(&tm, switch_time_now());
|
|
|
|
switch_strftime(date, &retsize, sizeof(date), "%Y-%m-%d %T", &tm);
|
2005-12-21 22:25:22 +00:00
|
|
|
|
2006-04-11 21:13:44 +00:00
|
|
|
if (channel == SWITCH_CHANNEL_ID_LOG) {
|
2006-01-20 15:05:05 +00:00
|
|
|
fprintf(handle, "[%d] %s %s:%d %s() %s", (int) getpid(), date, filep, line, func, data);
|
2005-12-21 22:25:22 +00:00
|
|
|
}
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
else if (channel == SWITCH_CHANNEL_ID_EVENT &&
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_event_running() == SWITCH_STATUS_SUCCESS && switch_event_create(&event, SWITCH_EVENT_LOG) == SWITCH_STATUS_SUCCESS) {
|
2006-01-03 01:17:59 +00:00
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Data", "%s", data);
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-File", "%s", filep);
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Function", "%s", func);
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Log-Line", "%d", line);
|
|
|
|
switch_event_fire(&event);
|
2005-12-21 22:25:22 +00:00
|
|
|
}
|
2005-11-19 20:07:43 +00:00
|
|
|
}
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
if (data) {
|
2006-02-13 18:34:39 +00:00
|
|
|
free(data);
|
|
|
|
}
|
2005-11-19 20:07:43 +00:00
|
|
|
fflush(handle);
|
|
|
|
}
|
|
|
|
|
2007-04-30 20:37:41 +00:00
|
|
|
static char hostname[256] = "";
|
|
|
|
|
|
|
|
#ifdef SWITCH_HAVE_LIBEDIT
|
|
|
|
#include <histedit.h>
|
|
|
|
static char prompt_str[512] = "";
|
|
|
|
|
|
|
|
char * prompt(EditLine *e) {
|
|
|
|
if (switch_strlen_zero(prompt_str)) {
|
|
|
|
gethostname(hostname, sizeof(hostname));
|
2007-04-30 23:56:27 +00:00
|
|
|
snprintf(prompt_str, sizeof(prompt_str), "freeswitch@%s> ", hostname);
|
2007-04-30 20:37:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return prompt_str;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2005-11-19 20:07:43 +00:00
|
|
|
SWITCH_DECLARE(void) switch_console_loop(void)
|
|
|
|
{
|
2007-04-30 20:37:41 +00:00
|
|
|
EditLine *el;
|
|
|
|
History *myhistory;
|
|
|
|
int count;
|
|
|
|
const char *line;
|
|
|
|
HistEvent ev;
|
|
|
|
int32_t running = 1;
|
|
|
|
char *hfile;
|
|
|
|
|
|
|
|
el = el_init(__FILE__, switch_core_get_console(), switch_core_get_console(), switch_core_get_console());
|
|
|
|
el_set(el, EL_PROMPT, &prompt);
|
|
|
|
el_set(el, EL_EDITOR, "emacs");
|
|
|
|
|
|
|
|
myhistory = history_init();
|
|
|
|
if (myhistory == 0) {
|
|
|
|
fprintf(stderr, "history could not be initialized\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
hfile = switch_mprintf("%s%sfreeswitch.history", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR);
|
|
|
|
assert(hfile != NULL);
|
|
|
|
|
|
|
|
|
|
|
|
history(myhistory, &ev, H_SETSIZE, 800);
|
|
|
|
el_set(el, EL_HIST, history, myhistory);
|
|
|
|
history(myhistory, &ev, H_LOAD, hfile);
|
|
|
|
|
|
|
|
while (running) {
|
2007-04-30 23:56:27 +00:00
|
|
|
uint32_t arg;
|
|
|
|
|
|
|
|
switch_core_session_ctl(SCSC_CHECK_RUNNING, &arg);
|
|
|
|
if (!arg) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-04-30 20:37:41 +00:00
|
|
|
line = el_gets(el, &count);
|
2007-04-30 23:56:27 +00:00
|
|
|
|
2007-04-30 20:37:41 +00:00
|
|
|
if (count > 1) {
|
|
|
|
if (!switch_strlen_zero(line)) {
|
|
|
|
char *cmd = strdup(line);
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
if ((p = strrchr(cmd, '\r')) || (p = strrchr(cmd, '\n'))) {
|
|
|
|
*p = '\0';
|
|
|
|
}
|
|
|
|
assert(cmd != NULL);
|
|
|
|
history(myhistory, &ev, H_ENTER, line);
|
|
|
|
running = switch_console_process(cmd);
|
|
|
|
free(cmd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
history(myhistory, &ev, H_SAVE, hfile);
|
|
|
|
|
|
|
|
free(hfile);
|
|
|
|
|
|
|
|
/* Clean up our memory */
|
|
|
|
history_end(myhistory);
|
|
|
|
el_end(el);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
SWITCH_DECLARE(void) switch_console_loop(void)
|
|
|
|
{
|
|
|
|
|
2005-11-19 20:07:43 +00:00
|
|
|
char cmd[2048];
|
2007-02-13 01:58:39 +00:00
|
|
|
int32_t activity = 1, running = 1;
|
2006-08-22 00:56:27 +00:00
|
|
|
switch_size_t x = 0;
|
2005-11-19 20:07:43 +00:00
|
|
|
|
|
|
|
gethostname(hostname, sizeof(hostname));
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
while (running) {
|
2006-09-20 20:25:26 +00:00
|
|
|
uint32_t arg;
|
2007-02-14 00:31:11 +00:00
|
|
|
#ifndef _MSC_VER
|
2006-09-20 20:25:26 +00:00
|
|
|
fd_set rfds, efds;
|
2007-03-29 22:31:56 +00:00
|
|
|
struct timeval tv = { 0, 20000 };
|
2007-02-14 00:31:11 +00:00
|
|
|
#endif
|
2006-09-20 20:25:26 +00:00
|
|
|
|
|
|
|
switch_core_session_ctl(SCSC_CHECK_RUNNING, &arg);
|
|
|
|
if (!arg) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2005-11-19 20:07:43 +00:00
|
|
|
if (activity) {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_CONSOLE, "\nfreeswitch@%s> ", hostname);
|
2005-11-19 20:07:43 +00:00
|
|
|
}
|
2006-09-20 20:47:28 +00:00
|
|
|
#ifdef _MSC_VER
|
2007-03-29 22:31:56 +00:00
|
|
|
activity = WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 20);
|
2006-09-20 20:47:28 +00:00
|
|
|
|
2007-02-14 00:31:11 +00:00
|
|
|
if (activity == 102) {
|
|
|
|
fflush(stdout);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
#else
|
2006-09-20 20:25:26 +00:00
|
|
|
FD_ZERO(&rfds);
|
|
|
|
FD_ZERO(&efds);
|
|
|
|
FD_SET(fileno(stdin), &rfds);
|
|
|
|
FD_SET(fileno(stdin), &efds);
|
2007-03-29 22:31:56 +00:00
|
|
|
if ((activity = select(fileno(stdin) + 1, &rfds, NULL, &efds, &tv)) < 0) {
|
|
|
|
break;
|
|
|
|
}
|
2005-11-19 20:07:43 +00:00
|
|
|
|
|
|
|
if (activity == 0) {
|
|
|
|
fflush(stdout);
|
|
|
|
continue;
|
|
|
|
}
|
2007-02-14 00:31:11 +00:00
|
|
|
#endif
|
|
|
|
|
2005-11-19 20:07:43 +00:00
|
|
|
|
|
|
|
memset(&cmd, 0, sizeof(cmd));
|
2007-03-29 22:31:56 +00:00
|
|
|
for (x = 0; x < (sizeof(cmd) - 1); x++) {
|
|
|
|
int c = getchar();
|
|
|
|
if (c < 0) {
|
|
|
|
int y = read(fileno(stdin), cmd, sizeof(cmd));
|
|
|
|
cmd[y - 1] = '\0';
|
|
|
|
break;
|
|
|
|
}
|
2006-12-19 19:15:13 +00:00
|
|
|
|
|
|
|
cmd[x] = (char) c;
|
|
|
|
|
2005-11-19 20:07:43 +00:00
|
|
|
if (cmd[x] == '\n') {
|
|
|
|
cmd[x] = '\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
if (cmd[0]) {
|
2006-09-07 03:58:01 +00:00
|
|
|
running = switch_console_process(cmd);
|
2005-11-19 20:07:43 +00:00
|
|
|
}
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2005-11-19 20:07:43 +00:00
|
|
|
|
|
|
|
}
|
2007-04-30 20:37:41 +00:00
|
|
|
#endif
|
2006-11-27 22:30:48 +00:00
|
|
|
|
|
|
|
/* For Emacs:
|
|
|
|
* Local Variables:
|
|
|
|
* mode:c
|
2007-02-09 02:36:03 +00:00
|
|
|
* indent-tabs-mode:t
|
2006-11-27 22:30:48 +00:00
|
|
|
* tab-width:4
|
|
|
|
* c-basic-offset:4
|
|
|
|
* End:
|
|
|
|
* For VIM:
|
|
|
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
|
|
|
*/
|