int main(int argc, char *argv[]) { esl_handle_t handle = {{0}}; int count = 0; const char *line = NULL; char cmd_str[1024] = ""; esl_config_t cfg; cli_profile_t *profile = NULL; int rv = 0; #ifndef WIN32 char hfile[512] = "/etc/fs_cli_history"; char cfile[512] = "/etc/fs_cli.conf"; char dft_cfile[512] = "/etc/fs_cli.conf"; #else char hfile[512] = "fs_cli_history"; char cfile[512] = "fs_cli.conf"; char dft_cfile[512] = "fs_cli.conf"; #endif char *home = getenv("HOME"); /* Vars for optargs */ int opt; static struct option options[] = { {"help", 0, 0, 'h'}, {"host", 1, 0, 'H'}, {"port", 1, 0, 'P'}, {"user", 1, 0, 'u'}, {"password", 1, 0, 'p'}, {"debug", 1, 0, 'd'}, {"execute", 1, 0, 'x'}, {"loglevel", 1, 0, 'l'}, {"quiet", 0, 0, 'q'}, {0, 0, 0, 0} }; char temp_host[128]; int argv_host = 0; char temp_user[256]; char temp_pass[128]; int argv_pass = 0 ; int argv_user = 0 ; int temp_port = 0; int argv_port = 0; int temp_log = -1; int argv_error = 0; int argv_exec = 0; char argv_command[256] = ""; char argv_loglevel[128] = ""; int argv_quiet = 0; strncpy(internal_profile.host, "127.0.0.1", sizeof(internal_profile.host)); strncpy(internal_profile.pass, "ClueCon", sizeof(internal_profile.pass)); strncpy(internal_profile.name, "internal", sizeof(internal_profile.name)); internal_profile.port = 8021; set_fn_keys(&internal_profile); if (home) { snprintf(hfile, sizeof(hfile), "%s/.fs_cli_history", home); snprintf(cfile, sizeof(cfile), "%s/.fs_cli_conf", home); } signal(SIGINT, handle_SIGINT); #ifdef SIGQUIT signal(SIGQUIT, handle_SIGQUIT); #endif esl_global_set_default_logger(6); /* default debug level to 6 (info) */ for(;;) { int option_index = 0; opt = getopt_long(argc, argv, "H:U:P:S:u:p:d:x:l:qh?", options, &option_index); if (opt == -1) break; switch (opt) { case 'H': esl_set_string(temp_host, optarg); argv_host = 1; break; case 'P': temp_port= atoi(optarg); if (temp_port > 0 && temp_port < 65536){ argv_port = 1; } else { printf("ERROR: Port must be in range 1 - 65535\n"); argv_error = 1; } break; case 'u': esl_set_string(temp_user, optarg); argv_user = 1; break; case 'p': esl_set_string(temp_pass, optarg); argv_pass = 1; break; case 'd': temp_log=atoi(optarg); if (temp_log < 0 || temp_log > 7){ printf("ERROR: Debug level should be 0 - 7.\n"); argv_error = 1; } else { esl_global_set_default_logger(temp_log); } break; case 'x': argv_exec = 1; esl_set_string(argv_command, optarg); break; case 'l': esl_set_string(argv_loglevel, optarg); break; case 'q': argv_quiet = 1; break; case 'h': case '?': print_banner(stdout); usage(argv[0]); return 0; default: opt = 0; } } if (argv_error){ printf("\n"); return usage(argv[0]); } if (!(rv = esl_config_open_file(&cfg, cfile))) { rv = esl_config_open_file(&cfg, dft_cfile); } if (rv) { char *var, *val; char cur_cat[128] = ""; while (esl_config_next_pair(&cfg, &var, &val)) { if (strcmp(cur_cat, cfg.category)) { esl_set_string(cur_cat, cfg.category); esl_set_string(profiles[pcount].name, cur_cat); esl_set_string(profiles[pcount].host, "localhost"); esl_set_string(profiles[pcount].pass, "ClueCon"); profiles[pcount].port = 8021; set_fn_keys(&profiles[pcount]); esl_log(ESL_LOG_DEBUG, "Found Profile [%s]\n", profiles[pcount].name); pcount++; } if (!strcasecmp(var, "host")) { esl_set_string(profiles[pcount-1].host, val); } else if (!strcasecmp(var, "user")) { esl_set_string(profiles[pcount-1].user, val); } else if (!strcasecmp(var, "password")) { esl_set_string(profiles[pcount-1].pass, val); } else if (!strcasecmp(var, "port")) { int pt = atoi(val); if (pt > 0) { profiles[pcount-1].port = (esl_port_t)pt; } } else if (!strcasecmp(var, "debug")) { int dt = atoi(val); if (dt > -1 && dt < 8){ profiles[pcount-1].debug = dt; } } else if(!strcasecmp(var, "loglevel")) { esl_set_string(profiles[pcount-1].loglevel, val); } else if(!strcasecmp(var, "quiet")) { profiles[pcount-1].quiet = esl_true(val); } else if (!strncasecmp(var, "key_F", 5)) { char *key = var + 5; if (key) { int i = atoi(key); if (i > 0 && i < 13) { profiles[pcount-1].console_fnkeys[i - 1] = strdup(val); } } } } esl_config_close_file(&cfg); } if (optind < argc) { get_profile(argv[optind], &profile); } if (!profile) { if (get_profile("default", &profile)) { esl_log(ESL_LOG_DEBUG, "profile default does not exist using builtin profile\n"); profile = &internal_profile; } } if (temp_log < 0 ) { esl_global_set_default_logger(profile->debug); } if (argv_host) { esl_set_string(profile->host, temp_host); } if (argv_port) { profile->port = (esl_port_t)temp_port; } if (argv_user) { esl_set_string(profile->user, temp_user); } if (argv_pass) { esl_set_string(profile->pass, temp_pass); } if (*argv_loglevel) { esl_set_string(profile->loglevel, argv_loglevel); profile->quiet = 0; } esl_log(ESL_LOG_DEBUG, "Using profile %s [%s]\n", profile->name, profile->host); if (argv_host) { if (argv_port && profile->port != 8021) { snprintf(prompt_str, sizeof(prompt_str), "freeswitch@%s:%u@%s> ", profile->host, profile->port, profile->name); } else { snprintf(prompt_str, sizeof(prompt_str), "freeswitch@%s@%s> ", profile->host, profile->name); } } else { snprintf(prompt_str, sizeof(prompt_str), "freeswitch@%s> ", profile->name); } if (esl_connect(&handle, profile->host, profile->port, profile->user, profile->pass)) { esl_global_set_default_logger(7); esl_log(ESL_LOG_ERROR, "Error Connecting [%s]\n", handle.err); if (!argv_exec) usage(argv[0]); return -1; } if (argv_exec){ const char *err = NULL; snprintf(cmd_str, sizeof(cmd_str), "api %s\n\n", argv_command); esl_send_recv(&handle, cmd_str); if (handle.last_sr_event) { if (handle.last_sr_event->body) { printf("%s\n", handle.last_sr_event->body); } else if ((err = esl_event_get_header(handle.last_sr_event, "reply-text")) && !strncasecmp(err, "-err", 3)) { printf("Error: %s!\n", err + 4); } } esl_disconnect(&handle); return 0; } global_handle = &handle; global_profile = profile; esl_thread_create_detached(msg_thread_run, &handle); #ifdef HAVE_EDITLINE el = el_init(__FILE__, stdout, stdout, stdout); el_set(el, EL_PROMPT, &prompt); el_set(el, EL_EDITOR, "emacs"); myhistory = history_init(); el_set(el, EL_ADDFN, "f1-key", "F1 KEY PRESS", console_f1key); el_set(el, EL_ADDFN, "f2-key", "F2 KEY PRESS", console_f2key); el_set(el, EL_ADDFN, "f3-key", "F3 KEY PRESS", console_f3key); el_set(el, EL_ADDFN, "f4-key", "F4 KEY PRESS", console_f4key); el_set(el, EL_ADDFN, "f5-key", "F5 KEY PRESS", console_f5key); el_set(el, EL_ADDFN, "f6-key", "F6 KEY PRESS", console_f6key); el_set(el, EL_ADDFN, "f7-key", "F7 KEY PRESS", console_f7key); el_set(el, EL_ADDFN, "f8-key", "F8 KEY PRESS", console_f8key); el_set(el, EL_ADDFN, "f9-key", "F9 KEY PRESS", console_f9key); el_set(el, EL_ADDFN, "f10-key", "F10 KEY PRESS", console_f10key); el_set(el, EL_ADDFN, "f11-key", "F11 KEY PRESS", console_f11key); el_set(el, EL_ADDFN, "f12-key", "F12 KEY PRESS", console_f12key); el_set(el, EL_ADDFN, "EOF-key", "EOF (^D) KEY PRESS", console_eofkey); el_set(el, EL_BIND, "\033OP", "f1-key", NULL); el_set(el, EL_BIND, "\033OQ", "f2-key", NULL); el_set(el, EL_BIND, "\033OR", "f3-key", NULL); el_set(el, EL_BIND, "\033OS", "f4-key", NULL); el_set(el, EL_BIND, "\033[11~", "f1-key", NULL); el_set(el, EL_BIND, "\033[12~", "f2-key", NULL); el_set(el, EL_BIND, "\033[13~", "f3-key", NULL); el_set(el, EL_BIND, "\033[14~", "f4-key", NULL); el_set(el, EL_BIND, "\033[15~", "f5-key", NULL); el_set(el, EL_BIND, "\033[17~", "f6-key", NULL); el_set(el, EL_BIND, "\033[18~", "f7-key", NULL); el_set(el, EL_BIND, "\033[19~", "f8-key", NULL); el_set(el, EL_BIND, "\033[20~", "f9-key", NULL); el_set(el, EL_BIND, "\033[21~", "f10-key", NULL); el_set(el, EL_BIND, "\033[23~", "f11-key", NULL); el_set(el, EL_BIND, "\033[24~", "f12-key", NULL); el_set(el, EL_BIND, "\004", "EOF-key", NULL); el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete); el_set(el, EL_BIND, "^I", "ed-complete", NULL); if (myhistory == 0) { esl_log(ESL_LOG_ERROR, "history could not be initialized\n"); goto done; } history(myhistory, &ev, H_SETSIZE, 800); el_set(el, EL_HIST, history, myhistory); history(myhistory, &ev, H_LOAD, hfile); el_source(el, NULL); #endif #ifdef WIN32 hStdout = GetStdHandle(STD_OUTPUT_HANDLE); if (hStdout != INVALID_HANDLE_VALUE && GetConsoleScreenBufferInfo(hStdout, &csbiInfo)) { wOldColorAttrs = csbiInfo.wAttributes; } #endif if (!argv_quiet && !profile->quiet) { snprintf(cmd_str, sizeof(cmd_str), "log %s\n\n", profile->loglevel); esl_send_recv(&handle, cmd_str); } print_banner(stdout); esl_log(ESL_LOG_INFO, "FS CLI Ready.\nenter /help for a list of commands.\n"); printf("%s\n", handle.last_sr_reply); while (running) { #ifdef HAVE_EDITLINE line = el_gets(el, &count); #else line = basic_gets(&count); #endif if (count > 1) { if (!esl_strlen_zero(line)) { char *cmd = strdup(line); char *p; #ifdef HAVE_EDITLINE const LineInfo *lf = el_line(el); char *foo = (char *) lf->buffer; #endif if ((p = strrchr(cmd, '\r')) || (p = strrchr(cmd, '\n'))) { *p = '\0'; } assert(cmd != NULL); #ifdef HAVE_EDITLINE history(myhistory, &ev, H_ENTER, line); #endif if (process_command(&handle, cmd)) { running = 0; } #ifdef HAVE_EDITLINE el_deletestr(el, strlen(foo) + 1); memset(foo, 0, strlen(foo)); #endif free(cmd); } } usleep(1000); } #ifdef HAVE_EDITLINE done: history(myhistory, &ev, H_SAVE, hfile); /* Clean up our memory */ history_end(myhistory); el_end(el); #endif esl_disconnect(&handle); thread_running = 0; return 0; }
static void read_config(const char *dft_cfile, const char *cfile) { esl_config_t cfg; if (esl_config_open_file(&cfg, cfile) || esl_config_open_file(&cfg, dft_cfile)) { char *var, *val; char cur_cat[128] = ""; while (esl_config_next_pair(&cfg, &var, &val)) { if (strcmp(cur_cat, cfg.category)) { esl_set_string(cur_cat, cfg.category); esl_set_string(profiles[pcount].name, cur_cat); esl_set_string(profiles[pcount].host, "127.0.0.1"); esl_set_string(profiles[pcount].pass, "ClueCon"); profiles[pcount].port = 8021; set_fn_keys(&profiles[pcount]); esl_set_string(profiles[pcount].prompt_color, prompt_color); esl_set_string(profiles[pcount].input_text_color, input_text_color); esl_set_string(profiles[pcount].output_text_color, output_text_color); esl_log(ESL_LOG_DEBUG, "Found Profile [%s]\n", profiles[pcount].name); pcount++; } if (!strcasecmp(var, "host")) { esl_set_string(profiles[pcount-1].host, val); } else if (!strcasecmp(var, "user")) { esl_set_string(profiles[pcount-1].user, val); } else if (!strcasecmp(var, "password")) { esl_set_string(profiles[pcount-1].pass, val); } else if (!strcasecmp(var, "port")) { int pt = atoi(val); if (pt > 0) { profiles[pcount-1].port = (esl_port_t)pt; } } else if (!strcasecmp(var, "batchmode")) { profiles[pcount-1].batch_mode = esl_true(val); } else if (!strcasecmp(var, "debug")) { int dt = atoi(val); if (dt > -1 && dt < 8){ profiles[pcount-1].debug = dt; } } else if(!strcasecmp(var, "loglevel")) { esl_set_string(profiles[pcount-1].loglevel, val); } else if(!strcasecmp(var, "log-uuid")) { profiles[pcount-1].log_uuid = esl_true(val); } else if(!strcasecmp(var, "quiet")) { profiles[pcount-1].quiet = esl_true(val); } else if(!strcasecmp(var, "prompt-color")) { esl_set_string(profiles[pcount-1].prompt_color, match_color(val)); } else if(!strcasecmp(var, "input-text-color")) { esl_set_string(profiles[pcount-1].input_text_color, match_color(val)); } else if(!strcasecmp(var, "output-text-color")) { esl_set_string(profiles[pcount-1].output_text_color, match_color(val)); } else if (!strncasecmp(var, "key_F", 5)) { char *key = var + 5; if (key) { int i = atoi(key); if (i > 0 && i < 13) { profiles[pcount-1].console_fnkeys[i - 1] = strdup(val); } } } else if (!strcasecmp(var, "timeout")) { timeout = atoi(val); } else if (!strcasecmp(var, "connect-timeout")) { connect_timeout = atoi(val); } } esl_config_close_file(&cfg); } }